Detailed changes
@@ -74,7 +74,7 @@ dependencies {
implementation 'org.hsluv:hsluv:0.2'
implementation 'org.conscrypt:conscrypt-android:2.5.2'
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:converter-gson:2.9.0"
@@ -5,6 +5,7 @@
<activity
android:name=".ui.ManageAccountActivity"
android:label="@string/title_activity_manage_accounts"
+ android:theme="@style/Theme.Conversations3"
android:launchMode="singleTask" />
<activity
android:name=".ui.WelcomeActivity"
@@ -225,7 +225,7 @@ public class ImportBackupService extends Service {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getBaseContext(), "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);
return mBuilder.build();
}
@@ -415,7 +415,7 @@ public class ImportBackupService extends Service {
? PendingIntent.FLAG_IMMUTABLE
| 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());
}
@@ -2,6 +2,7 @@ package eu.siacs.conversations.ui;
import android.app.Activity;
import android.content.Intent;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Bundle;
@@ -11,8 +12,10 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
+import com.google.android.material.color.MaterialColors;
import com.google.common.base.Strings;
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.xmpp.Jid;
-public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOnboardingInvite.OnInviteRequested {
+public class EasyOnboardingInviteActivity extends XmppActivity
+ implements EasyOnboardingInvite.OnInviteRequested {
private ActivityEasyInviteBinding binding;
private EasyOnboardingInvite easyOnboardingInvite;
-
@Override
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_easy_invite);
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar(), true);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
this.binding.shareButton.setOnClickListener(v -> share());
if (bundle != null && bundle.containsKey("invite")) {
this.easyOnboardingInvite = bundle.getParcelable("invite");
@@ -65,11 +69,11 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
}
private void share() {
- final String shareText = getString(
- R.string.easy_invite_share_text,
- easyOnboardingInvite.getDomain(),
- easyOnboardingInvite.getShareableLink()
- );
+ final String shareText =
+ getString(
+ R.string.easy_invite_share_text,
+ easyOnboardingInvite.getDomain(),
+ easyOnboardingInvite.getShareableLink());
final Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, shareText);
@@ -95,16 +99,47 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
private void showInvite(final EasyOnboardingInvite invite) {
this.binding.inProgress.setVisibility(View.GONE);
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();
getWindowManager().getDefaultDisplay().getSize(size);
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);
}
@Override
- public void onSaveInstanceState(Bundle bundle) {
+ public void onSaveInstanceState(@NonNull Bundle bundle) {
super.onSaveInstanceState(bundle);
if (easyOnboardingInvite != null) {
bundle.putParcelable("invite", easyOnboardingInvite);
@@ -141,11 +176,12 @@ public class EasyOnboardingInviteActivity extends XmppActivity implements EasyOn
@Override
public void inviteRequestFailed(final String message) {
- runOnUiThread(() -> {
- if (!Strings.isNullOrEmpty(message)) {
- Toast.makeText(this, message, Toast.LENGTH_LONG).show();
- }
- finish();
- });
+ runOnUiThread(
+ () -> {
+ if (!Strings.isNullOrEmpty(message)) {
+ Toast.makeText(this, message, Toast.LENGTH_LONG).show();
+ }
+ finish();
+ });
}
}
@@ -18,6 +18,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
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.util.SettingsUtils;
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 {
@@ -46,22 +46,15 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
@Override
protected void onCreate(final Bundle savedInstanceState) {
- this.mTheme = ThemeHelper.find(this);
- setTheme(this.mTheme);
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_import_backup);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
setLoadingState(savedInstanceState != null && savedInstanceState.getBoolean("loading_state", false));
this.backupFileAdapter = new BackupFileAdapter();
this.binding.list.setAdapter(this.backupFileAdapter);
this.backupFileAdapter.setOnItemClickedListener(this);
}
-
- @Override
- protected void onResume(){
- super.onResume();
- SettingsUtils.applyScreenshotPreventionSetting(this);
- }
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
@@ -80,12 +73,7 @@ public class ImportBackupActivity extends ActionBarActivity implements ServiceCo
@Override
public void onStart() {
super.onStart();
- final int theme = ThemeHelper.find(this);
- if (this.mTheme != theme) {
- recreate();
- } else {
- bindService(new Intent(this, ImportBackupService.class), this, Context.BIND_AUTO_CREATE);
- }
+ bindService(new Intent(this, ImportBackupService.class), this, Context.BIND_AUTO_CREATE);
final Intent intent = getIntent();
if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction()) && !this.mLoadingState) {
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);
Log.d(Config.LOGTAG, "attempting to import " + backupFile.getUri());
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.setTitle(R.string.enter_password);
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.inProgress.setVisibility(loadingState ? View.VISIBLE : View.GONE);
setTitle(loadingState ? R.string.restoring_backup : R.string.restore_backup);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
configureActionBar(getSupportActionBar(), !loadingState);
this.mLoadingState = loadingState;
invalidateOptionsMenu();
@@ -10,45 +10,32 @@ import android.widget.Toast;
import androidx.databinding.DataBindingUtil;
-import java.security.SecureRandom;
-
import eu.siacs.conversations.Config;
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.utils.CryptoHelper;
import eu.siacs.conversations.utils.InstallReferrerUtils;
import eu.siacs.conversations.xmpp.Jid;
+import java.security.SecureRandom;
+
public class MagicCreateActivity extends XmppActivity implements TextWatcher {
public static final String EXTRA_DOMAIN = "domain";
public static final String EXTRA_PRE_AUTH = "pre_auth";
public static final String EXTRA_USERNAME = "username";
- private MagicCreateBinding binding;
+ private ActivityMagicCreateBinding binding;
private String domain;
private String username;
private String preAuth;
@Override
- protected void refreshUiReal() {
-
- }
+ protected void refreshUiReal() {}
@Override
- void onBackendConnected() {
-
- }
-
- @Override
- public void onStart() {
- super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- }
- }
+ void onBackendConnected() {}
@Override
protected void onCreate(final Bundle savedInstanceState) {
@@ -60,7 +47,8 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
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);
configureActionBar(getSupportActionBar(), this.domain == null);
if (username != null && domain != null) {
@@ -72,51 +60,64 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
} else if (domain != null) {
binding.instructions.setText(getString(R.string.magic_create_text_on_x, domain));
}
- binding.createAccount.setOnClickListener(v -> {
- try {
- final String username = binding.username.getText().toString();
- final Jid jid;
- final boolean fixedUsername;
- if (this.domain != null && this.username != null) {
- fixedUsername = true;
- jid = Jid.ofLocalAndDomainEscaped(this.username, this.domain);
- } else if (this.domain != null) {
- fixedUsername = false;
- jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
- } else {
- 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);
+ binding.createAccount.setOnClickListener(
+ v -> {
+ try {
+ final String username = binding.username.getText().toString();
+ final Jid jid;
+ final boolean fixedUsername;
+ if (this.domain != null && this.username != null) {
+ fixedUsername = true;
+ jid = Jid.ofLocalAndDomainEscaped(this.username, this.domain);
+ } else if (this.domain != null) {
+ fixedUsername = false;
+ jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
+ } else {
+ fixedUsername = false;
+ jid = Jid.ofLocalAndDomainEscaped(username, Config.MAGIC_CREATE_DOMAIN);
+ }
+ 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);
}
- xmppConnectionService.createAccount(account);
+ } 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);
}
@@ -127,14 +128,10 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
}
@Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
-
- }
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(final Editable s) {
@@ -153,8 +150,10 @@ public class MagicCreateActivity extends XmppActivity implements TextWatcher {
} else {
jid = Jid.ofLocalAndDomainEscaped(username, this.domain);
}
- binding.fullJid.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
- } catch (IllegalArgumentException e) {
+ binding.fullJid.setText(
+ getString(R.string.your_full_jid_will_be, jid.toEscapedString()));
+ binding.usernameLayout.setError(null);
+ } catch (final IllegalArgumentException e) {
binding.fullJid.setVisibility(View.INVISIBLE);
}
}
@@ -1,10 +1,14 @@
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.Intent;
import android.os.Bundle;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.util.Log;
import android.util.Pair;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -12,23 +16,17 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AlertDialog;
+import androidx.databinding.DataBindingUtil;
-import org.openintents.openpgp.util.OpenPgpApi;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
+import com.google.common.base.Strings;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.ActivityManageAccountsBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
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.XmppConnection;
-import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
-import static eu.siacs.conversations.utils.PermissionUtils.writeGranted;
+import org.openintents.openpgp.util.OpenPgpApi;
-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";
@@ -50,7 +55,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
protected Jid selectedAccountJid = null;
protected final List<Account> accountList = new ArrayList<>();
- protected ListView accountListView;
protected AccountAdapter mAccountAdapter;
protected AtomicBoolean mInvokedAddAccount = new AtomicBoolean(false);
@@ -67,7 +71,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
accountList.clear();
accountList.addAll(xmppConnectionService.getAccounts());
}
- ActionBar actionBar = getSupportActionBar();
+ final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(this.accountList.size() > 0);
actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0);
@@ -81,8 +85,11 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_manage_accounts);
- setSupportActionBar(findViewById(R.id.toolbar));
+ ActivityManageAccountsBinding binding =
+ DataBindingUtil.setContentView(this, R.layout.activity_manage_accounts);
+
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+ setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
if (savedInstanceState != null) {
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);
- accountListView.setAdapter(this.mAccountAdapter);
- accountListView.setOnItemClickListener((arg0, view, position, arg3) -> switchToAccount(accountList.get(position)));
- registerForContextMenu(accountListView);
+ binding.accountList.setAdapter(this.mAccountAdapter);
+ binding.accountList.setOnItemClickListener(
+ (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
- public void onSaveInstanceState(final Bundle savedInstanceState) {
+ public void onSaveInstanceState(@NonNull final Bundle savedInstanceState) {
if (selectedAccount != null) {
- savedInstanceState.putString(STATE_SELECTED_ACCOUNT, selectedAccount.getJid().asBareJid().toEscapedString());
+ savedInstanceState.putString(
+ STATE_SELECTED_ACCOUNT, selectedAccount.getJid().asBareJid().toEscapedString());
}
super.onSaveInstanceState(savedInstanceState);
}
@@ -122,8 +122,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
- ManageAccountActivity.this.getMenuInflater().inflate(
- R.menu.manageaccounts_context, menu);
+ ManageAccountActivity.this.getMenuInflater().inflate(R.menu.manageaccounts_context, menu);
AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
this.selectedAccount = accountList.get(acmi.position);
if (this.selectedAccount.isEnabled()) {
@@ -144,9 +143,10 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
refreshUiReal();
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)) {
addAccountFromKey();
}
@@ -233,9 +233,9 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
return super.onOptionsItemSelected(item);
}
-
@Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(
+ int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0) {
if (allGranted(grantResults)) {
@@ -258,13 +258,14 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
@Override
public boolean onNavigateUp() {
if (xmppConnectionService.getConversations().size() == 0) {
- Intent contactsIntent = new Intent(this,
- StartConversationActivity.class);
+ Intent contactsIntent = new Intent(this, StartConversationActivity.class);
contactsIntent.setFlags(
// 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
- Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ |
// don't use the new activity animation; finish
// animation runs instead
Intent.FLAG_ACTIVITY_NO_ANIMATION);
@@ -286,16 +287,17 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
private void addAccountFromKey() {
+ Log.d(Config.LOGTAG, "add account from key");
try {
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
+ } catch (final ActivityNotFoundException e) {
+ Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG)
+ .show();
}
}
private void publishAvatar(Account account) {
- Intent intent = new Intent(getApplicationContext(),
- PublishProfilePictureActivity.class);
+ Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toEscapedString());
startActivity(intent);
}
@@ -377,7 +379,6 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
}
}
-
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
@@ -385,7 +386,8 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
if (xmppConnectionServiceBound) {
if (requestCode == REQUEST_CHOOSE_PGP_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);
} else {
choosePgpSignId(selectedAccount);
@@ -402,9 +404,17 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
@Override
public void alias(final String alias) {
- if (alias != null) {
- xmppConnectionService.createAccountFromKey(alias, this);
- }
+ if (Strings.isNullOrEmpty(alias)) {
+ runOnUiThread(
+ () ->
+ Toast.makeText(
+ this,
+ R.string.no_certificate_selected,
+ Toast.LENGTH_LONG)
+ .show());
+ return;
+ }
+ xmppConnectionService.createAccountFromKey(alias, this);
}
@Override
@@ -417,6 +427,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
@Override
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
public boolean onOptionsItemSelected(final MenuItem item) {
@@ -53,7 +44,8 @@ public class PickServerActivity extends XmppActivity {
}
@Override
- public void onNewIntent(Intent intent) {
+ public void onNewIntent(final Intent intent) {
+ super.onNewIntent(intent);
if (intent != null) {
setIntent(intent);
}
@@ -66,6 +58,7 @@ public class PickServerActivity extends XmppActivity {
}
super.onCreate(savedInstanceState);
ActivityPickServerBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_pick_server);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
binding.useCim.setOnClickListener(v -> {
@@ -81,7 +74,7 @@ public class PickServerActivity extends XmppActivity {
if (accounts.size() == 1) {
intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
intent.putExtra("init", true);
- } else if (accounts.size() >= 1) {
+ } else if (!accounts.isEmpty()) {
intent = new Intent(this, ManageAccountActivity.class);
}
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
void onBackendConnected() {
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.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;
@@ -66,7 +69,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
final Intent intent;
if (xmppUri.isAction(XmppUri.ACTION_REGISTER)) {
intent = SignupUtils.getTokenRegistrationIntent(this, jid, preAuth);
- } else if (xmppUri.isAction(XmppUri.ACTION_ROSTER) && "y".equals(xmppUri.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.putExtra(StartConversationActivity.EXTRA_INVITE_URI, xmppUri.toString());
} else {
@@ -81,22 +85,14 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
}
@Override
- protected void refreshUiReal() {
-
- }
+ protected void refreshUiReal() {}
@Override
- void onBackendConnected() {
-
- }
+ void onBackendConnected() {}
@Override
public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- }
new InstallReferrerUtils(this);
}
@@ -119,42 +115,44 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
super.onCreate(savedInstanceState);
- ActivityWelcomeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_welcome);
+ ActivityWelcomeBinding binding =
+ DataBindingUtil.setContentView(this, R.layout.activity_welcome);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar(), false);
- binding.registerNewAccount.setOnClickListener(v -> {
- final Intent intent = new Intent(this, PickServerActivity.class);
- addInviteUri(intent);
- startActivity(intent);
- });
- binding.useExisting.setOnClickListener(v -> {
- final List<Account> accounts = xmppConnectionService.getAccounts();
- Intent intent = new Intent(WelcomeActivity.this, EditAccountActivity.class);
- intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
- if (accounts.size() == 1) {
- intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
- intent.putExtra("init", true);
- } else if (accounts.size() >= 1) {
- intent = new Intent(WelcomeActivity.this, ManageAccountActivity.class);
- }
- addInviteUri(intent);
- startActivity(intent);
- });
-
+ setTitle(null);
+ binding.registerNewAccount.setOnClickListener(
+ v -> {
+ final Intent intent = new Intent(this, PickServerActivity.class);
+ addInviteUri(intent);
+ startActivity(intent);
+ });
+ binding.useExisting.setOnClickListener(
+ v -> {
+ final List<Account> accounts = xmppConnectionService.getAccounts();
+ Intent intent = new Intent(this, EditAccountActivity.class);
+ intent.putExtra(EditAccountActivity.EXTRA_FORCE_REGISTER, false);
+ if (accounts.size() == 1) {
+ intent.putExtra("jid", accounts.get(0).getJid().asBareJid().toString());
+ intent.putExtra("init", true);
+ } else if (!accounts.isEmpty()) {
+ intent = new Intent(this, ManageAccountActivity.class);
+ }
+ addInviteUri(intent);
+ startActivity(intent);
+ });
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
+ public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.welcome_menu, menu);
final MenuItem scan = menu.findItem(R.id.action_scan_qr_code);
scan.setVisible(Compatibility.hasFeatureCamera(this));
return super.onCreateOptionsMenu(menu);
}
-
-
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_import_backup:
if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
@@ -174,16 +172,25 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
private void addAccountFromKey() {
try {
KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG).show();
+ } catch (final ActivityNotFoundException e) {
+ Toast.makeText(this, R.string.device_does_not_support_certificates, Toast.LENGTH_LONG)
+ .show();
}
}
@Override
public void alias(final String alias) {
- if (alias != null) {
- xmppConnectionService.createAccountFromKey(alias, this);
+ if (Strings.isNullOrEmpty(alias)) {
+ runOnUiThread(
+ () ->
+ Toast.makeText(
+ this,
+ R.string.no_certificate_selected,
+ Toast.LENGTH_LONG)
+ .show());
+ return;
}
+ xmppConnectionService.createAccountFromKey(alias, this);
}
@Override
@@ -201,7 +208,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
}
@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);
UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
if (grantResults.length > 0) {
@@ -211,7 +219,8 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
startActivity(new Intent(this, ImportBackupActivity.class));
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();
}
}
@@ -232,5 +241,4 @@ public class WelcomeActivity extends XmppActivity implements XmppConnectionServi
to.putExtra(StartConversationActivity.EXTRA_INVITE_URI, this.inviteUri.toString());
}
}
-
}
@@ -22,7 +22,7 @@ import java.util.List;
import java.util.concurrent.RejectedExecutionException;
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.ImportBackupService;
import eu.siacs.conversations.utils.BackupFileHeader;
@@ -39,7 +39,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
@NonNull
@Override
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
@@ -73,9 +73,9 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
}
static class BackupFileViewHolder extends RecyclerView.ViewHolder {
- private final AccountRowBinding binding;
+ private final ItemAccountBinding binding;
- BackupFileViewHolder(AccountRowBinding binding) {
+ BackupFileViewHolder(ItemAccountBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
@@ -91,7 +91,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
private Jid jid = null;
private final int size;
- BitmapWorkerTask(ImageView imageView) {
+ BitmapWorkerTask(final ImageView imageView) {
imageViewReference = new WeakReference<>(imageView);
DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
this.size = ((int) (48 * metrics.density));
@@ -146,8 +146,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
- if (drawable instanceof AsyncDrawable) {
- final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ if (drawable instanceof AsyncDrawable asyncDrawable) {
return asyncDrawable.getBitmapWorkerTask();
}
}
@@ -1,17 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
-<layout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:background="?attr/color_background_primary"
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>
<LinearLayout
android:id="@+id/in_progress"
@@ -41,7 +47,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tap_share_button_send_invite"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ android:textAppearance="?textAppearanceBodyMedium" />
<TextView
android:id="@+id/scan_the_code"
@@ -50,7 +56,7 @@
android:layout_below="@+id/tap_to_share"
android:layout_marginTop="24sp"
android:text="@string/if_contact_is_nearby_use_qr"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ android:textAppearance="?textAppearanceBodyMedium" />
<ImageView
android:id="@+id/qr_code"
@@ -59,23 +65,19 @@
android:layout_above="@+id/share_button"
android:layout_below="@id/scan_the_code"
android:layout_alignParentStart="true"
- android:layout_alignParentRight="true"
+ android:layout_alignParentEnd="true"
android:layout_centerHorizontal="true"
android:layout_margin="24sp"
android:scaleType="fitCenter" />
<Button
android:id="@+id/share_button"
- style="@style/Widget.Conversations.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:minWidth="0dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:text="@string/share"
android:layout_centerHorizontal="true"
- android:textColor="?attr/colorAccent" />
+ android:layout_marginHorizontal="16dp"
+ android:text="@string/share" />
</RelativeLayout>
@@ -2,22 +2,30 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
-
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
- android:background="?attr/color_background_primary"
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>
+
<LinearLayout
- android:visibility="gone"
android:id="@+id/in_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center">
+ android:gravity="center"
+ android:visibility="gone">
+
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -25,18 +33,15 @@
</LinearLayout>
-
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?attr/color_background_primary">
+ android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="?attr/color_background_primary"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -7,7 +7,18 @@
android:layout_height="match_parent"
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
android:layout_width="match_parent"
@@ -16,15 +27,13 @@
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?attr/color_background_primary">
+ android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:minHeight="256dp"
android:orientation="vertical"
@@ -42,50 +51,53 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pick_your_username"
- android:textAppearance="@style/TextAppearance.Conversations.Title" />
+ android:textAppearance="?textAppearanceTitleLarge" />
<TextView
android:id="@+id/instructions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginVertical="8dp"
android:text="@string/magic_create_text"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ android:textAppearance="?textAppearanceBodyMedium" />
- <EditText
- android:id="@+id/username"
+ <com.google.android.material.textfield.TextInputLayout
+ android:id="@+id/username_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:hint="@string/username_hint"
- android:textColor="?attr/edit_text_color"
- android:inputType="textNoSuggestions" />
+ android:hint="@string/username_hint">
+
+ <com.google.android.material.textfield.TextInputEditText
+ 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
android:id="@+id/full_jid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
+ android:layout_marginVertical="8dp"
android:text="@string/your_full_jid_will_be"
- android:textAppearance="@style/TextAppearance.Conversations.Caption"
+ android:textAppearance="?textAppearanceLabelSmall"
android:visibility="invisible" />
<Button
android:id="@+id/create_account"
- style="@style/Widget.Conversations.Button.Borderless"
+ style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:text="@string/next"
- android:textColor="?colorAccent" />
+ android:layout_gravity="end"
+ android:text="@string/next" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/linearLayout"
- android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true">
+ android:layout_alignParentStart="true">
<ImageView
android:layout_width="wrap_content"
@@ -7,7 +7,17 @@
android:layout_height="match_parent"
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
android:layout_width="match_parent"
@@ -16,15 +26,13 @@
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?attr/color_background_primary">
+ android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:minHeight="256dp"
android:orientation="vertical"
@@ -41,40 +49,38 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pick_a_server"
- android:textAppearance="@style/TextAppearance.Conversations.Title" />
+ android:textAppearance="?textAppearanceTitleLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
+ android:layout_marginBottom="16dp"
android:text="@string/server_select_text"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ android:textAppearance="?textAppearanceBodyMedium" />
<Button
android:id="@+id/use_cim"
- style="@style/Widget.Conversations.Button.Borderless"
+ style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:text="@string/use_conversations.im"
- android:textColor="?colorAccent" />
+ android:layout_gravity="end"
+ android:text="@string/use_conversations.im" />
<Button
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_height="wrap_content"
- android:layout_gravity="right"
- android:text="@string/use_own_provider"
- android:textColor="?android:textColorSecondary" />
+ android:layout_gravity="end"
+ android:text="@string/use_own_provider" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/linearLayout"
- android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true">
+ android:layout_alignParentStart="true">
<ImageView
android:layout_width="wrap_content"
@@ -6,9 +6,18 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <include
- android:id="@+id/toolbar"
- layout="@layout/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
android:layout_width="match_parent"
@@ -17,15 +26,13 @@
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?attr/color_background_primary">
+ android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:minHeight="256dp"
android:orientation="vertical"
@@ -42,40 +49,38 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/welcome_header"
- android:textAppearance="@style/TextAppearance.Conversations.Title" />
+ android:textAppearance="?textAppearanceTitleLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
+ android:layout_marginBottom="16dp"
android:text="@string/do_you_have_an_account"
- android:textAppearance="@style/TextAppearance.Conversations.Body1" />
+ android:textAppearance="?textAppearanceBodyMedium" />
<Button
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_height="wrap_content"
- android:layout_gravity="right"
- android:text="@string/create_new_account"
- android:textColor="?colorAccent" />
+ android:layout_gravity="end"
+ android:text="@string/create_new_account" />
<Button
android:id="@+id/use_existing"
- style="@style/Widget.Conversations.Button.Borderless"
+ style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:text="@string/i_already_have_an_account"
- android:textColor="?android:textColorSecondary" />
+ android:layout_gravity="end"
+ android:text="@string/i_already_have_an_account" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/linearLayout"
- android:layout_alignParentStart="true"
- android:layout_alignParentLeft="true">
+ android:layout_alignParentStart="true">
<ImageView
android:layout_width="wrap_content"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
+ xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
@@ -13,41 +13,35 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/enter_password_to_restore"
- android:textAppearance="@style/TextAppearance.Conversations.Body2"/>
+ android:textAppearance="?textAppearanceBodyMedium" />
<TextView
- android:layout_marginTop="?TextSizeBody1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="18sp"
android:text="@string/restore_warning"
- android:textAppearance="@style/TextAppearance.Conversations.Body1"/>
+ android:textAppearance="?textAppearanceBodyMedium" />
<TextView
- android:layout_marginTop="?TextSizeBody1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="18sp"
android:text="@string/restore_warning_continued"
- android:textAppearance="@style/TextAppearance.Conversations.Subhead.Bold"/>
+ android:textAppearance="?textAppearanceBodyMedium" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/account_password_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- app:passwordToggleDrawable="@drawable/visibility_toggle_drawable"
- app:passwordToggleEnabled="true"
- app:passwordToggleTint="?android:textColorSecondary"
- app:hintTextAppearance="@style/TextAppearance.Conversations.Design.Hint"
- app:errorTextAppearance="@style/TextAppearance.Conversations.Design.Error">
+ app:endIconMode="password_toggle">
- <eu.siacs.conversations.ui.widget.TextInputEditText
- android:id="@+id/account_password"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="@string/password"
- android:inputType="textPassword"
- android:textColor="?attr/edit_text_color"
- style="@style/Widget.Conversations.EditText"/>
+ <eu.siacs.conversations.ui.widget.TextInputEditText
+ android:id="@+id/account_password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/password"
+ android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
@@ -4,7 +4,7 @@
<item
android:id="@+id/action_share"
- android:icon="?attr/icon_share"
+ android:icon="@drawable/ic_share_24dp"
android:title="@string/invite"
app:showAsAction="always" />
</menu>
@@ -1,32 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<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
- android:id="@+id/action_add_account"
- android:icon="?attr/icon_add_person"
- app:showAsAction="always"
- android:title="@string/action_add_account"/>
- <item
- android:id="@+id/action_import_backup"
- app:showAsAction="never"
- android:title="@string/restore_backup"/>
- <item
- android:id="@+id/action_add_account_with_cert"
- app:showAsAction="never"
- android:icon="?attr/icon_add_person"
- android:title="@string/action_add_account_with_certificate"
- android:visible="true"/>
- <item
- android:id="@+id/action_enable_all"
- android:title="@string/enable_all_accounts"/>
- <item
- android:id="@+id/action_disable_all"
- android:title="@string/disable_all_accounts"/>
- <item
- android:id="@+id/action_settings"
- android:orderInCategory="100"
- app:showAsAction="never"
- android:title="@string/action_settings"/>
+ <item
+ android:id="@+id/action_add_account"
+ android:icon="@drawable/ic_person_add_24dp"
+ android:title="@string/action_add_account"
+ app:showAsAction="ifRoom" />
+ <item
+ android:id="@+id/action_import_backup"
+ android:title="@string/restore_backup"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/action_add_account_with_cert"
+ android:title="@string/action_add_account_with_certificate"
+ android:visible="true"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/action_enable_all"
+ android:title="@string/enable_all_accounts" />
+ <item
+ android:id="@+id/action_disable_all"
+ android:title="@string/disable_all_accounts" />
+ <item
+ android:id="@+id/action_settings"
+ android:orderInCategory="100"
+ android:title="@string/action_settings"
+ app:showAsAction="never" />
</menu>
@@ -3,7 +3,7 @@
<item
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:title="@string/scan_qr_code"
android:visible="@bool/show_qr_code_scan"
@@ -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 -->
<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
android:name="android.hardware.camera"
@@ -84,6 +84,7 @@
<application
+ android:name=".Conversations"
android:allowBackup="true"
android:appCategory="social"
android:dataExtractionRules="@xml/data_extraction_rules"
@@ -96,7 +97,7 @@
android:networkSecurityConfig="@xml/network_security_configuration"
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
- android:theme="@style/ConversationsTheme"
+ android:theme="@style/Theme.Conversations3"
tools:targetApi="tiramisu">
<meta-data
@@ -132,9 +133,10 @@
</intent-filter>
</service>
- <service android:name=".services.CallIntegrationConnectionService"
- android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
- android:exported="true">
+ <service
+ android:name=".services.CallIntegrationConnectionService"
+ android:exported="true"
+ android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.ConnectionService" />
</intent-filter>
@@ -180,14 +182,14 @@
<activity
android:name=".ui.RecordingActivity"
android:configChanges="orientation|screenSize"
- android:theme="@style/ConversationsTheme.Dialog" />
+ android:theme="@style/Theme.Conversations3.Dialog" />
<activity
android:name=".ui.ShowLocationActivity"
android:label="@string/title_activity_show_location" />
<activity
android:name=".ui.ConversationActivity"
android:exported="true"
- android:theme="@style/SplashTheme">
+ android:theme="@style/Theme.Conversations3.SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -202,7 +204,7 @@
<activity
android:name=".ui.ScanActivity"
android:screenOrientation="portrait"
- android:theme="@style/ConversationsTheme.FullScreen"
+ android:theme="@style/Theme.Conversations3.FullScreen"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".ui.UriHandlerActivity"
@@ -263,10 +265,10 @@
</activity>
<activity
android:name=".ui.ChooseContactActivity"
- android:label="@string/title_activity_choose_contact" />
+ android:label="@string/title_activity_choose_contact"/>
<activity
android:name=".ui.BlocklistActivity"
- android:label="@string/title_activity_block_list" />
+ android:label="@string/title_activity_block_list"/>
<activity
android:name=".ui.ChangePasswordActivity"
android:label="@string/change_password_on_server" />
@@ -351,7 +353,7 @@
<activity
android:name=".ui.MediaBrowserActivity"
- android:label="@string/media_browser" />
+ android:label="@string/media_browser"/>
<provider
android:name="androidx.core.content.FileProvider"
@@ -378,10 +380,10 @@
</activity>
<activity
android:name=".ui.MucUsersActivity"
- android:label="@string/group_chat_members" />
+ android:label="@string/group_chat_members"/>
<activity
android:name=".ui.ChannelDiscoveryActivity"
- android:label="@string/discover_channels" />
+ android:label="@string/discover_channels"/>
<activity
android:name=".ui.RtpSessionActivity"
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 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 Jid QUICKSY_DOMAIN = Jid.of("quicksy.im");
@@ -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);
}
- 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 (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 {
- return darkTheme ? R.drawable.ic_call_missed_white_18dp : R.drawable.ic_call_missed_black_18dp;
+ return R.drawable.ic_call_missed_24db;
}
} else {
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 {
- 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");
}
- 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 {
final QRCodeWriter barcodeWriter = new QRCodeWriter();
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++) {
final int offset = y * width;
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);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
} catch (final Exception e) {
- e.printStackTrace();
+ Log.e(Config.LOGTAG,"could not generate QR code image",e);
return null;
}
}
@@ -266,7 +266,7 @@ public class ExportBackupService extends Service {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getBaseContext(), "backup");
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);
startForeground(NOTIFICATION_ID, mBuilder.build());
int count = 0;
@@ -420,11 +420,11 @@ public class ExportBackupService extends Service {
.getAbsolutePath())))
.setAutoCancel(true)
.setContentIntent(openFolderIntent)
- .setSmallIcon(R.drawable.ic_archive_white_24dp);
+ .setSmallIcon(R.drawable.ic_archive_24dp);
if (shareFilesIntent != null) {
mBuilder.addAction(
- R.drawable.ic_share_white_24dp,
+ R.drawable.ic_share_24dp,
getString(R.string.share_backup_files),
shareFilesIntent);
}
@@ -475,7 +475,7 @@ public class NotificationService {
new Builder(mXmppConnectionService, "delivery_failed")
.setContentTitle(conversation.getName())
.setAutoCancel(true)
- .setSmallIcon(R.drawable.ic_error_white_24dp)
+ .setSmallIcon(R.drawable.ic_error_24dp)
.setContentText(
mXmppConnectionService
.getResources()
@@ -495,7 +495,7 @@ public class NotificationService {
.getQuantityText(
R.plurals.some_messages_could_not_be_delivered,
1024))
- .setSmallIcon(R.drawable.ic_error_white_24dp)
+ .setSmallIcon(R.drawable.ic_error_24dp)
.setGroup("delivery_failed")
.setGroupSummary(true)
.setAutoCancel(true)
@@ -569,11 +569,11 @@ public class NotificationService {
new NotificationCompat.Builder(
mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL);
if (media.contains(Media.VIDEO)) {
- builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
+ builder.setSmallIcon(R.drawable.ic_videocam_24dp);
builder.setContentTitle(
mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call));
} else {
- builder.setSmallIcon(R.drawable.ic_call_white_24dp);
+ builder.setSmallIcon(R.drawable.ic_call_24dp);
builder.setContentTitle(
mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
}
@@ -596,7 +596,7 @@ public class NotificationService {
builder.setOngoing(true);
builder.addAction(
new NotificationCompat.Action.Builder(
- R.drawable.ic_call_end_white_48dp,
+ R.drawable.ic_call_end_24dp,
mXmppConnectionService.getString(R.string.dismiss_call),
createCallAction(
id.sessionId,
@@ -605,7 +605,7 @@ public class NotificationService {
.build());
builder.addAction(
new NotificationCompat.Action.Builder(
- R.drawable.ic_call_white_24dp,
+ R.drawable.ic_call_24dp,
mXmppConnectionService.getString(R.string.answer_call),
createPendingRtpSession(
id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103))
@@ -622,7 +622,7 @@ public class NotificationService {
final NotificationCompat.Builder builder =
new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
if (ongoingCall.media.contains(Media.VIDEO)) {
- builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
+ builder.setSmallIcon(R.drawable.ic_videocam_24dp);
if (ongoingCall.reconnecting) {
builder.setContentTitle(
mXmppConnectionService.getString(R.string.reconnecting_video_call));
@@ -631,7 +631,7 @@ public class NotificationService {
mXmppConnectionService.getString(R.string.ongoing_video_call));
}
} else {
- builder.setSmallIcon(R.drawable.ic_call_white_24dp);
+ builder.setSmallIcon(R.drawable.ic_call_24dp);
if (ongoingCall.reconnecting) {
builder.setContentTitle(
mXmppConnectionService.getString(R.string.reconnecting_call));
@@ -647,7 +647,7 @@ public class NotificationService {
builder.setOngoing(true);
builder.addAction(
new NotificationCompat.Action.Builder(
- R.drawable.ic_call_end_white_48dp,
+ R.drawable.ic_call_end_24dp,
mXmppConnectionService.getString(R.string.hang_up),
createCallAction(
id.sessionId, XmppConnectionService.ACTION_END_CALL, 104))
@@ -826,7 +826,7 @@ public class NotificationService {
}
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);
if (last.getStatus() != Message.STATUS_RECEIVED) {
if (mXmppConnectionService.markRead((Conversation) last.getConversation(), false)) {
@@ -837,7 +837,8 @@ public class NotificationService {
}
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() {
@@ -1035,7 +1036,7 @@ public class NotificationService {
if (!publicVersion) {
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.setGroup(MISSED_CALLS_GROUP);
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
@@ -1085,7 +1086,7 @@ public class NotificationService {
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.setCategory(NotificationCompat.CATEGORY_CALL);
builder.setWhen(info.getLastTime());
@@ -1221,7 +1222,7 @@ public class NotificationService {
PendingIntent markAsReadPendingIntent = createReadPendingIntent(conversation);
NotificationCompat.Action markReadAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_drafts_white_24dp,
+ R.drawable.ic_mark_chat_read_24dp,
mXmppConnectionService.getString(R.string.mark_as_read),
markAsReadPendingIntent)
.setSemanticAction(
@@ -1232,7 +1233,7 @@ public class NotificationService {
final String lastMessageUuid = Iterables.getLast(messages).getUuid();
final NotificationCompat.Action replyAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_send_text_offline,
+ R.drawable.ic_send_24dp,
replyLabel,
createReplyIntent(conversation, lastMessageUuid, false))
.setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
@@ -1241,7 +1242,7 @@ public class NotificationService {
.build();
final NotificationCompat.Action wearReplyAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_wear_reply,
+ R.drawable.ic_reply_24dp,
replyLabel,
createReplyIntent(conversation, lastMessageUuid, true))
.addRemoteInput(remoteInput)
@@ -1260,7 +1261,7 @@ public class NotificationService {
PendingIntent pendingSnoozeIntent = createSnoozeIntent(conversation);
NotificationCompat.Action snoozeAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_notifications_paused_white_24dp,
+ R.drawable.ic_notifications_paused_24dp,
label,
pendingSnoozeIntent)
.build();
@@ -1279,7 +1280,7 @@ public class NotificationService {
.getString(R.string.show_location);
NotificationCompat.Action locationAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_room_white_24dp,
+ R.drawable.ic_location_pin_24dp,
label,
pendingShowLocationIntent)
.build();
@@ -1303,7 +1304,7 @@ public class NotificationService {
createDownloadIntent(firstDownloadableMessage);
NotificationCompat.Action downloadAction =
new NotificationCompat.Action.Builder(
- R.drawable.ic_file_download_white_24dp,
+ R.drawable.ic_download_24dp,
label,
pendingDownloadIntent)
.build();
@@ -1761,21 +1762,21 @@ public class NotificationService {
.setPriority(Notification.PRIORITY_MIN)
.setSmallIcon(
connected > 0
- ? R.drawable.ic_link_white_24dp
- : R.drawable.ic_link_off_white_24dp)
+ ? R.drawable.ic_link_24dp
+ : R.drawable.ic_link_off_24dp)
.setLocalOnly(true);
if (Compatibility.runsTwentySix()) {
mBuilder.setChannelId("foreground");
mBuilder.addAction(
- R.drawable.ic_logout_white_24dp,
+ R.drawable.ic_logout_24dp,
mXmppConnectionService.getString(R.string.log_out),
pendingServiceIntent(
mXmppConnectionService,
XmppConnectionService.ACTION_TEMPORARILY_DISABLE,
87));
mBuilder.addAction(
- R.drawable.ic_notifications_off_white_24dp,
+ R.drawable.ic_notifications_off_24dp,
mXmppConnectionService.getString(R.string.hide_notification),
pendingNotificationSettingsIntent(mXmppConnectionService));
}
@@ -1853,7 +1854,7 @@ public class NotificationService {
}
try {
mBuilder.addAction(
- R.drawable.ic_autorenew_white_24dp,
+ R.drawable.ic_autorenew_24dp,
mXmppConnectionService.getString(R.string.try_again),
pendingServiceIntent(
mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45));
@@ -1871,7 +1872,7 @@ public class NotificationService {
if (torNotAvailable) {
if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
mBuilder.addAction(
- R.drawable.ic_play_circle_filled_white_48dp,
+ R.drawable.ic_play_circle_24dp,
mXmppConnectionService.getString(R.string.start_orbot),
PendingIntent.getActivity(
mXmppConnectionService,
@@ -1883,7 +1884,7 @@ public class NotificationService {
: PendingIntent.FLAG_UPDATE_CURRENT));
} else {
mBuilder.addAction(
- R.drawable.ic_file_download_white_24dp,
+ R.drawable.ic_download_24dp,
mXmppConnectionService.getString(R.string.install_orbot),
PendingIntent.getActivity(
mXmppConnectionService,
@@ -1896,7 +1897,7 @@ public class NotificationService {
}
}
mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
- mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
+ mBuilder.setSmallIcon(R.drawable.ic_warning_24dp);
mBuilder.setLocalOnly(true);
mBuilder.setPriority(Notification.PRIORITY_LOW);
final Intent intent;
@@ -1935,7 +1936,7 @@ public class NotificationService {
} else {
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) {
builder.setContentIntent(createContentIntent(message.getConversation()));
}
@@ -4760,9 +4760,6 @@ public class XmppConnectionService extends Service {
if (Config.QUICKSY_DOMAIN != null) {
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) {
hosts.add(Config.MAGIC_CREATE_DOMAIN);
}
@@ -1,31 +1,25 @@
package eu.siacs.conversations.ui;
+import static eu.siacs.conversations.ui.XmppActivity.configureActionBar;
+
import android.os.Bundle;
-import androidx.appcompat.app.AppCompatActivity;
+import androidx.databinding.DataBindingUtil;
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 eu.siacs.conversations.databinding.ActivityAboutBinding;
-public class AboutActivity extends AppCompatActivity {
+public class AboutActivity extends BaseActivity {
- @Override
- protected void onResume(){
- super.onResume();
- SettingsUtils.applyScreenshotPreventionSetting(this);
- }
@Override
protected void onCreate(Bundle 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(findViewById(R.id.toolbar));
+ setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
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.TextView;
+import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import java.util.ArrayList;
@@ -34,7 +35,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
private final MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() {
@Override
- public boolean onMenuItemActionExpand(final MenuItem item) {
+ public boolean onMenuItemActionExpand(@NonNull final MenuItem item) {
mSearchEditText.post(() -> {
mSearchEditText.requestFocus();
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -45,7 +46,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
}
@Override
- public boolean onMenuItemActionCollapse(final MenuItem item) {
+ public boolean onMenuItemActionCollapse(@NonNull final MenuItem item) {
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
mSearchEditText.setText("");
@@ -92,6 +93,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity im
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_choose_contact);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
this.binding.chooseContactList.setFastScrollEnabled(true);
@@ -8,7 +8,7 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
-public abstract class ActionBarActivity extends AppCompatActivity {
+public abstract class ActionBarActivity extends BaseActivity {
public static void configureActionBar(ActionBar actionBar) {
configureActionBar(actionBar, true);
}
@@ -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;
+ }
+}
@@ -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.databinding.DataBindingUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.DialogBlockContactBinding;
import eu.siacs.conversations.entities.Blockable;
@@ -19,7 +21,7 @@ public final class BlockContactDialog {
show(xmppActivity, blockable, null);
}
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();
builder.setNegativeButton(R.string.cancel, null);
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.os.Bundle;
import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
import android.widget.Toast;
+import androidx.databinding.DataBindingUtil;
+
import com.google.android.material.textfield.TextInputLayout;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.ActivityChangePasswordBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
public class ChangePasswordActivity extends XmppActivity implements XmppConnectionService.OnAccountPasswordChanged {
- private Button mChangePasswordButton;
+ private ActivityChangePasswordBinding binding;
+
private final View.OnClickListener mOnChangePasswordButtonClicked = new View.OnClickListener() {
@Override
- public void onClick(View view) {
- if (mAccount != null) {
- final String currentPassword = mCurrentPassword.getText().toString();
- final String newPassword = mNewPassword.getText().toString();
- if (!mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) && !currentPassword.equals(mAccount.getPassword())) {
- mCurrentPassword.requestFocus();
- mCurrentPasswordLayout.setError(getString(R.string.account_status_unauthorized));
- removeErrorsOnAllBut(mCurrentPasswordLayout);
+ public void onClick(final View view) {
+ final var account = mAccount;
+ if (account == null) {
+ return;
+ }
+ 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()) {
- mNewPassword.requestFocus();
- mNewPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
- removeErrorsOnAllBut(mNewPasswordLayout);
+ binding.newPassword.requestFocus();
+ binding.newPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
+ removeErrorsOnAllBut(binding.newPasswordLayout);
} else {
- mCurrentPasswordLayout.setError(null);
- mNewPasswordLayout.setError(null);
- xmppConnectionService.updateAccountPasswordOnServer(mAccount, newPassword, ChangePasswordActivity.this);
- mChangePasswordButton.setEnabled(false);
- mChangePasswordButton.setText(R.string.updating);
+ 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;
@Override
void onBackendConnected() {
this.mAccount = extractAccount(getIntent());
if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
- this.mCurrentPasswordLayout.setVisibility(View.GONE);
+ this.binding.currentPasswordLayout.setVisibility(View.GONE);
} else {
- this.mCurrentPassword.setVisibility(View.VISIBLE);
+ this.binding.currentPasswordLayout.setVisibility(View.VISIBLE);
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_change_password);
- setSupportActionBar(findViewById(R.id.toolbar));
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_change_password);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+ setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
- Button mCancelButton = findViewById(R.id.left_button);
- mCancelButton.setOnClickListener(view -> finish());
- this.mChangePasswordButton = findViewById(R.id.right_button);
- this.mChangePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
- 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);
+ binding.cancelButton.setOnClickListener(view -> finish());
+ binding.changePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
+ binding.currentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
+ binding.newPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
Intent intent = getIntent();
String password = intent != null ? intent.getStringExtra("password") : null;
if (password != null) {
- this.mNewPassword.getEditableText().clear();
- this.mNewPassword.getEditableText().append(password);
+ binding.newPassword.getEditableText().clear();
+ binding.newPassword.getEditableText().append(password);
}
}
@@ -97,21 +95,21 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
@Override
public void onPasswordChangeFailed() {
runOnUiThread(() -> {
- mNewPasswordLayout.setError(getString(R.string.could_not_change_password));
- mChangePasswordButton.setEnabled(true);
- mChangePasswordButton.setText(R.string.change_password);
+ binding.newPasswordLayout.setError(getString(R.string.could_not_change_password));
+ binding.changePasswordButton.setEnabled(true);
+ binding.changePasswordButton.setText(R.string.change_password);
});
}
private void removeErrorsOnAllBut(TextInputLayout exception) {
- if (this.mCurrentPasswordLayout != exception) {
- this.mCurrentPasswordLayout.setErrorEnabled(false);
- this.mCurrentPasswordLayout.setError(null);
+ if (this.binding.currentPasswordLayout != exception) {
+ this.binding.currentPasswordLayout.setErrorEnabled(false);
+ this.binding.currentPasswordLayout.setError(null);
}
- if (this.mNewPasswordLayout != exception) {
- this.mNewPasswordLayout.setErrorEnabled(false);
- this.mNewPasswordLayout.setError(null);
+ if (this.binding.newPasswordLayout != exception) {
+ this.binding.newPasswordLayout.setErrorEnabled(false);
+ this.binding.newPasswordLayout.setError(null);
}
}
@@ -19,8 +19,11 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
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 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.util.PendingItem;
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
-import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.utils.AccountUtils;
import eu.siacs.conversations.xmpp.Jid;
@@ -81,6 +83,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_channel_discovery);
setSupportActionBar(binding.toolbar);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
configureActionBar(getSupportActionBar(), true);
binding.list.setAdapter(this.adapter);
this.adapter.setOnChannelSearchResultSelectedListener(this);
@@ -155,7 +158,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
private void toggleLoadingScreen() {
adapter.submitList(Collections.emptyList());
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
@@ -163,13 +166,13 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
super.onStart();
this.method = getMethod(this);
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.setMessage(Html.fromHtml(getString(R.string.channel_discover_opt_in_message)));
builder.setNegativeButton(R.string.cancel, (dialog, which) -> finish());
builder.setPositiveButton(R.string.confirm, (dialog, which) -> optIn());
builder.setOnCancelListener(dialog -> finish());
- final AlertDialog dialog = builder.create();
+ final androidx.appcompat.app.AlertDialog dialog = builder.create();
dialog.setOnShowListener(d -> {
final TextView textView = dialog.findViewById(android.R.id.message);
if (textView == null) {
@@ -186,7 +189,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
private void holdLoading() {
adapter.submitList(Collections.emptyList());
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
@@ -220,10 +223,10 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
runOnUiThread(() -> {
adapter.submitList(results);
binding.progressBar.setVisibility(View.GONE);
- if (results.size() == 0) {
- binding.list.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_primary_background_no_results));
+ if (results.isEmpty()) {
+ binding.list.setBackground(ContextCompat.getDrawable(this,R.drawable.background_no_results));
} 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);
if (accounts.size() == 1) {
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();
} else {
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.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));
@@ -271,10 +274,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
}
public void joinChannelSearchResult(final String selectedAccount, final Room result) {
- final Jid jid =
- Config.DOMAIN_LOCK == null
- ? Jid.ofEscaped(selectedAccount)
- : Jid.ofLocalAndDomainEscaped(selectedAccount, Config.DOMAIN_LOCK);
+ final Jid jid = Jid.ofEscaped(selectedAccount);
final boolean syncAutoJoin = getBooleanPreference("autojoin", R.bool.autojoin);
final Account account = xmppConnectionService.findAccountByJid(jid);
final Conversation conversation =
@@ -3,20 +3,21 @@ package eu.siacs.conversations.ui;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.widget.ListView;
import android.widget.Toast;
-import java.util.ArrayList;
-import java.util.List;
+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.List;
+
public class ChooseAccountForProfilePictureActivity extends XmppActivity {
protected final List<Account> accountList = new ArrayList<>();
- protected ListView accountListView;
protected AccountAdapter mAccountAdapter;
@Override
@@ -28,25 +29,21 @@ public class ChooseAccountForProfilePictureActivity extends XmppActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_manage_accounts);
- setSupportActionBar(findViewById(R.id.toolbar));
+ final ActivityManageAccountsBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_manage_accounts);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+ setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar(), false);
- accountListView = findViewById(R.id.account_list);
this.mAccountAdapter = new AccountAdapter(this, accountList, false);
- accountListView.setAdapter(this.mAccountAdapter);
- accountListView.setOnItemClickListener((arg0, view, position, arg3) -> {
+ binding.accountList.setAdapter(this.mAccountAdapter);
+ binding.accountList.setOnItemClickListener((arg0, view, position, arg3) -> {
final Account account = accountList.get(position);
goToProfilePictureActivity(account);
});
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- }
}
@Override
@@ -9,6 +9,7 @@ import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.SoundEffectConstants;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
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_CONVERSATION = "extra_conversation";
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 Set<String> filterContacts;
@@ -130,7 +131,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
if (this.showEnterJid) {
this.binding.fab.show();
} else {
- binding.fab.setImageResource(R.drawable.ic_forward_white_24dp);
+ binding.fab.setImageResource(R.drawable.ic_navigate_next_24dp);
}
final SharedPreferences preferences = getPreferences();
@@ -139,7 +140,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
}
private void onFabClicked(View v) {
- if (selected.size() == 0) {
+ if (selected.isEmpty()) {
showEnterJidDialog(null);
} else {
submitSelection();
@@ -154,7 +155,8 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
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();
final View view = getSearchEditText();
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -166,12 +168,13 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
@Override
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) {
this.binding.fab.show();
} else {
this.binding.fab.hide();
}
+ binding.chooseContactList.setFastScrollEnabled(true);
selected.clear();
}
@@ -199,8 +202,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (selected.size() != 0) {
- getListView().playSoundEffect(0);
+ getListView().playSoundEffect(SoundEffectConstants.CLICK);
}
+ getListItemAdapter().notifyDataSetChanged();
Contact item = (Contact) getListItems().get(position);
if (checked) {
selected.add(item.getJid().toString());
@@ -361,13 +365,9 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity im
void onBackendConnected() {
filterContacts();
this.mActivatedAccounts.clear();
- for (Account account : xmppConnectionService.getAccounts()) {
+ for (final Account account : xmppConnectionService.getAccounts()) {
if (account.isEnabled()) {
- if (Config.DOMAIN_LOCK != null) {
- this.mActivatedAccounts.add(account.getJid().getEscapedLocal());
- } else {
- this.mActivatedAccounts.add(account.getJid().asBareJid().toEscapedString());
- }
+ this.mActivatedAccounts.add(account.getJid().asBareJid().toEscapedString());
}
}
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.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 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() {
@Override
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);
String[] choices = {
getString(R.string.notify_on_all_messages),
@@ -130,7 +132,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
@Override
public void onClick(View v) {
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);
builder.setTitle(configuration.title);
final boolean[] values = configuration.values;
@@ -168,6 +170,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_details);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
this.binding.changeConferenceButton.setOnClickListener(this.mChangeConferenceSettings);
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
@@ -216,12 +219,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- }
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();
this.binding.mucEditor.setVisibility(View.VISIBLE);
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();
this.binding.mucEditTitle.setText("");
final boolean owner = mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER);
@@ -311,7 +310,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
private void hideEditor() {
this.binding.mucEditor.setVisibility(View.GONE);
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) {
@@ -384,7 +383,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
protected void destroyRoom() {
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.setMessage(groupChat ? R.string.destroy_room_dialog : R.string.destroy_channel_dialog);
builder.setPositiveButton(R.string.ok, (dialog, which) -> {
@@ -434,12 +433,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
final MucOptions mucOptions = mConversation.getMucOptions();
final User self = mucOptions.getSelf();
- String account;
- if (Config.DOMAIN_LOCK != null) {
- account = mConversation.getAccount().getJid().getEscapedLocal();
- } else {
- account = mConversation.getAccount().getJid().asBareJid().toEscapedString();
- }
+ final String account = mConversation.getAccount().getJid().asBareJid().toEscapedString();
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.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());
MyLinkify.addLinks(spannable, false);
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.setVisibility(View.VISIBLE);
this.binding.mucSubject.setMovementMethod(LinkMovementMethod.getInstance());
@@ -507,24 +501,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.mucSettings.setVisibility(View.GONE);
}
- int ic_notifications = getThemeResource(R.attr.icon_notifications, R.drawable.ic_notifications_black_24dp);
- 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);
+ final long mutedTill = mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
if (mutedTill == Long.MAX_VALUE) {
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) {
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()) {
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 {
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();
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 nameChanged = changed(binding.mucEditTitle.getEditableText().toString(), mucOptions.getName());
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 {
- 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.databinding.DataBindingUtil;
+import com.google.android.material.color.MaterialColors;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.Collection;
@@ -144,7 +147,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} else {
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.setMessage(getString(R.string.add_phone_book_text, value));
builder.setNegativeButton(getString(R.string.cancel), null);
@@ -215,6 +218,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
this.messageFingerprint = getIntent().getStringExtra("fingerprint");
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_details);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
@@ -238,14 +242,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override
public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- } else {
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
- this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
- this.showLastSeen = preferences.getBoolean("last_activity", false);
- }
+ 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);
mMediaAdapter.setAttachments(Collections.emptyList());
}
@@ -268,8 +267,6 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
if (MenuDoubleTabUtil.shouldIgnoreTap()) {
return false;
}
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setNegativeButton(getString(R.string.cancel), null);
switch (menuItem.getItemId()) {
case android.R.id.home:
finish();
@@ -281,6 +278,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
shareLink(false);
break;
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))
.setMessage(JidDialog.style(this, R.string.remove_contact_text, contact.getJid().toEscapedString()))
.setPositiveButton(getString(R.string.delete),
@@ -431,12 +430,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
- String account;
- if (Config.DOMAIN_LOCK != null) {
- account = contact.getAccount().getJid().getEscapedLocal();
- } else {
- account = contact.getAccount().getJid().asBareJid().toEscapedString();
- }
+ final String account = contact.getAccount().getJid().asBareJid().toEscapedString();
binding.detailsAccount.setText(getString(R.string.using_account, account));
AvatarWorkerTask.loadAvatar(contact, binding.detailsContactBadge, R.dimen.avatar_on_details_screen_size);
binding.detailsContactBadge.setOnClickListener(this::onBadgeClick);
@@ -498,7 +492,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
TextView keyType = view.findViewById(R.id.key_type);
keyType.setText(R.string.openpgp_key_id);
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()));
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);
List<ListItem.Tag> tagList = contact.getTags(this);
- if (tagList.size() == 0 || !this.showDynamicTags) {
+ if (tagList.isEmpty() || !this.showDynamicTags) {
binding.tags.setVisibility(View.GONE);
} else {
binding.tags.setVisibility(View.VISIBLE);
@@ -16,10 +16,4 @@ public class ConversationActivity extends AppCompatActivity {
startActivity(new Intent(this, ConversationsActivity.class));
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.SharedPreferences;
import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -63,6 +64,7 @@ import androidx.core.view.inputmethod.InputConnectionCompat;
import androidx.core.view.inputmethod.InputContentInfoCompat;
import androidx.databinding.DataBindingUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
@@ -1062,7 +1064,7 @@ public class ConversationFragment extends XmppFragment
};
if (conversation == null
|| conversation.getMode() == Conversation.MODE_MULTI
- || Attachment.canBeSendInband(attachments)
+ || Attachment.canBeSendInBand(attachments)
|| (conversation.getAccount().httpUploadAvailable()
&& FileBackend.allFilesUnderSize(
getActivity(), attachments, getMaxHttpUploadSize(conversation)))) {
@@ -1934,8 +1936,8 @@ public class ConversationFragment extends XmppFragment
@SuppressLint("InflateParams")
protected void clearHistoryDialog(final Conversation conversation) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
- builder.setTitle(getString(R.string.clear_conversation_history));
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
+ builder.setTitle(R.string.clear_conversation_history);
final View dialogView =
requireActivity().getLayoutInflater().inflate(R.layout.dialog_clear_history, null);
final CheckBox endConversationCheckBox =
@@ -1958,7 +1960,7 @@ public class ConversationFragment extends XmppFragment
}
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);
final int[] durations = getResources().getIntArray(R.array.mute_options_durations);
final CharSequence[] labels = new CharSequence[durations.length];
@@ -2132,7 +2134,7 @@ public class ConversationFragment extends XmppFragment
}
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);
final String errorMessage = message.getErrorMessage();
final String[] errorMessageParts =
@@ -2159,7 +2161,7 @@ public class ConversationFragment extends XmppFragment
}
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.setTitle(R.string.delete_file_dialog);
builder.setMessage(R.string.delete_file_dialog_msg);
@@ -2921,10 +2923,11 @@ public class ConversationFragment extends XmppFragment
status = Presence.Status.OFFLINE;
}
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();
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) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setIconAttribute(android.R.attr.alertDialogIcon);
+ public void showNoPGPKeyDialog(final boolean plural, final DialogInterface.OnClickListener listener) {
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
if (plural) {
builder.setTitle(getString(R.string.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.databinding.DataBindingUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.openintents.openpgp.util.OpenPgpApi;
import java.util.Arrays;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OmemoSetting;
import eu.siacs.conversations.databinding.ActivityConversationsBinding;
-import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
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.OnConversationSelected;
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.ConversationMenuConfigurator;
import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
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.SignupUtils;
import eu.siacs.conversations.utils.XmppUri;
@@ -227,10 +227,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
private boolean openBatteryOptimizationDialogIfNeeded() {
- if (isOptimizingBattery()
- && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
- && getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ if (isOptimizingBattery() && getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) {
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.battery_optimizations_enabled);
builder.setMessage(getString(R.string.battery_optimizations_enabled_dialog, getString(R.string.app_name)));
builder.setPositiveButton(R.string.next, (dialog, which) -> {
@@ -372,6 +370,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
ConversationMenuConfigurator.reloadFeatures(this);
OmemoSetting.load(this);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_conversations);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
this.getFragmentManager().addOnBackStackChangedListener(this::invalidateActionBarTitle);
@@ -466,9 +465,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
conversationFragment.reInit(conversation, extras == null ? new Bundle() : extras);
if (mainNeedsRefresh) {
refreshFragment(R.id.main_fragment);
- } else {
- invalidateActionBarTitle();
}
+ invalidateActionBarTitle();
}
private static void executePendingTransactions(final FragmentManager fragmentManager) {
@@ -546,15 +544,8 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- this.mSkipBackgroundBinding = true;
- recreate();
- } else {
- this.mSkipBackgroundBinding = false;
- }
mRedirectInProcess.set(false);
}
@@ -630,21 +621,31 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
}
final FragmentManager fragmentManager = getFragmentManager();
final Fragment mainFragment = fragmentManager.findFragmentById(R.id.main_fragment);
- if (mainFragment instanceof ConversationFragment) {
- final Conversation conversation = ((ConversationFragment) mainFragment).getConversation();
+ if (mainFragment instanceof ConversationFragment conversationFragment) {
+ final Conversation conversation = conversationFragment.getConversation();
if (conversation != null) {
actionBar.setTitle(conversation.getName());
actionBar.setDisplayHomeAsUpEnabled(true);
- ActionBarUtil.setActionBarOnClickListener(
+ ToolbarUtils.setActionBarOnClickListener(
binding.toolbar,
(v) -> openConversationDetails(conversation)
);
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);
- ActionBarUtil.resetActionBarOnClickListeners(binding.toolbar);
+ ToolbarUtils.resetActionBarOnClickListeners(binding.toolbar);
}
private void openConversationDetails(final Conversation conversation) {
@@ -50,6 +50,8 @@ import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
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.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.PendingItem;
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.EasyOnboardingInvite;
-import eu.siacs.conversations.utils.ThemeHelper;
import static androidx.recyclerview.widget.ItemTouchHelper.LEFT;
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);
if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
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);
c.drawRect(viewHolder.itemView.getLeft(),viewHolder.itemView.getTop()
,viewHolder.itemView.getRight(),viewHolder.itemView.getBottom(), paint);
@@ -196,8 +196,6 @@ public class ConversationsOverviewFragment extends XmppFragment {
activity.xmppConnectionService.archiveConversation(c);
}
});
-
- ThemeHelper.fix(snackbar);
snackbar.show();
}
};
@@ -381,14 +379,14 @@ public class ConversationsOverviewFragment extends XmppFragment {
private void selectAccountToStartEasyInvite() {
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
Toast.makeText(getActivity(),R.string.no_active_accounts_support_this, Toast.LENGTH_LONG).show();
} else if (accounts.size() == 1) {
openEasyInviteScreen(accounts.get(0));
} else {
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);
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)));
@@ -3,18 +3,20 @@ package eu.siacs.conversations.ui;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
-import android.widget.Spinner;
+import android.widget.AutoCompleteTextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.DialogFragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.R;
-import eu.siacs.conversations.databinding.CreateConferenceDialogBinding;
+import eu.siacs.conversations.databinding.DialogCreateConferenceBinding;
import eu.siacs.conversations.ui.util.DelayedHintHelper;
public class CreatePrivateGroupChatDialog extends DialogFragment {
@@ -39,9 +41,9 @@ public class CreatePrivateGroupChatDialog extends DialogFragment {
@NonNull
@Override
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);
- 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);
StartConversationActivity.populateAccountSpinner(getActivity(), mActivatedAccounts, binding.account);
builder.setView(binding.getRoot());
@@ -57,7 +59,7 @@ public class CreatePrivateGroupChatDialog extends DialogFragment {
public interface CreateConferenceDialogListener {
- void onCreateDialogPositiveClick(Spinner spinner, String subject);
+ void onCreateDialogPositiveClick(AutoCompleteTextView spinner, String subject);
}
@Override
@@ -17,13 +17,14 @@ import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.DialogFragment;
-import java.security.SecureRandom;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.services.XmppConnectionService;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
@@ -44,7 +45,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
private boolean nameEntered = false;
private boolean skipTetxWatcher = false;
- public static CreatePublicChannelDialog newInstance(List<String> accounts) {
+ public static CreatePublicChannelDialog newInstance(final List<String> accounts) {
CreatePublicChannelDialog dialog = new CreatePublicChannelDialog();
Bundle bundle = new Bundle();
bundle.putStringArrayList(ACCOUNTS_LIST_KEY, (ArrayList<String>) accounts);
@@ -63,9 +64,9 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
public Dialog onCreateDialog(Bundle savedInstanceState) {
jidWasModified = savedInstanceState != null && savedInstanceState.getBoolean("jid_was_modified_false", 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);
- 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() {
@Override
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.setNegativeButton(nameEntered ? R.string.back : R.string.cancel, null);
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);
final AlertDialog dialog = builder.create();
binding.groupChatName.setOnEditorActionListener((v, actionId, event) -> {
@@ -121,7 +122,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
return dialog;
}
- private void updateJidSuggestion(CreatePublicChannelDialogBinding binding) {
+ private void updateJidSuggestion(final DialogCreatePublicChannelBinding binding) {
if (jidWasModified) {
return;
}
@@ -138,7 +139,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
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 XmppConnection connection = account == null ? null : account.getXmppConnection();
if (connection == null) {
@@ -169,7 +170,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
return name.replaceAll("\\s+","-");
}
- private void goBack(AlertDialog dialog, CreatePublicChannelDialogBinding binding) {
+ private void goBack(AlertDialog dialog, DialogCreatePublicChannelBinding binding) {
if (nameEntered) {
nameEntered = false;
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 Editable nameText = binding.groupChatName.getText();
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.nameLayout.setVisibility(nameEntered ? View.GONE : View.VISIBLE);
if (!requestFocus) {
@@ -265,7 +266,7 @@ public class CreatePublicChannelDialog extends DialogFragment implements OnBacke
}
@Override
- public void onAttach(Context context) {
+ public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
mListener = (CreatePublicChannelDialogListener) context;
@@ -33,9 +33,10 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AlertDialog.Builder;
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.common.base.CharMatcher;
@@ -98,7 +99,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private Jid jidToEdit;
private boolean mInitMode = false;
private Boolean mForceRegister = null;
- private boolean mUsernameMode = Config.DOMAIN_LOCK != null;
+ private boolean mUsernameMode = false;
private boolean mShowOptions = false;
private Account mAccount;
private final OnClickListener mCancelButtonClickListener = v -> {
@@ -609,6 +610,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mSavedInstanceInit = savedInstanceState.getBoolean("initMode", false);
}
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_account);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
binding.accountJid.addTextChangedListener(this.mTextWatcher);
binding.accountJid.setOnFocusChangeListener(this.mEditTextFocusListener);
@@ -697,13 +699,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
final Intent intent = getIntent();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- } else if (intent != null) {
+ if (intent != null) {
try {
this.jidToEdit = Jid.ofEscaped(intent.getStringExtra("jid"));
} catch (final IllegalArgumentException | NullPointerException ignored) {
@@ -758,7 +757,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
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);
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
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());
- AlertDialog dialog = builder.create();
+ final var dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.setOnCancelListener(d -> finish());
dialog.show();
@@ -835,7 +834,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.binding.accountJidLayout.setHint(getString(R.string.username_hint));
} else {
final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
- R.layout.simple_list_item,
+ R.layout.item_autocomplete,
xmppConnectionService.getKnownHosts());
this.binding.accountJid.setAdapter(mKnownHostsAdapter);
}
@@ -853,7 +852,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
if (mAccount != null && mAccount.getJid().getDomain() != null) {
return mAccount.getServer();
} else {
- return Config.DOMAIN_LOCK;
+ return null;
}
}
@@ -940,7 +939,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private void changePresence() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
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);
String current = mAccount.getPresenceStatusMessage();
if (current != null && !current.trim().isEmpty()) {
@@ -949,7 +948,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
setAvailabilityRadioButton(mAccount.getPresenceStatus(), binding);
binding.show.setVisibility(manualStatus ? View.VISIBLE : View.GONE);
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.setOnItemClickListener((parent, view, position, id) -> {
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.setOnClickListener(openPgp);
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.actionDeletePgp.setOnClickListener(delete);
@@ -1155,10 +1154,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
if (ownAxolotlFingerprint != null && Config.supportOmemo()) {
this.binding.axolotlFingerprintBox.setVisibility(View.VISIBLE);
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);
} 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.axolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(ownAxolotlFingerprint.substring(2)));
@@ -1222,10 +1221,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private void updateDisplayName(String displayName) {
if (TextUtils.isEmpty(displayName)) {
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 {
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() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.unpublish_pgp);
builder.setMessage(R.string.unpublish_pgp_message);
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();
}
});
- } 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.osOptimizationHeadline.setText(R.string.battery_optimizations_enabled);
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() {
- Builder builder = new Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(getString(R.string.clear_other_devices));
builder.setIconAttribute(android.R.attr.alertDialogIcon);
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()) {
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 ImageView imageView = view.findViewById(R.id.captcha);
final EditText input = view.findViewById(R.id.input);
@@ -1372,7 +1371,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
if (mFetchingMamPrefsToast != null) {
mFetchingMamPrefsToast.cancel();
}
- Builder builder = new Builder(EditAccountActivity.this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(EditAccountActivity.this);
builder.setTitle(R.string.server_side_mam_prefs);
String defaultAttr = prefs.getAttribute("default");
final List<String> defaults = Arrays.asList("never", "roster", "always");
@@ -13,15 +13,17 @@ import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
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.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import eu.siacs.conversations.Config;
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.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
@@ -46,28 +48,28 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
private KnownHostsAdapter knownHostsAdapter;
private Collection<String> whitelistedDomains = Collections.emptyList();
- private EnterJidDialogBinding binding;
+ private DialogEnterJidBinding binding;
private AlertDialog dialog;
private boolean sanityCheckJid = false;
private boolean issuedWarning = false;
public static EnterJidDialog newInstance(
- final List<String> activatedAccounts,
+ final ArrayList<String> activatedAccounts,
final String title,
final String positiveButton,
final String prefilledJid,
final String account,
boolean allowEditJid,
final boolean sanity_check_jid) {
- EnterJidDialog dialog = new EnterJidDialog();
+ final EnterJidDialog dialog = new EnterJidDialog();
Bundle bundle = new Bundle();
bundle.putString(TITLE_KEY, title);
bundle.putString(POSITIVE_BUTTON_KEY, positiveButton);
bundle.putString(PREFILLED_JID_KEY, prefilledJid);
bundle.putString(ACCOUNT_KEY, account);
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);
dialog.setArguments(bundle);
return dialog;
@@ -91,16 +93,16 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
@NonNull
@Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle(getArguments().getString(TITLE_KEY));
+ public Dialog onCreateDialog(final Bundle savedInstanceState) {
+ final var arguments = getArguments();
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity());
+ builder.setTitle(arguments.getString(TITLE_KEY));
binding =
- DataBindingUtil.inflate(
- getActivity().getLayoutInflater(), R.layout.enter_jid_dialog, null, false);
- this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item);
+ DataBindingUtil.inflate(requireActivity().getLayoutInflater(), R.layout.dialog_enter_jid, null, false);
+ this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.item_autocomplete);
binding.jid.setAdapter(this.knownHostsAdapter);
binding.jid.addTextChangedListener(this);
- String prefilledJid = getArguments().getString(PREFILLED_JID_KEY);
+ final String prefilledJid = arguments.getString(PREFILLED_JID_KEY);
if (prefilledJid != null) {
binding.jid.append(prefilledJid);
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);
- String account = getArguments().getString(ACCOUNT_KEY);
- if (account == null) {
+ final String account = getArguments().getString(ACCOUNT_KEY);
+ if (Strings.isNullOrEmpty(account)) {
StartConversationActivity.populateAccountSpinner(
getActivity(),
- getArguments().getStringArrayList(ACCOUNTS_LIST_KEY),
+ arguments.getStringArrayList(ACCOUNTS_LIST_KEY),
binding.account);
} else {
- ArrayAdapter<String> adapter =
- new ArrayAdapter<>(
- getActivity(), R.layout.simple_list_item, new String[] {account});
+ final ArrayAdapter<String> adapter =
+ new ArrayAdapter<>(requireActivity(), R.layout.item_autocomplete, new String[] {account});
+ binding.account.setText(account);
binding.account.setEnabled(false);
- adapter.setDropDownViewResource(R.layout.simple_list_item);
+ adapter.setDropDownViewResource(R.layout.item_autocomplete);
binding.account.setAdapter(adapter);
}
@@ -135,9 +137,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
this.dialog = builder.create();
View.OnClickListener dialogOnClick =
- v -> {
- handleEnter(binding, account);
- };
+ v -> handleEnter(binding, account);
binding.jid.setOnEditorActionListener(
(v, actionId, event) -> {
@@ -150,21 +150,13 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
return dialog;
}
- private void handleEnter(EnterJidDialogBinding binding, String account) {
+ private void handleEnter(DialogEnterJidBinding binding, String account) {
final Jid accountJid;
if (!binding.account.isEnabled() && account == null) {
return;
}
try {
- if (Config.DOMAIN_LOCK != null) {
- accountJid =
- Jid.ofEscaped(
- (String) binding.account.getSelectedItem(),
- Config.DOMAIN_LOCK,
- null);
- } else {
- accountJid = Jid.ofEscaped((String) binding.account.getSelectedItem());
- }
+ accountJid = Jid.ofEscaped((String) binding.account.getEditableText().toString());
} catch (final IllegalArgumentException e) {
return;
}
@@ -13,6 +13,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.DialogFragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import java.util.ArrayList;
@@ -50,11 +51,11 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
@NonNull
@Override
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);
- 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);
- this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.simple_list_item);
+ this.knownHostsAdapter = new KnownHostsAdapter(getActivity(), R.layout.item_autocomplete);
binding.jid.setAdapter(knownHostsAdapter);
String prefilledJid = getArguments().getString(PREFILLED_JID_KEY);
if (prefilledJid != null) {
@@ -117,6 +118,6 @@ public class JoinConferenceDialog extends DialogFragment implements OnBackendCon
}
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.MyLocation;
import eu.siacs.conversations.ui.util.SettingsUtils;
-import eu.siacs.conversations.utils.ThemeHelper;
public abstract class LocationActivity extends ActionBarActivity implements LocationListener {
protected LocationManager locationManager;
@@ -78,7 +77,6 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context ctx = getApplicationContext();
- setTheme(ThemeHelper.find(this));
final PackageManager packageManager = ctx.getPackageManager();
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
// 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).
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && savedInstanceState == null) {
+ if (savedInstanceState == null) {
requestPermissions(REQUEST_CODE_CREATE);
}
@@ -224,7 +222,6 @@ public abstract class LocationActivity extends ActionBarActivity implements Loca
@Override
protected void onResume() {
super.onResume();
- SettingsUtils.applyScreenshotPreventionSetting(this);
Configuration.getInstance().load(this, getPreferences());
map.onResume();
this.setMyLoc(null);
@@ -29,6 +29,7 @@ public class MediaBrowserActivity extends XmppActivity implements OnMediaLoaded
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this,R.layout.activity_media_browser);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
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.AppCompatActivity;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -40,7 +42,6 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.MTMDecision;
import eu.siacs.conversations.services.MemorizingTrustManager;
import eu.siacs.conversations.ui.util.SettingsUtils;
-import eu.siacs.conversations.utils.ThemeHelper;
public class MemorizingActivity extends AppCompatActivity implements OnClickListener, OnCancelListener {
@@ -53,10 +54,7 @@ public class MemorizingActivity extends AppCompatActivity implements OnClickList
@Override
public void onCreate(Bundle savedInstanceState) {
LOGGER.log(Level.FINE, "onCreate");
- setTheme(ThemeHelper.find(this));
super.onCreate(savedInstanceState);
- getLayoutInflater().inflate(R.layout.toolbar, findViewById(android.R.id.content));
- setSupportActionBar(findViewById(R.id.toolbar));
}
@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);
String cert = i.getStringExtra(MemorizingTrustManager.DECISION_INTENT_CERT);
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)
.setPositiveButton(R.string.always, this)
.setNeutralButton(R.string.once, this)
@@ -102,8 +102,9 @@ public class MucUsersActivity extends XmppActivity implements XmppConnectionServ
@Override
protected void onCreate(final Bundle 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);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
configureActionBar(getSupportActionBar(), true);
this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
binding.list.setAdapter(this.userAdapter);
@@ -11,6 +11,9 @@ import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
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.R;
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 fingerprint = v.getTag(R.id.TAG_FINGERPRINT);
Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS);
- if (account != null
- && fingerprint != null
- && account instanceof Account
- && fingerprintStatus != null
+ if (account instanceof Account
&& fingerprint instanceof String
&& fingerprintStatus instanceof FingerprintStatus) {
getMenuInflater().inflate(R.menu.omemo_key_context, menu);
@@ -130,8 +130,8 @@ public abstract class OmemoActivity extends XmppActivity {
binding.tglTrust.setChecked(status.isTrusted());
if (status.isActive()) {
- binding.key.setTextAppearance(this,R.style.TextAppearance_Conversations_Fingerprint);
- binding.keyType.setTextAppearance(this,R.style.TextAppearance_Conversations_Caption);
+ binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurface));
+ binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorOnSurface));
if (status.isVerified()) {
binding.verifiedFingerprint.setVisibility(View.VISIBLE);
binding.verifiedFingerprint.setAlpha(1.0f);
@@ -157,8 +157,8 @@ public abstract class OmemoActivity extends XmppActivity {
toast = v -> hideToast();
}
} else {
- binding.key.setTextAppearance(this,R.style.TextAppearance_Conversations_Fingerprint_Disabled);
- binding.keyType.setTextAppearance(this,R.style.TextAppearance_Conversations_Caption_Disabled);
+ binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurfaceVariant));
+ 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);
if (status.isVerified()) {
binding.tglTrust.setVisibility(View.GONE);
@@ -181,7 +181,7 @@ public abstract class OmemoActivity extends XmppActivity {
binding.keyType.setVisibility(View.GONE);
}
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));
} else {
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) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.distrust_omemo_key);
builder.setMessage(R.string.distrust_omemo_key_text);
builder.setNegativeButton(getString(R.string.cancel), null);
@@ -91,6 +91,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_publish_profile_picture);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(this.binding.toolbar);
configureActionBar(getSupportActionBar());
this.binding.cancelButton.setOnClickListener((v) -> this.finish());
@@ -114,6 +115,7 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
final CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
@@ -18,6 +18,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
+import androidx.databinding.DataBindingUtil;
import com.canhub.cropper.CropImage;
@@ -25,6 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.databinding.ActivityPublishProfilePictureBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
@@ -77,7 +79,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
public void onAvatarPublicationFailed(int res) {
runOnUiThread(() -> {
hintOrWarning.setText(res);
- hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
hintOrWarning.setVisibility(View.VISIBLE);
publishing = false;
togglePublishButton(true, R.string.publish);
@@ -87,8 +88,12 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
@Override
public void onCreate(Bundle 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.cancelButton = findViewById(R.id.cancel_button);
@@ -220,7 +225,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
final Intent intent = getIntent();
this.mInitialAccountSetup = intent != null && intent.getBooleanExtra("setup", false);
@@ -261,7 +266,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
if (bm == null) {
togglePublishButton(false, R.string.publish);
this.hintOrWarning.setVisibility(View.VISIBLE);
- this.hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
return;
}
@@ -272,7 +276,6 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
} else {
togglePublishButton(false, R.string.publish);
this.hintOrWarning.setVisibility(View.VISIBLE);
- this.hintOrWarning.setTextAppearance(this,R.style.TextAppearance_Conversations_Body1_Warning);
if (account.getStatus() == Account.State.ONLINE) {
this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
} else {
@@ -15,6 +15,7 @@ import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import com.google.common.collect.ImmutableSet;
@@ -33,10 +34,9 @@ import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ActivityRecordingBinding;
import eu.siacs.conversations.ui.util.SettingsUtils;
-import eu.siacs.conversations.utils.ThemeHelper;
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;
@@ -61,7 +61,6 @@ public class RecordingActivity extends Activity implements View.OnClickListener
@Override
protected void onCreate(Bundle savedInstanceState) {
- setTheme(ThemeHelper.findDialog(this));
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_recording);
this.binding.cancelButton.setOnClickListener(this);
@@ -69,19 +68,13 @@ public class RecordingActivity extends Activity implements View.OnClickListener
this.setFinishOnTouchOutside(false);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
-
- @Override
- protected void onResume() {
- super.onResume();
- SettingsUtils.applyScreenshotPreventionSetting(this);
- }
-
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
if (!startRecording()) {
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);
}
}
@@ -179,6 +179,7 @@ public class RtpSessionActivity extends XmppActivity
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_rtp_session);
setSupportActionBar(binding.toolbar);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
}
@Override
@@ -920,34 +921,34 @@ public class RtpSessionActivity extends XmppActivity
} else if (state == RtpEndUserState.INCOMING_CALL) {
this.binding.rejectCall.setContentDescription(getString(R.string.dismiss_call));
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.endCall.setVisibility(View.INVISIBLE);
this.binding.acceptCall.setContentDescription(getString(R.string.answer_call));
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);
} else if (state == RtpEndUserState.INCOMING_CONTENT_ADD) {
this.binding.rejectCall.setContentDescription(
getString(R.string.reject_switch_to_video));
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.endCall.setVisibility(View.INVISIBLE);
this.binding.acceptCall.setContentDescription(getString(R.string.accept));
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);
} else if (asList(RtpEndUserState.DECLINED_OR_BUSY, RtpEndUserState.CONTACT_OFFLINE)
.contains(state)) {
this.binding.rejectCall.setContentDescription(getString(R.string.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.endCall.setVisibility(View.INVISIBLE);
this.binding.acceptCall.setContentDescription(getString(R.string.record_voice_mail));
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);
} else if (asList(
RtpEndUserState.CONNECTIVITY_ERROR,
@@ -958,18 +959,18 @@ public class RtpSessionActivity extends XmppActivity
.contains(state)) {
this.binding.rejectCall.setContentDescription(getString(R.string.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.endCall.setVisibility(View.INVISIBLE);
this.binding.acceptCall.setContentDescription(getString(R.string.try_again));
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);
} else {
this.binding.rejectCall.setVisibility(View.INVISIBLE);
this.binding.endCall.setContentDescription(getString(R.string.hang_up));
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.acceptCall.setVisibility(View.INVISIBLE);
}
@@ -1038,7 +1039,7 @@ public class RtpSessionActivity extends XmppActivity
switch (selectedAudioDevice) {
case EARPIECE -> {
this.binding.inCallActionRight.setImageResource(
- R.drawable.ic_volume_off_black_24dp);
+ R.drawable.ic_volume_off_24dp);
if (numberOfChoices >= 2) {
this.binding.inCallActionRight.setOnClickListener(this::switchToSpeaker);
} else {
@@ -1047,12 +1048,12 @@ public class RtpSessionActivity extends XmppActivity
}
}
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.setClickable(false);
}
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) {
this.binding.inCallActionRight.setOnClickListener(this::switchToEarpiece);
} else {
@@ -1062,7 +1063,7 @@ public class RtpSessionActivity extends XmppActivity
}
case BLUETOOTH -> {
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.setClickable(false);
}
@@ -1076,17 +1077,17 @@ public class RtpSessionActivity extends XmppActivity
this.binding.inCallActionRight.setVisibility(View.VISIBLE);
if (isCameraSwitchable) {
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.setOnClickListener(this::switchCamera);
} else {
this.binding.inCallActionFarRight.setVisibility(View.GONE);
}
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);
} 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);
}
}
@@ -1140,10 +1141,10 @@ public class RtpSessionActivity extends XmppActivity
@SuppressLint("RestrictedApi")
private void updateInCallButtonConfigurationMicrophone(final boolean 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);
} 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.setVisibility(View.VISIBLE);
@@ -182,7 +182,6 @@ public final class ScanActivity extends Activity implements SurfaceTextureListen
@Override
protected void onResume() {
super.onResume();
- SettingsUtils.applyScreenshotPreventionSetting(this);
maybeOpenCamera();
}
@@ -42,8 +42,10 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
+import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
+import com.google.android.material.color.MaterialColors;
import com.google.common.base.Strings;
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.PendingItem;
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.MessageUtils;
@@ -95,6 +96,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
}
super.onCreate(bundle);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_search);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(this.binding.toolbar);
configureActionBar(getSupportActionBar());
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) {
if (hasSearch) {
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 {
- binding.searchResults.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_background_no_results));
+ binding.searchResults.setBackgroundResource(R.drawable.background_no_results);
}
} 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)) {
return;
}
- if (term.size() > 0) {
- xmppConnectionService.search(term, uuid,this);
- } else {
+ if (term.isEmpty()) {
MessageSearchTask.cancelRunningTasks();
this.messages.clear();
messageListAdapter.setHighlightedTerm(null);
messageListAdapter.notifyDataSetChanged();
changeBackground(false, false);
+ } else {
+ xmppConnectionService.search(term, uuid,this);
}
}
@@ -267,7 +269,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc
DateSeparator.addAll(messages);
this.messages.addAll(messages);
messageListAdapter.notifyDataSetChanged();
- changeBackground(true, messages.size() > 0);
+ changeBackground(true, !messages.isEmpty());
ListViewUtils.scrollToBottom(this.binding.searchResults);
});
}
@@ -22,7 +22,10 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
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.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -37,8 +40,10 @@ import java.util.Collections;
import java.util.List;
import eu.siacs.conversations.Config;
+import eu.siacs.conversations.Conversations;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OmemoSetting;
+import eu.siacs.conversations.databinding.ActivitySettingsBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.persistance.FileBackend;
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.UnifiedPushDistributor;
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.TimeFrameUtils;
-import eu.siacs.conversations.xmpp.InvalidJid;
import eu.siacs.conversations.xmpp.Jid;
public class SettingsActivity extends XmppActivity implements OnSharedPreferenceChangeListener {
@@ -74,7 +77,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_settings);
+ final ActivitySettingsBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_settings);
FragmentManager fm = getFragmentManager();
mSettingsFragment = (SettingsFragment) fm.findFragmentById(R.id.settings_content);
if (mSettingsFragment == null
@@ -83,13 +86,8 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
fm.beginTransaction().replace(R.id.settings_content, mSettingsFragment).commit();
}
mSettingsFragment.setActivityIntent(getIntent());
- this.mTheme = findTheme();
- setTheme(this.mTheme);
- getWindow()
- .getDecorView()
- .setBackgroundColor(
- StyledAttributes.getColor(this, R.attr.color_background_primary));
- setSupportActionBar(findViewById(R.id.toolbar));
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+ setSupportActionBar(binding.toolbar);
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) mSettingsFragment.findPreference(AUTOMATIC_MESSAGE_DELETION);
if (automaticMessageDeletionList != null) {
@@ -204,36 +208,6 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
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 =
mSettingsFragment.findPreference("remove_trusted_certificates");
if (removeCertsPreference != null) {
@@ -242,17 +216,16 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
final MemorizingTrustManager mtm =
xmppConnectionService.getMemorizingTrustManager();
final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
- if (aliases.size() == 0) {
+ if (aliases.isEmpty()) {
displayToast(getString(R.string.toast_no_trusted_certs));
return true;
}
final ArrayList<Integer> selectedItems = new ArrayList<>();
- final AlertDialog.Builder dialogBuilder =
- new AlertDialog.Builder(SettingsActivity.this);
+ final MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(SettingsActivity.this);
dialogBuilder.setTitle(
getResources().getString(R.string.dialog_manage_certs_title));
dialogBuilder.setMultiChoiceItems(
- aliases.toArray(new CharSequence[aliases.size()]),
+ aliases.toArray(new CharSequence[0]),
null,
(dialog, indexSelected, isChecked) -> {
if (isChecked) {
@@ -262,7 +235,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
}
((AlertDialog) dialog)
.getButton(DialogInterface.BUTTON_POSITIVE)
- .setEnabled(selectedItems.size() > 0);
+ .setEnabled(!selectedItems.isEmpty());
});
dialogBuilder.setPositiveButton(
@@ -273,13 +246,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
if (count > 0) {
for (int i = 0; i < count; i++) {
try {
- Integer item =
- Integer.valueOf(
+ final int item =
+ Integer.parseInt(
selectedItems.get(i).toString());
String alias = aliases.get(item);
mtm.deleteCertificate(alias);
- } catch (KeyStoreException e) {
- e.printStackTrace();
+ } catch (final KeyStoreException e) {
displayToast("Error: " + e.getLocalizedMessage());
}
}
@@ -372,10 +344,8 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
private boolean isCallable(final Intent i) {
return i != null
- && getPackageManager()
- .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY)
- .size()
- > 0;
+ && !getPackageManager()
+ .queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY).isEmpty();
}
private boolean cleanCache() {
@@ -413,7 +383,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
}
private boolean deleteOmemoIdentities() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.pref_delete_omemo_identities);
final List<CharSequence> accounts = new ArrayList<>();
for (Account account : xmppConnectionService.getAccounts()) {
@@ -502,10 +472,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
} else if (name.equals(AUTOMATIC_MESSAGE_DELETION)) {
xmppConnectionService.expireOldMessages(true);
} else if (name.equals(THEME)) {
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- }
+ final var value = preferences.getString(THEME,getString(R.string.theme));
+ final int desiredNightMode = Conversations.getDesiredNightMode(value);
+ setDesiredNightMode(desiredNightMode);
+ } else if (name.equals("dynamic_colors")) {
+ final var value = preferences.getBoolean("dynamic_colors",false);
+ setDynamicColors(value);
} else if (name.equals(PREVENT_SCREENSHOTS)) {
SettingsUtils.applyScreenshotPreventionSetting(this);
} else if (UnifiedPushDistributor.PREFERENCES.contains(name)) {
@@ -572,7 +544,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference
private void createBackup() {
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.setPositiveButton(R.string.ok, null);
builder.create().show();
@@ -5,7 +5,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
-import android.os.Build;
import android.os.Bundle;
import android.view.View;
@@ -15,11 +14,6 @@ import androidx.databinding.DataBindingUtil;
import com.google.android.material.snackbar.Snackbar;
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.R;
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.MyLocation;
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 {
@@ -58,6 +56,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_share_location);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
setupMapView(binding.map, LocationProvider.getGeoPoint(this));
@@ -71,13 +70,12 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
this.snackBar.setAction(R.string.enable, view -> {
if (isLocationEnabledAndAllowed()) {
updateUi();
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasLocationPermissions()) {
+ } else if (!hasLocationPermissions()) {
requestPermissions(REQUEST_CODE_SNACKBAR_PRESSED);
} else if (!isLocationEnabled()) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
});
- ThemeHelper.fix(this.snackBar);
this.binding.shareButton.setOnClickListener(this::shareLocation);
@@ -87,7 +85,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
if (!marker_fixed_to_loc) {
if (!isLocationEnabled()) {
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);
}
}
@@ -117,16 +115,9 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
@NonNull final int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (grantResults.length > 0 &&
- grantResults[0] != PackageManager.PERMISSION_GRANTED &&
- Build.VERSION.SDK_INT >= 23 &&
- 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])) {
+ if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED && 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;
}
@@ -172,7 +163,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
}
@Override
- public void onLocationChanged(final Location location) {
+ public void onLocationChanged(@NonNull final Location location) {
if (this.myLoc == null) {
this.marker_fixed_to_loc = true;
}
@@ -206,7 +197,7 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
}
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() {
@@ -229,8 +220,8 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
if (isLocationEnabledAndAllowed()) {
this.binding.fab.setVisibility(View.VISIBLE);
runOnUiThread(() -> {
- this.binding.fab.setImageResource(marker_fixed_to_loc ? R.drawable.ic_gps_fixed_white_24dp :
- R.drawable.ic_gps_not_fixed_white_24dp);
+ this.binding.fab.setImageResource(marker_fixed_to_loc ? R.drawable.ic_gps_fixed_24dp :
+ R.drawable.ic_gps_not_fixed_24dp);
this.binding.fab.setContentDescription(getResources().getString(
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.widget.Toast;
+import androidx.annotation.NonNull;
+import androidx.databinding.DataBindingUtil;
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.R;
+import eu.siacs.conversations.databinding.ActivityShareWithBinding;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
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 Conversation mPendingConversation = null;
@@ -48,11 +51,10 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
private ConversationAdapter mAdapter;
private final List<Conversation> mConversations = new ArrayList<>();
-
- protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
+ protected void onActivityResult(
+ final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_START_NEW_CONVERSATION
- && resultCode == RESULT_OK) {
+ if (requestCode == REQUEST_START_NEW_CONVERSATION && resultCode == RESULT_OK) {
share.contact = data.getStringExtra("contact");
share.account = data.getStringExtra(EXTRA_ACCOUNT);
}
@@ -65,7 +67,10 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
}
@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);
if (grantResults.length > 0)
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
@@ -77,27 +82,35 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
}
}
} 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
- protected void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_share_with);
- setSupportActionBar(findViewById(R.id.toolbar));
- if (getSupportActionBar() != null) {
- getSupportActionBar().setDisplayHomeAsUpEnabled(false);
- getSupportActionBar().setHomeButtonEnabled(false);
+ final ActivityShareWithBinding binding =
+ DataBindingUtil.setContentView(this, R.layout.activity_share_with);
+ setSupportActionBar(binding.toolbar);
+ 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);
- mListView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
- mListView.setAdapter(mAdapter);
+ binding.chooseConversationList.setLayoutManager(
+ new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
+ binding.chooseConversationList.setAdapter(mAdapter);
mAdapter.setConversationClickListener((view, conversation) -> share(conversation));
this.share = new Share();
}
@@ -112,8 +125,9 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add:
- final Intent intent = new Intent(getApplicationContext(), ChooseContactActivity.class);
- intent.putExtra("direct_search",true);
+ final Intent intent =
+ new Intent(getApplicationContext(), ChooseContactActivity.class);
+ intent.putExtra("direct_search", true);
startActivityForResult(intent, REQUEST_START_NEW_CONVERSATION);
return true;
}
@@ -133,7 +147,8 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
if (Intent.ACTION_SEND.equals(action)) {
final String text = intent.getStringExtra(Intent.EXTRA_TEXT);
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())) {
this.share.uris.clear();
@@ -151,14 +166,16 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
this.share.uris = uris == null ? new ArrayList<>() : uris;
}
if (xmppConnectionServiceBound) {
- xmppConnectionService.populateWithOrderedConversations(mConversations, this.share.uris.size() == 0, false);
+ xmppConnectionService.populateWithOrderedConversations(
+ mConversations, this.share.uris.isEmpty(), false);
}
-
}
@Override
void onBackendConnected() {
- if (xmppConnectionServiceBound && share != null && ((share.contact != null && share.account != null))) {
+ if (xmppConnectionServiceBound
+ && share != null
+ && ((share.contact != null && share.account != null))) {
share();
return;
}
@@ -167,32 +184,34 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
private void share() {
final Conversation conversation;
- Account account;
- try {
- account = xmppConnectionService.findAccountByJid(Jid.ofEscaped(share.account));
- } catch (final IllegalArgumentException e) {
- account = null;
- }
- if (account == null) {
- return;
- }
+ Account account;
+ try {
+ account = xmppConnectionService.findAccountByJid(Jid.ofEscaped(share.account));
+ } catch (final IllegalArgumentException e) {
+ account = null;
+ }
+ if (account == null) {
+ return;
+ }
- try {
- conversation = xmppConnectionService.findOrCreateConversation(account, Jid.of(share.contact), false, true);
- } catch (final IllegalArgumentException e) {
- return;
- }
+ try {
+ conversation =
+ xmppConnectionService.findOrCreateConversation(
+ account, Jid.of(share.contact), false, true);
+ } catch (final IllegalArgumentException e) {
+ return;
+ }
share(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;
return;
}
- Intent intent = new Intent(this, ConversationsActivity.class);
+ final Intent intent = new Intent(this, ConversationsActivity.class);
intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
- if (share.uris.size() > 0) {
+ if (!share.uris.isEmpty()) {
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, share.uris);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -207,15 +226,20 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
try {
startActivity(intent);
} 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;
}
finish();
}
public void refreshUiReal() {
- //TODO inject desired order to not resort on refresh
- xmppConnectionService.populateWithOrderedConversations(mConversations, this.share != null && this.share.uris.size() == 0, false);
+ // TODO inject desired order to not resort on refresh
+ xmppConnectionService.populateWithOrderedConversations(
+ mConversations, this.share != null && this.share.uris.isEmpty(), false);
mAdapter.notifyDataSetChanged();
}
}
@@ -45,7 +45,7 @@ public class ShortcutActivity extends AbstractSearchableListItemActivity {
}
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
ActionBar bar = getSupportActionBar();
if(bar != null){
@@ -49,6 +49,8 @@ public class ShowLocationActivity extends LocationActivity implements LocationLi
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_show_location);
setSupportActionBar(binding.toolbar);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
+
configureActionBar(getSupportActionBar());
setupMapView(this.binding.map, this.loc);
@@ -6,7 +6,6 @@ import android.app.Dialog;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -55,7 +54,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager.widget.PagerAdapter;
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.common.collect.Iterables;
import com.leinardi.android.speeddial.SpeedDialActionItem;
import com.leinardi.android.speeddial.SpeedDialView;
@@ -109,7 +111,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
private ListItemAdapter mContactsAdapter;
private final List<ListItem> conferences = new ArrayList<>();
private ListItemAdapter mConferenceAdapter;
- private final List<String> mActivatedAccounts = new ArrayList<>();
+ private final ArrayList<String> mActivatedAccounts = new ArrayList<>();
private EditText mSearchEditText;
private final AtomicBoolean mRequestedContactsPermission = 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) {
- if (accounts.size() > 0) {
- 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 {
+ public static void populateAccountSpinner(final Context context, final List<String> accounts, final AutoCompleteTextView spinner) {
+ if (accounts.isEmpty()) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
- R.layout.simple_list_item,
+ R.layout.item_autocomplete,
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.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) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_start_conversation);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
@@ -363,7 +367,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
}
final SpeedDialActionItem actionItem = new SpeedDialActionItem.Builder(menuItem.getItemId(), menuItem.getIcon())
.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();
speedDialView.addActionItem(actionItem);
}
@@ -394,13 +399,8 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
@Override
public void onStart() {
super.onStart();
- final int theme = findTheme();
- if (this.mTheme != theme) {
- recreate();
- } else {
- if (pendingViewIntent.peek() == null) {
- askForContactsPermissions();
- }
+ if (pendingViewIntent.peek() == null) {
+ askForContactsPermissions();
}
mConferenceAdapter.refreshSettings();
mContactsAdapter.refreshSettings();
@@ -490,7 +490,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
protected void deleteContact() {
final int position = contact_context_id;
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.setTitle(R.string.action_delete_contact);
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 var conversation = bookmark.getConversation();
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.setTitle(R.string.delete_bookmark);
if (hasConversation) {
@@ -611,18 +611,14 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
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()) {
return null;
}
if (context instanceof XmppActivity) {
- Jid jid;
+ final Jid jid;
try {
- if (Config.DOMAIN_LOCK != null) {
- jid = Jid.ofEscaped((String) spinner.getSelectedItem(), Config.DOMAIN_LOCK, null);
- } else {
- jid = Jid.ofEscaped((String) spinner.getSelectedItem());
- }
+ jid = Jid.ofEscaped(spinner.getText().toString());
} catch (final IllegalArgumentException e) {
return null;
}
@@ -792,7 +788,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
if (requiresConsent
|| shouldShowRequestPermissionRationale(
Manifest.permission.READ_CONTACTS)) {
- final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
final AtomicBoolean requestPermission = new AtomicBoolean(false);
if (QuickConversationsService.isQuicksy()) {
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) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.verify_omemo_keys);
View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null);
final CheckBox isTrustedSource = view.findViewById(R.id.trusted_source);
@@ -1104,7 +1100,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
}
@Override
- public void onCreateDialogPositiveClick(Spinner spinner, String name) {
+ public void onCreateDialogPositiveClick(AutoCompleteTextView spinner, String name) {
if (!xmppConnectionServiceBound) {
return;
}
@@ -1122,7 +1118,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
}
@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) {
return;
}
@@ -14,14 +14,7 @@ import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.databinding.DataBindingUtil;
-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;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import eu.siacs.conversations.Config;
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.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 {
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) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.activity_trust_keys);
+ Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
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 {
this.contactJids.add(Jid.of(jid));
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
+ } catch (final IllegalArgumentException ignored) {
}
}
@@ -100,7 +103,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.trust_keys, menu);
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);
}
@@ -191,7 +194,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
);
}
- if (fingerprints.size() == 0) {
+ if (fingerprints.isEmpty()) {
keysCardBinding.noKeysToAccept.setVisibility(View.VISIBLE);
if (hasNoOtherTrustedKeys(jid)) {
if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) {
@@ -254,8 +257,8 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
}
- private void disableEncryptionDialog(View view) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ private void disableEncryptionDialog(final View view) {
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.disable_encryption);
builder.setMessage(R.string.disable_encryption_message);
builder.setPositiveButton(R.string.disable_now, (dialog, which) -> {
@@ -279,7 +282,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
private boolean foreignActuallyHasKeys() {
synchronized (this.foreignKeysToTrust) {
for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) {
- if (entry.getValue().size() > 0) {
+ if (!entry.getValue().isEmpty()) {
return true;
}
}
@@ -305,7 +308,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
foreignKeysToTrust.clear();
for (Jid jid : contactJids) {
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));
}
Map<String, Boolean> foreignFingerprints = new HashMap<>();
@@ -315,7 +318,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
foreignFingerprints.put(fingerprint, false);
}
}
- if (foreignFingerprints.size() > 0 || !acceptedTargets.contains(jid)) {
+ if (!foreignFingerprints.isEmpty() || !acceptedTargets.contains(jid)) {
foreignKeysToTrust.put(jid, foreignFingerprints);
}
}
@@ -42,7 +42,7 @@ import java.util.List;
import java.util.regex.Matcher;
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";
private static final String EXTRA_ALLOW_PROVISIONING = "extra_allow_provisioning";
@@ -2,7 +2,6 @@ package eu.siacs.conversations.ui;
import android.Manifest;
import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
@@ -17,10 +16,10 @@ import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
-import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -50,10 +49,11 @@ import androidx.annotation.BoolRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.app.AppCompatDelegate;
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 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.ExceptionHelper;
import eu.siacs.conversations.utils.SignupUtils;
-import eu.siacs.conversations.utils.ThemeHelper;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
@@ -106,7 +105,6 @@ public abstract class XmppActivity extends ActionBarActivity {
private boolean isCameraFeatureAvailable = false;
- protected int mTheme;
protected boolean mUsingEnterKey = false;
protected boolean mUseTor = false;
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) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
@@ -212,14 +209,10 @@ public abstract class XmppActivity extends ActionBarActivity {
abstract protected void refreshUiReal();
@Override
- protected void onStart() {
+ public void onStart() {
super.onStart();
if (!xmppConnectionServiceBound) {
- if (this.mSkipBackgroundBinding) {
- Log.d(Config.LOGTAG, "skipping background binding");
- } else {
- connectToBackend();
- }
+ connectToBackend();
} else {
this.registerListeners();
this.onBackendConnected();
@@ -255,7 +248,7 @@ public abstract class XmppActivity extends ActionBarActivity {
}
public void showInstallPgpDialog() {
- Builder builder = new AlertDialog.Builder(this);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(getString(R.string.openkeychain_required));
builder.setIconAttribute(android.R.attr.alertDialogIcon);
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) {
- 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 CheckBox deleteFromServer =
dialogView.findViewById(R.id.delete_from_server);
@@ -495,28 +488,12 @@ public abstract class XmppActivity extends ActionBarActivity {
ExceptionHelper.init(getApplicationContext());
EmojiInitializationService.execute(this);
this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
- this.mTheme = findTheme();
- setTheme(this.mTheme);
}
protected boolean 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() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
@@ -698,21 +675,10 @@ public abstract class XmppActivity extends ActionBarActivity {
}
}
- @SuppressWarnings("deprecation")
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- 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>() {
+ protected void choosePgpSignId(final Account account) {
+ xmppConnectionService.getPgpEngine().chooseKey(account, new UiCallback<>() {
@Override
- public void success(Account account1) {
+ public void success(final Account a) {
}
@Override
@@ -733,8 +699,7 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void displayErrorDialog(final int errorCode) {
runOnUiThread(() -> {
- Builder builder = new Builder(XmppActivity.this);
- builder.setIconAttribute(android.R.attr.alertDialogIcon);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(XmppActivity.this);
builder.setTitle(getString(R.string.error));
builder.setMessage(errorCode);
builder.setNeutralButton(R.string.accept, null);
@@ -744,7 +709,7 @@ public abstract class XmppActivity extends ActionBarActivity {
}
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.setMessage(getString(R.string.not_in_roster));
builder.setNegativeButton(getString(R.string.cancel), null);
@@ -753,7 +718,7 @@ public abstract class XmppActivity extends ActionBarActivity {
}
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.setMessage(R.string.request_presence_updates);
builder.setNegativeButton(R.string.cancel, null);
@@ -787,8 +752,8 @@ public abstract class XmppActivity extends ActionBarActivity {
final @StringRes int hint,
boolean password,
boolean permitEmpty) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- DialogQuickeditBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_quickedit, null, false);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ final DialogQuickeditBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_quickedit, null, false);
if (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) {
- 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) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
return false;
@@ -911,10 +876,6 @@ public abstract class XmppActivity extends ActionBarActivity {
SettingsUtils.applyScreenshotPreventionSetting(this);
}
- protected int findTheme() {
- return ThemeHelper.find(this);
- }
-
@Override
public void onPause() {
super.onPause();
@@ -936,14 +897,26 @@ public abstract class XmppActivity extends ActionBarActivity {
if (uri == null || uri.isEmpty()) {
return;
}
- Point size = new Point();
+ final Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
- final int width = (size.x < size.y ? size.x : size.y);
- Bitmap bitmap = BarcodeProvider.create2dBarcodeBitmap(uri, width);
- ImageView view = new ImageView(this);
- view.setBackgroundColor(Color.WHITE);
+ final int width = Math.min(size.x, size.y);
+ 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.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);
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setView(view);
builder.create().show();
}
@@ -8,15 +8,16 @@ import android.widget.ArrayAdapter;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
-import java.util.List;
+import com.google.android.material.color.MaterialColors;
import eu.siacs.conversations.Config;
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.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
-import eu.siacs.conversations.ui.util.StyledAttributes;
+
+import java.util.List;
public class AccountAdapter extends ArrayAdapter<Account> {
@@ -35,36 +36,33 @@ public class AccountAdapter extends ArrayAdapter<Account> {
this.showStateButton = true;
}
+ @NonNull
@Override
public View getView(int position, View view, @NonNull ViewGroup parent) {
final Account account = getItem(position);
final ViewHolder viewHolder;
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();
viewHolder = new ViewHolder(binding);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
- if (Config.DOMAIN_LOCK != null) {
- viewHolder.binding.accountJid.setText(account.getJid().getLocal());
- } else {
- viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toEscapedString());
- }
+ viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toEscapedString());
AvatarWorkerTask.loadAvatar(account, viewHolder.binding.accountImage, R.dimen.avatar);
viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId()));
switch (account.getStatus()) {
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;
case DISABLED:
case LOGGED_OUT:
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;
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;
}
final boolean isDisabled = (account.getStatus() == Account.State.DISABLED);
@@ -84,9 +82,9 @@ public class AccountAdapter extends ArrayAdapter<Account> {
}
private static class ViewHolder {
- private final AccountRowBinding binding;
+ private final ItemAccountBinding binding;
- private ViewHolder(AccountRowBinding binding) {
+ private ViewHolder(ItemAccountBinding binding) {
this.binding = binding;
}
}
@@ -13,18 +13,18 @@ import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
-import java.util.Locale;
-
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.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
import eu.siacs.conversations.xmpp.Jid;
+import java.util.Locale;
+
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
public boolean areItemsTheSame(@NonNull Room a, @NonNull Room b) {
return a.address != null && a.address.equals(b.address);
@@ -45,7 +45,7 @@ public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchR
@NonNull
@Override
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
@@ -99,9 +99,9 @@ public class ChannelSearchResultAdapter extends ListAdapter<Room, ChannelSearchR
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());
this.binding = binding;
}
@@ -6,30 +6,30 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.color.MaterialColors;
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.databinding.ConversationListRowBinding;
+import eu.siacs.conversations.databinding.ItemConversationBinding;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Conversational;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.ConversationFragment;
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.StyledAttributes;
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
-import eu.siacs.conversations.utils.MimeUtils;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.jingle.OngoingRtpSession;
+import java.util.List;
+
public class ConversationAdapter
extends RecyclerView.Adapter<ConversationAdapter.ConversationViewHolder> {
@@ -48,7 +48,7 @@ public class ConversationAdapter
return new ConversationViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()),
- R.layout.conversation_list_row,
+ R.layout.item_conversation,
parent,
false));
}
@@ -68,14 +68,13 @@ public class ConversationAdapter
}
if (conversation == ConversationFragment.getConversation(activity)) {
- viewHolder.binding.frame.setBackgroundColor(
- StyledAttributes.getColor(activity, R.attr.color_background_tertiary));
+ viewHolder.binding.frame.setBackgroundResource(R.drawable.background_selected_item_conversation);
+ //viewHolder.binding.frame.setBackgroundColor(MaterialColors.getColor(viewHolder.binding.frame, com.google.android.material.R.attr.colorSurfaceDim));
} else {
- viewHolder.binding.frame.setBackgroundColor(
- StyledAttributes.getColor(activity, R.attr.color_background_primary));
+ viewHolder.binding.frame.setBackgroundColor(MaterialColors.getColor(viewHolder.binding.frame, com.google.android.material.R.attr.colorSurface));
}
- Message message = conversation.getLatestMessage();
+ final Message message = conversation.getLatestMessage();
final int unreadCount = conversation.unreadCount();
final boolean isRead = conversation.isRead();
final Conversation.Draft draft = isRead ? conversation.getDraft() : null;
@@ -106,68 +105,9 @@ public class ConversationAdapter
&& (message.isFileOrImage()
|| message.treatAsDownloadable()
|| message.isGeoUri())) {
- final int imageResource;
- if (message.isGeoUri()) {
- imageResource =
- 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;
- }
- }
- }
+ final var attachment = Attachment.of(message);
+ final @DrawableRes int imageResource = MediaAdapter.getImageDrawable(attachment);
+ showPreviewText = false;
viewHolder.binding.conversationLastmsgImg.setImageResource(imageResource);
viewHolder.binding.conversationLastmsgImg.setVisibility(View.VISIBLE);
} else {
@@ -231,36 +171,21 @@ public class ConversationAdapter
if (ongoingCall.isPresent()) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- final int ic_ongoing_call =
- activity.getThemeResource(
- R.attr.ic_ongoing_call_hint, R.drawable.ic_phone_in_talk_black_18dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_ongoing_call);
+ viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_phone_in_talk_24dp);
} else {
final long muted_till =
conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0);
if (muted_till == Long.MAX_VALUE) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_off =
- activity.getThemeResource(
- R.attr.icon_notifications_off,
- R.drawable.ic_notifications_off_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_off);
+ viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_off_24dp);
} else if (muted_till >= System.currentTimeMillis()) {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_paused =
- activity.getThemeResource(
- R.attr.icon_notifications_paused,
- R.drawable.ic_notifications_paused_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_paused);
+ viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_paused_24dp);
} else if (conversation.alwaysNotify()) {
viewHolder.binding.notificationStatus.setVisibility(View.GONE);
} else {
viewHolder.binding.notificationStatus.setVisibility(View.VISIBLE);
- int ic_notifications_none =
- activity.getThemeResource(
- R.attr.icon_notifications_none,
- R.drawable.ic_notifications_none_black_24dp);
- viewHolder.binding.notificationStatus.setImageResource(ic_notifications_none);
+ viewHolder.binding.notificationStatus.setImageResource(R.drawable.ic_notifications_none_24dp);
}
}
@@ -307,9 +232,9 @@ public class ConversationAdapter
}
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());
this.binding = binding;
}
@@ -6,32 +6,35 @@ import android.widget.Filter;
import androidx.annotation.NonNull;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Ordering;
+
+import eu.siacs.conversations.Config;
+
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
+import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
-import eu.siacs.conversations.Config;
-
public class KnownHostsAdapter extends ArrayAdapter<String> {
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() {
@Override
- protected FilterResults performFiltering(CharSequence constraint) {
- final ArrayList<String> suggestions = new ArrayList<>();
+ protected FilterResults performFiltering(final CharSequence constraint) {
+ final ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
final String[] split = constraint == null ? new String[0] : constraint.toString().split("@");
if (split.length == 1) {
final String local = split[0].toLowerCase(Locale.ENGLISH);
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 {
for (String domain : domains) {
- suggestions.add(local + '@' + domain);
+ builder.add(local + '@' + domain);
}
}
} else if (split.length == 2) {
@@ -40,45 +43,49 @@ public class KnownHostsAdapter extends ArrayAdapter<String> {
if (domains.contains(domainPart)) {
return new FilterResults();
}
- for (String domain : domains) {
+ for (final String domain : domains) {
if (domain.contains(domainPart)) {
- suggestions.add(localPart + "@" + domain);
+ builder.add(localPart + "@" + domain);
}
}
} else {
return new FilterResults();
}
- FilterResults filterResults = new FilterResults();
+ final var suggestions = builder.build();
+ final FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
}
@Override
- protected void publishResults(CharSequence constraint, FilterResults results) {
- ArrayList filteredList = (ArrayList) results.values;
- if (results.count > 0) {
- clear();
- addAll(filteredList);
- notifyDataSetChanged();
+ protected void publishResults(final CharSequence constraint, final FilterResults results) {
+ final ImmutableList.Builder<String> suggestions = new ImmutableList.Builder<>();
+ if (results.values instanceof Collection<?> collection) {
+ for(final Object item : collection) {
+ if (item instanceof String string) {
+ 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<>());
- domains = new ArrayList<>(mKnownHosts);
- Collections.sort(domains);
+ domains = Ordering.natural().sortedCopy(knownHosts);
}
- public KnownHostsAdapter(Context context, int viewResourceId) {
+ public KnownHostsAdapter(final Context context, final int viewResourceId) {
super(context, viewResourceId, new ArrayList<>());
- domains = new ArrayList<>();
+ domains = ImmutableList.of();
}
- public void refresh(Collection<String> knownHosts) {
- domains = new ArrayList<>(knownHosts);
- Collections.sort(domains);
+ public void refresh(final Collection<String> knownHosts) {
+ this.domains = Ordering.natural().sortedCopy(knownHosts);
notifyDataSetChanged();
}
@@ -2,6 +2,7 @@ package eu.siacs.conversations.ui.adapter;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,30 +10,30 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import com.wefika.flowlayout.FlowLayout;
-import java.util.List;
-
+import eu.siacs.conversations.Config;
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.ui.SettingsActivity;
import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
-import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.utils.IrregularUnicodeDetector;
import eu.siacs.conversations.xmpp.Jid;
+import java.util.List;
+
public class ListItemAdapter extends ArrayAdapter<ListItem> {
protected XmppActivity activity;
private boolean showDynamicTags = false;
private OnTagClickedListener mOnTagClickedListener = null;
private final View.OnClickListener onTagTvClick = view -> {
- if (view instanceof TextView && mOnTagClickedListener != null) {
- TextView tv = (TextView) view;
+ if (view instanceof TextView tv && mOnTagClickedListener != null) {
final String tag = tv.getText().toString();
mOnTagClickedListener.onTagClicked(tag);
}
@@ -49,22 +50,25 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
this.showDynamicTags = preferences.getBoolean(SettingsActivity.SHOW_DYNAMIC_TAGS, false);
}
+ @NonNull
@Override
- public View getView(int position, View view, ViewGroup parent) {
+ public View getView(int position, View view, @NonNull ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
ListItem item = getItem(position);
ViewHolder viewHolder;
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);
view = binding.getRoot();
} else {
viewHolder = (ViewHolder) view.getTag();
}
- view.setBackground(StyledAttributes.getDrawable(view.getContext(),R.attr.list_item_background));
-
- List<ListItem.Tag> tags = item.getTags(activity);
- if (tags.size() == 0 || !this.showDynamicTags) {
+ if (view.isActivated()) {
+ Log.d(Config.LOGTAG,"item "+item.getDisplayName()+" is activated");
+ }
+ //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);
} else {
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.name = binding.contactDisplayName;
viewHolder.jid = binding.contactJid;
@@ -1,47 +1,50 @@
package eu.siacs.conversations.ui.adapter;
-import android.content.Context;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
-import androidx.annotation.AttrRes;
import androidx.annotation.DimenRes;
+import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
+import androidx.core.widget.ImageViewCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
+import com.google.android.material.color.MaterialColors;
+import com.google.common.base.Strings;
-import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
-import eu.siacs.conversations.databinding.MediaBinding;
+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.StyledAttributes;
import eu.siacs.conversations.ui.util.ViewUtil;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.RejectedExecutionException;
+
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
- public static final List<String> DOCUMENT_MIMES = Arrays.asList(
- "application/pdf",
- "application/vnd.oasis.opendocument.text",
- "application/msword",
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- "text/x-tex",
- "text/plain"
- );
+ public static final List<String> DOCUMENT_MIMES =
+ Arrays.asList(
+ "application/pdf",
+ "application/vnd.oasis.opendocument.text",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "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<>();
@@ -55,58 +58,77 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
}
@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();
- if (adapter instanceof MediaAdapter) {
- ((MediaAdapter) adapter).setMediaSize(mediaSize);
+ if (adapter instanceof MediaAdapter mediaAdapter) {
+ mediaAdapter.setMediaSize(mediaSize);
}
}
- private static @AttrRes
- int getImageAttr(Attachment attachment) {
- final @AttrRes int attr;
+ public static @DrawableRes int getImageDrawable(final Attachment attachment) {
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) {
- attr = R.attr.media_preview_recording;
+ return R.drawable.ic_mic_48dp;
} else {
- final String mime = 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 getImageDrawable(attachment.getMime());
+ }
+ }
+
+ private static @DrawableRes int getImageDrawable(final String mime) {
+
+ // TODO ideas for more mime types: XML, HTML documents, GPG/PGP files, eml files,
+ // 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;
}
- return attr;
}
- static void renderPreview(Context context, Attachment attachment, ImageView imageView) {
- imageView.setBackgroundColor(StyledAttributes.getColor(context, R.attr.color_background_tertiary));
- imageView.setImageAlpha(Math.round(StyledAttributes.getFloat(context, R.attr.icon_alpha) * 255));
- imageView.setImageDrawable(StyledAttributes.getDrawable(context, getImageAttr(attachment)));
+ 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) {
@@ -126,8 +148,7 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
- if (drawable instanceof AsyncDrawable) {
- final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ if (drawable instanceof AsyncDrawable asyncDrawable) {
return asyncDrawable.getBitmapWorkerTask();
}
}
@@ -137,8 +158,9 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
@NonNull
@Override
public MediaViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
- MediaBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.media, parent, false);
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ ItemMediaBinding binding =
+ DataBindingUtil.inflate(layoutInflater, R.layout.item_media, parent, false);
return new MediaViewHolder(binding);
}
@@ -146,16 +168,15 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
public void onBindViewHolder(@NonNull MediaViewHolder holder, int position) {
final Attachment attachment = attachments.get(position);
if (attachment.renderThumbnail()) {
- holder.binding.media.setImageAlpha(255);
loadPreview(attachment, holder.binding.media);
} else {
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));
}
- public void setAttachments(List<Attachment> attachments) {
+ public void setAttachments(final List<Attachment> attachments) {
this.attachments.clear();
this.attachments.addAll(attachments);
notifyDataSetChanged();
@@ -167,16 +188,21 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
private void loadPreview(Attachment attachment, ImageView 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) {
cancelPotentialWork(attachment, imageView);
imageView.setImageBitmap(bm);
- imageView.setBackgroundColor(0x00000000);
+ imageView.setBackgroundColor(Color.TRANSPARENT);
} else {
+ // TODO consider if this is still a good, general purpose loading color
imageView.setBackgroundColor(0xff333333);
imageView.setImageDrawable(null);
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);
try {
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());
this.binding = binding;
}
@@ -225,13 +251,15 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
}
@Override
- protected Bitmap doInBackground(Attachment... params) {
+ protected Bitmap doInBackground(final Attachment... params) {
this.attachment = params[0];
final XmppActivity activity = XmppActivity.find(imageViewReference);
if (activity == null) {
return null;
}
- return activity.xmppConnectionService.getFileBackend().getPreviewForUri(this.attachment, mediaSize, false);
+ return activity.xmppConnectionService
+ .getFileBackend()
+ .getPreviewForUri(this.attachment, mediaSize, false);
}
@Override
@@ -15,22 +15,25 @@ import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.core.widget.ImageViewCompat;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
-
import eu.siacs.conversations.R;
-import eu.siacs.conversations.databinding.MediaPreviewBinding;
+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;
-public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewViewHolder> {
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.RejectedExecutionException;
+
+public class MediaPreviewAdapter
+ extends RecyclerView.Adapter<MediaPreviewAdapter.MediaPreviewViewHolder> {
private final ArrayList<Attachment> mediaPreviews = new ArrayList<>();
@@ -43,8 +46,9 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
@NonNull
@Override
public MediaPreviewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
- MediaPreviewBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.media_preview, parent, false);
+ final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
+ ItemMediaPreviewBinding binding =
+ DataBindingUtil.inflate(layoutInflater, R.layout.item_media_preview, parent, false);
return new MediaPreviewViewHolder(binding);
}
@@ -53,18 +57,19 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
final Context context = conversationFragment.getActivity();
final Attachment attachment = mediaPreviews.get(position);
if (attachment.renderThumbnail()) {
- holder.binding.mediaPreview.setImageAlpha(255);
+ ImageViewCompat.setImageTintList(holder.binding.mediaPreview, null);
loadPreview(attachment, holder.binding.mediaPreview);
} else {
cancelPotentialWork(attachment, holder.binding.mediaPreview);
- MediaAdapter.renderPreview(context, attachment, holder.binding.mediaPreview);
+ MediaAdapter.renderPreview(attachment, holder.binding.mediaPreview);
}
- holder.binding.deleteButton.setOnClickListener(v -> {
- final int pos = mediaPreviews.indexOf(attachment);
- mediaPreviews.remove(pos);
- notifyItemRemoved(pos);
- conversationFragment.toggleInputMethod();
- });
+ holder.binding.deleteButton.setOnClickListener(
+ v -> {
+ final int pos = mediaPreviews.indexOf(attachment);
+ mediaPreviews.remove(pos);
+ notifyItemRemoved(pos);
+ conversationFragment.toggleInputMethod();
+ });
holder.binding.mediaPreview.setOnClickListener(v -> view(context, attachment));
}
@@ -76,9 +81,14 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
try {
context.startActivity(view);
} 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) {
- 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) {
if (cancelPotentialWork(attachment, imageView)) {
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) {
cancelPotentialWork(attachment, imageView);
imageView.setImageBitmap(bm);
imageView.setBackgroundColor(0x00000000);
} else {
- imageView.setBackgroundColor(0xff333333);
+ imageView.setBackgroundColor(
+ ContextCompat.getColor(imageView.getContext(), R.color.gray_800));
imageView.setImageDrawable(null);
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);
try {
task.execute(attachment);
@@ -126,8 +147,7 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
- if (drawable instanceof AsyncDrawable) {
- final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ if (drawable instanceof AsyncDrawable asyncDrawable) {
return asyncDrawable.getBitmapWorkerTask();
}
}
@@ -140,7 +160,7 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
}
public boolean hasAttachments() {
- return mediaPreviews.size() > 0;
+ return !mediaPreviews.isEmpty();
}
public ArrayList<Attachment> getAttachments() {
@@ -153,9 +173,9 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
static class MediaPreviewViewHolder extends RecyclerView.ViewHolder {
- private final MediaPreviewBinding binding;
+ private final ItemMediaPreviewBinding binding;
- MediaPreviewViewHolder(MediaPreviewBinding binding) {
+ MediaPreviewViewHolder(ItemMediaPreviewBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
@@ -189,7 +209,14 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
if (activity == 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
@@ -5,6 +5,7 @@ import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.Build;
import android.preference.PreferenceManager;
@@ -20,16 +21,22 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
-import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
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.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 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.text.DividerSpan;
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.MyLinkify;
import eu.siacs.conversations.ui.util.QuoteHelper;
@@ -160,15 +168,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
return this.getItemViewType(getItem(position));
}
- private int getMessageTextColor(boolean onDark, boolean primary) {
- 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) {
+ private void displayStatus(ViewHolder viewHolder, Message message, int type, final BubbleColor bubbleColor) {
String filesize = null;
String info = null;
boolean error = false;
@@ -179,8 +179,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (viewHolder.edit_indicator != null) {
if (message.edited()) {
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);
- viewHolder.edit_indicator.setAlpha(darkBackground ? 0.7f : 0.57f);
+ setImageTint(viewHolder.edit_indicator, bubbleColor);
} else {
viewHolder.edit_indicator.setVisibility(View.GONE);
}
@@ -211,8 +210,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break;
case Message.STATUS_SEND_RECEIVED:
case Message.STATUS_SEND_DISPLAYED:
- viewHolder.indicatorReceived.setImageResource(darkBackground ? R.drawable.ic_done_white_18dp : R.drawable.ic_done_black_18dp);
- viewHolder.indicatorReceived.setAlpha(darkBackground ? 0.7f : 0.57f);
+ setImageTint(viewHolder.indicatorReceived, bubbleColor);
viewHolder.indicatorReceived.setVisibility(View.VISIBLE);
break;
case Message.STATUS_SEND_FAILED:
@@ -245,18 +243,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break;
}
if (error && type == SENT) {
- if (darkBackground) {
- viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption_Warning_OnDark);
- } else {
- viewHolder.time.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Caption_Warning);
- }
+ viewHolder.time.setTextColor(MaterialColors.getColor(viewHolder.time, com.google.android.material.R.attr.colorError));
} else {
- if (darkBackground) {
- 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));
+ setTextColor(viewHolder.time,bubbleColor);
}
if (message.getEncryption() == Message.ENCRYPTION_NONE) {
viewHolder.indicator.setVisibility(View.GONE);
@@ -271,15 +260,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
}
if (verified) {
- viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_verified_user_white_18dp : R.drawable.ic_verified_user_black_18dp);
- } else {
- viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_lock_white_18dp : R.drawable.ic_lock_black_18dp);
- }
- if (darkBackground) {
- viewHolder.indicator.setAlpha(0.7f);
+ viewHolder.indicator.setImageResource(R.drawable.ic_verified_user_24dp);
} else {
- viewHolder.indicator.setAlpha(0.57f);
+ viewHolder.indicator.setImageResource(R.drawable.ic_lock_24dp);
}
+ setImageTint(viewHolder.indicator, bubbleColor);
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.audioPlayer.setVisibility(View.GONE);
viewHolder.image.setVisibility(View.GONE);
viewHolder.messageBody.setVisibility(View.VISIBLE);
viewHolder.messageBody.setText(text);
- if (darkBackground) {
- viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Secondary_OnDark);
- } else {
- viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Secondary);
- }
+ viewHolder.messageBody.setTextColor(bubbleToOnSurfaceVariant(viewHolder.messageBody,bubbleColor));
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.audioPlayer.setVisibility(View.GONE);
viewHolder.image.setVisibility(View.GONE);
viewHolder.messageBody.setVisibility(View.VISIBLE);
- if (darkBackground) {
- viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Emoji_OnDark);
- } else {
- viewHolder.messageBody.setTextAppearance(getContext(), R.style.TextAppearance_Conversations_Body1_Emoji);
- }
- Spannable span = new SpannableString(body);
+ setTextColor(viewHolder.messageBody, bubbleColor);
+ final Spannable span = new SpannableString(body);
float size = Emoticons.isEmoji(body) ? 3.0f : 2.0f;
span.setSpan(new RelativeSizeSpan(size), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
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())) {
body.insert(start++, "\n");
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.setSpan(new DividerSpan(false), end, end + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
- int color = darkBackground ? this.getMessageTextColor(darkBackground, false)
- : ContextCompat.getColor(activity, R.color.green700_desaturated);
- DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
- body.setSpan(new QuoteSpan(color, metrics), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
+ body.setSpan(new QuoteSpan(bubbleToOnSurfaceVariant(textView, bubbleColor), metrics), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
/**
* 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.
*/
- private boolean handleTextQuotes(SpannableStringBuilder body, boolean darkBackground) {
+ private boolean handleTextQuotes(final TextView textView, final SpannableStringBuilder body, final BubbleColor bubbleColor) {
boolean startsWithQuote = false;
int quoteDepth = 1;
while (QuoteHelper.bodyContainsQuoteStart(body) && quoteDepth <= Config.QUOTE_MAX_DEPTH) {
@@ -382,7 +357,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (i == 0) startsWithQuote = true;
} else if (quoteStart >= 0) {
// Line start without quote, apply spans there
- applyQuoteSpan(body, quoteStart, i - 1, darkBackground);
+ applyQuoteSpan(textView, body, quoteStart, i - 1, bubbleColor);
quoteStart = -1;
}
}
@@ -407,26 +382,19 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
if (quoteStart >= 0) {
// Apply spans to finishing open quote
- applyQuoteSpan(body, quoteStart, body.length(), darkBackground);
+ applyQuoteSpan(textView, body, quoteStart, body.length(), bubbleColor);
}
quoteDepth++;
}
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.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.messageBody.setVisibility(View.VISIBLE);
-
- 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));
+ setTextColor(viewHolder.messageBody, bubbleColor);
viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
if (message.getBody() != null) {
@@ -446,7 +414,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
int end = body.getSpanEnd(mergeSeparator);
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 (hasMeCommand) {
body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
@@ -469,7 +437,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else {
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);
if (hasMeCommand) {
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() instanceof Conversation) {
- final Conversation conversation = (Conversation) message.getConversation();
+ if (message.getConversation() instanceof Conversation conversation) {
Pattern pattern = NotificationService.generateNickHighlightPattern(conversation.getMucOptions().getActualNick());
Matcher matcher = pattern.matcher(body);
while (matcher.find()) {
@@ -495,7 +462,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
if (highlightedTerm != null) {
- StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
+ StylingHelper.highlight(viewHolder.messageBody, body, highlightedTerm);
}
MyLinkify.addLinks(body, true);
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) {
- toggleWhisperInfo(viewHolder, message, darkBackground);
+ private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text, final BubbleColor bubbleColor) {
+ toggleWhisperInfo(viewHolder, message, bubbleColor);
viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE);
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));
}
- private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
- toggleWhisperInfo(viewHolder, message, darkBackground);
+ private void displayOpenableMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
+ toggleWhisperInfo(viewHolder, message, bubbleColor);
viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE);
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));
}
- private void displayLocationMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
- toggleWhisperInfo(viewHolder, message, darkBackground);
+ private void displayLocationMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
+ toggleWhisperInfo(viewHolder, message, bubbleColor);
viewHolder.image.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE);
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));
}
- private void displayAudioMessage(ViewHolder viewHolder, Message message, boolean darkBackground) {
- toggleWhisperInfo(viewHolder, message, darkBackground);
+ private void displayAudioMessage(ViewHolder viewHolder, Message message, final BubbleColor bubbleColor) {
+ toggleWhisperInfo(viewHolder, message, bubbleColor);
viewHolder.image.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.GONE);
final RelativeLayout audioPlayer = viewHolder.audioPlayer;
audioPlayer.setVisibility(View.VISIBLE);
- AudioPlayer.ViewHolder.get(audioPlayer).setDarkBackground(darkBackground);
+ AudioPlayer.ViewHolder.get(audioPlayer).setBubbleColor(bubbleColor);
this.audioPlayer.init(audioPlayer, message);
}
- private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final boolean darkBackground) {
- toggleWhisperInfo(viewHolder, message, darkBackground);
+ private void displayMediaPreviewMessage(ViewHolder viewHolder, final Message message, final BubbleColor bubbleColor) {
+ toggleWhisperInfo(viewHolder, message, bubbleColor);
viewHolder.download_button.setVisibility(View.GONE);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.image.setVisibility(View.VISIBLE);
@@ -573,7 +549,7 @@ public class MessageAdapter extends ArrayAdapter<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()) {
final String privateMarker;
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()));
}
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);
viewHolder.messageBody.setText(body);
viewHolder.messageBody.setVisibility(View.VISIBLE);
@@ -611,7 +587,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
@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 boolean omemoEncryption = message.getEncryption() == Message.ENCRYPTION_AXOLOTL;
final boolean isInValidSession = message.isValidInSession() && (!omemoEncryption || message.isTrusted());
@@ -623,19 +599,18 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder = new ViewHolder();
switch (type) {
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.message_box = view.findViewById(R.id.message_box);
- viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
break;
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.message_box = view.findViewById(R.id.message_box);
viewHolder.indicatorReceived = view.findViewById(R.id.indicator_received);
break;
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.contact_picture = view.findViewById(R.id.message_photo);
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);
break;
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.contact_picture = view.findViewById(R.id.message_photo);
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);
break;
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.status_message = view.findViewById(R.id.status_message);
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 (UIHelper.today(message.getTimeSent())) {
@@ -688,10 +673,15 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else {
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;
} else if (type == RTP_SESSION) {
- final boolean isDarkTheme = activity.isDarkTheme();
final boolean received = message.getStatus() <= Message.STATUS_RECEIVED;
final RtpSessionStatus rtpSessionStatus = RtpSessionStatus.of(message.getBody());
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.indicatorReceived.setImageResource(RtpSessionStatus.getDrawable(received, rtpSessionStatus.successful, isDarkTheme));
- viewHolder.indicatorReceived.setAlpha(isDarkTheme ? 0.7f : 0.57f);
- viewHolder.message_box.setBackgroundResource(isDarkTheme ? R.drawable.date_bubble_grey : R.drawable.date_bubble_white);
+ if (colorfulBackground) {
+ setBackgroundTint(viewHolder.message_box,BubbleColor.TERTIARY);
+ 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;
} else if (type == STATUS) {
if ("LOAD_MORE".equals(message.getBody())) {
@@ -769,43 +766,43 @@ public class MessageAdapter extends ArrayAdapter<Message> {
final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message);
if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) {
if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) {
- displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground);
+ 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) {
- 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 {
- 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) {
if (message.getFileParams().width > 0 && message.getFileParams().height > 0) {
- displayMediaPreviewMessage(viewHolder, message, darkBackground);
+ displayMediaPreviewMessage(viewHolder, message, bubbleColor);
} else if (message.getFileParams().runtime > 0) {
- displayAudioMessage(viewHolder, message, darkBackground);
+ displayAudioMessage(viewHolder, message, bubbleColor);
} else {
- displayOpenableMessage(viewHolder, message, darkBackground);
+ displayOpenableMessage(viewHolder, message, bubbleColor);
}
} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
if (account.isPgpDecryptionServiceConnected()) {
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 {
- displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground);
+ displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), bubbleColor);
}
} 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.messageBody.setOnClickListener(this::promptOpenKeychainInstall);
}
} 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) {
- 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) {
- displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), darkBackground);
+ displayInfoMessage(viewHolder, activity.getString(R.string.omemo_decryption_failed), bubbleColor);
} else {
if (message.isGeoUri()) {
- displayLocationMessage(viewHolder, message, darkBackground);
+ displayLocationMessage(viewHolder, message, bubbleColor);
} 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()) {
try {
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,
UIHelper.getFileDescriptionString(activity, message),
uri.getHost()),
- darkBackground);
+ bubbleColor);
} catch (Exception e) {
displayDownloadableMessage(viewHolder,
message,
activity.getString(R.string.check_x_filesize,
UIHelper.getFileDescriptionString(activity, message)),
- darkBackground);
+ bubbleColor);
}
} else {
- displayTextMessage(viewHolder, message, darkBackground, type);
+ displayTextMessage(viewHolder, message, bubbleColor, type);
}
}
+ setBackgroundTint(viewHolder.message_box, bubbleColor);
+ setTextColor(viewHolder.messageBody, bubbleColor);
+
if (type == RECEIVED) {
+ setTextColor(viewHolder.encryption, bubbleColor);
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);
} else {
- viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning);
viewHolder.encryption.setVisibility(View.VISIBLE);
if (omemoEncryption && !message.isTrusted()) {
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;
}
@@ -911,13 +904,68 @@ public class MessageAdapter extends ArrayAdapter<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 {
- public Button load_more_messages;
+ public MaterialButton load_more_messages;
public ImageView edit_indicator;
public RelativeLayout audioPlayer;
protected LinearLayout message_box;
- protected Button download_button;
+ protected MaterialButton download_button;
protected ImageView image;
protected ImageView indicator;
protected ImageView indicatorReceived;
@@ -17,7 +17,7 @@ import org.openintents.openpgp.util.OpenPgpUtils;
import eu.siacs.conversations.R;
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.MucOptions;
import eu.siacs.conversations.services.XmppConnectionService;
@@ -62,7 +62,7 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
@NonNull
@Override
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
@@ -129,11 +129,11 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
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());
this.binding = binding;
}
@@ -11,13 +11,14 @@ import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;
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.ui.XmppActivity;
import eu.siacs.conversations.ui.util.AvatarWorkerTask;
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;
@@ -28,29 +29,43 @@ public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreview
@NonNull
@Override
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
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
final MucOptions.User user = getItem(position);
AvatarWorkerTask.loadAvatar(user, viewHolder.binding.avatar, R.dimen.media_size);
- viewHolder.binding.getRoot().setOnClickListener(v -> {
- final XmppActivity activity = XmppActivity.find(v);
- if (activity != null) {
- activity.highlightInMuc(user.getConversation(), user.getName());
- }
- });
+ viewHolder
+ .binding
+ .getRoot()
+ .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().setTag(user);
- viewHolder.binding.getRoot().setOnLongClickListener(v -> {
- selectedUser = user;
- return false;
- });
+ viewHolder
+ .binding
+ .getRoot()
+ .setOnLongClickListener(
+ v -> {
+ selectedUser = user;
+ return false;
+ });
}
@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);
}
@@ -60,9 +75,9 @@ public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreview
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());
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.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.R;
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.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 Object LOCK = new Object();
@@ -57,33 +62,43 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
final Context context = adapter.getContext();
this.messageAdapter = adapter;
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);
synchronized (AudioPlayer.LOCK) {
if (AudioPlayer.player != null) {
AudioPlayer.player.setOnCompletionListener(this);
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) {
- 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) {
- if (Build.VERSION.SDK_INT >= 21) {
- synchronized (AudioPlayer.LOCK) {
- if (AudioPlayer.wakeLock == null) {
- final PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- AudioPlayer.wakeLock = powerManager == null ? null : powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, AudioPlayer.class.getSimpleName());
- AudioPlayer.wakeLock.setReferenceCounted(false);
- }
+ synchronized (AudioPlayer.LOCK) {
+ if (AudioPlayer.wakeLock == null) {
+ final PowerManager powerManager =
+ (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ AudioPlayer.wakeLock =
+ 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);
if (init(ViewHolder.get(audioPlayer), message)) {
this.audioPlayerLayouts.addWeakReferenceTo(audioPlayer);
- executor.execute(()-> this.stopRefresher(true));
+ executor.execute(() -> this.stopRefresher(true));
} else {
this.audioPlayerLayouts.removeWeakReferenceTo(audioPlayer);
}
}
}
- private boolean init(ViewHolder viewHolder, Message message) {
- if (viewHolder.darkBackground) {
- viewHolder.runtime.setTextAppearance(this.messageAdapter.getContext(), R.style.TextAppearance_Conversations_Caption_OnDark);
- } else {
- viewHolder.runtime.setTextAppearance(this.messageAdapter.getContext(), R.style.TextAppearance_Conversations_Caption);
- }
+ private boolean init(final ViewHolder viewHolder, final Message message) {
+ MessageAdapter.setTextColor(viewHolder.runtime, viewHolder.bubbleColor);
viewHolder.progress.setOnSeekBarChangeListener(this);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- ColorStateList color = ContextCompat.getColorStateList(messageAdapter.getContext(), viewHolder.darkBackground ? R.color.white70 : R.color.green700_desaturated);
- viewHolder.progress.setThumbTintList(color);
- viewHolder.progress.setProgressTintList(color);
- }
- viewHolder.playPause.setAlpha(viewHolder.darkBackground ? 0.7f : 0.57f);
+ final ColorStateList color =
+ MessageAdapter.bubbleToOnSurfaceColorStateList(
+ viewHolder.progress, viewHolder.bubbleColor);
+ viewHolder.progress.setThumbTintList(color);
+ viewHolder.progress.setProgressTintList(color);
viewHolder.playPause.setOnClickListener(this);
final Context context = viewHolder.playPause.getContext();
if (message == currentlyPlayingMessage) {
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.progress.setEnabled(true);
} else {
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);
}
return true;
} 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.runtime.setText(formatTime(message.getFileParams().runtime));
viewHolder.progress.setProgress(0);
@@ -145,9 +158,16 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
}
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));
- 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;
}
initializeProximityWakeLock(playPause.getContext());
@@ -163,13 +183,13 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
private boolean playPauseCurrent(final ViewHolder viewHolder) {
final Context context = viewHolder.playPause.getContext();
- viewHolder.playPause.setAlpha(viewHolder.darkBackground ? 0.7f : 0.57f);
if (player.isPlaying()) {
viewHolder.progress.setEnabled(false);
player.pause();
messageAdapter.flagScreenOff();
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));
} else {
viewHolder.progress.setEnabled(true);
@@ -177,7 +197,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
messageAdapter.flagScreenOn();
acquireProximityWakeLock();
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));
}
return false;
@@ -193,19 +214,24 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
AudioPlayer.player = new MediaPlayer();
try {
AudioPlayer.currentlyPlayingMessage = message;
- AudioPlayer.player.setAudioStreamType(earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
- AudioPlayer.player.setDataSource(messageAdapter.getFileBackend().getFile(message).getAbsolutePath());
+ AudioPlayer.player.setAudioStreamType(
+ earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
+ AudioPlayer.player.setDataSource(
+ messageAdapter.getFileBackend().getFile(message).getAbsolutePath());
AudioPlayer.player.setOnCompletionListener(this);
AudioPlayer.player.prepare();
AudioPlayer.player.start();
messageAdapter.flagScreenOn();
acquireProximityWakeLock();
viewHolder.progress.setEnabled(true);
- viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_pause_white_36dp : R.drawable.ic_pause_black_36dp);
- viewHolder.playPause.setContentDescription(viewHolder.playPause.getContext().getString(R.string.pause_audio));
- sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
+ viewHolder.playPause.setImageResource(R.drawable.ic_pause_24dp);
+ MessageAdapter.setImageTint(viewHolder.playPause,viewHolder.bubbleColor);
+ viewHolder.playPause.setContentDescription(
+ viewHolder.playPause.getContext().getString(R.string.pause_audio));
+ sensorManager.registerListener(
+ this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
return true;
- } catch (Exception e) {
+ } catch (final Exception e) {
messageAdapter.flagScreenOff();
releaseProximityWakeLock();
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) {
return;
}
final ViewHolder viewHolder = ViewHolder.get(audioPlayer);
final Message message = (Message) audioPlayer.getTag();
- viewHolder.playPause.setContentDescription(viewHolder.playPause.getContext().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.setContentDescription(
+ 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) {
viewHolder.runtime.setText(formatTime(message.getFileParams().runtime));
}
@@ -297,14 +325,10 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
}
@Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
+ public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
+ public void onStopTrackingTouch(SeekBar seekBar) {}
public void stop() {
synchronized (AudioPlayer.LOCK) {
@@ -361,7 +385,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
} else {
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;
}
@@ -391,7 +416,11 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
try {
ViewHolder currentViewHolder = getCurrentViewHolder();
if (currentViewHolder != null) {
- play(currentViewHolder, currentlyPlayingMessage, streamType == AudioManager.STREAM_VOICE_CALL, progress);
+ play(
+ currentViewHolder,
+ currentlyPlayingMessage,
+ streamType == AudioManager.STREAM_VOICE_CALL,
+ progress);
}
} catch (Exception e) {
Log.w(Config.LOGTAG, e);
@@ -401,8 +430,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
}
@Override
- public void onAccuracyChanged(Sensor sensor, int i) {
- }
+ public void onAccuracyChanged(Sensor sensor, int i) {}
private void acquireProximityWakeLock() {
synchronized (AudioPlayer.LOCK) {
@@ -435,22 +463,24 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
private TextView runtime;
private SeekBar progress;
private ImageButton playPause;
- private boolean darkBackground = false;
-
- public static ViewHolder get(RelativeLayout audioPlayer) {
- ViewHolder viewHolder = (ViewHolder) audioPlayer.getTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER);
- if (viewHolder == null) {
- 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);
+ private MessageAdapter.BubbleColor bubbleColor = MessageAdapter.BubbleColor.SURFACE;
+
+ public static ViewHolder get(final RelativeLayout audioPlayer) {
+ final var existingViewHolder =
+ (ViewHolder) audioPlayer.getTag(R.id.TAG_AUDIO_PLAYER_VIEW_HOLDER);
+ if (existingViewHolder != null) {
+ return existingViewHolder;
}
+ 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;
}
- public void setDarkBackground(boolean darkBackground) {
- this.darkBackground = darkBackground;
+ public void setBubbleColor(final MessageAdapter.BubbleColor bubbleColor) {
+ 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 eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.utils.MimeUtils;
+
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -46,9 +49,6 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
-import eu.siacs.conversations.utils.Compatibility;
-import eu.siacs.conversations.utils.MimeUtils;
-
public class Attachment implements Parcelable {
Attachment(Parcel in) {
@@ -71,17 +71,18 @@ public class Attachment implements Parcelable {
return 0;
}
- public static final Creator<Attachment> CREATOR = new Creator<Attachment>() {
- @Override
- public Attachment createFromParcel(Parcel in) {
- return new Attachment(in);
- }
+ public static final Creator<Attachment> CREATOR =
+ new Creator<Attachment>() {
+ @Override
+ public Attachment createFromParcel(Parcel in) {
+ return new Attachment(in);
+ }
- @Override
- public Attachment[] newArray(int size) {
- return new Attachment[size];
- }
- };
+ @Override
+ public Attachment[] newArray(int size) {
+ return new Attachment[size];
+ }
+ };
public String getMime() {
return mime;
@@ -103,7 +104,10 @@ public class Attachment implements Parcelable {
}
public enum Type {
- FILE, IMAGE, LOCATION, RECORDING
+ FILE,
+ IMAGE,
+ LOCATION,
+ RECORDING
}
private final Uri uri;
@@ -125,8 +129,8 @@ public class Attachment implements Parcelable {
this.uuid = UUID.randomUUID();
}
- public static boolean canBeSendInband(final List<Attachment> attachments) {
- for (Attachment attachment : attachments) {
+ public static boolean canBeSendInBand(final List<Attachment> attachments) {
+ for (final Attachment attachment : attachments) {
if (attachment.type != Type.LOCATION) {
return false;
}
@@ -135,10 +139,30 @@ public class Attachment implements Parcelable {
}
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));
}
+ 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) {
final List<Attachment> attachments = new ArrayList<>();
for (final Uri uri : uris) {
@@ -146,16 +170,25 @@ public class Attachment implements Parcelable {
continue;
}
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;
}
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<>();
if (intent == null) {
return uris;
@@ -167,7 +200,8 @@ public class Attachment implements Parcelable {
if (clipData != null) {
for (int i = 0; i < clipData.getItemCount(); ++i) {
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));
}
}
@@ -179,13 +213,12 @@ public class Attachment implements Parcelable {
}
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) {
- return mime.startsWith("video/")
- || isImage(mime)
- || "application/pdf".equals(mime);
+ return mime.startsWith("video/") || isImage(mime) || "application/pdf".equals(mime);
}
public Uri getUri() {
@@ -102,14 +102,16 @@ public class ConversationMenuConfigurator {
return;
}
- if (conversation.getNextEncryption() != Message.ENCRYPTION_NONE) {
- menuSecure.setIcon(R.drawable.ic_lock_white_24dp);
+ if (next == Message.ENCRYPTION_NONE) {
+ menuSecure.setIcon(R.drawable.ic_lock_open_outline_24dp);
+ } else {
+ menuSecure.setIcon(R.drawable.ic_lock_24dp);
}
pgp.setVisible(Config.supportOpenPgp());
none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
axolotl.setVisible(Config.supportOmemo());
- switch (conversation.getNextEncryption()) {
+ switch (next) {
case Message.ENCRYPTION_PGP:
menuSecure.setTitle(R.string.encrypted_with_openpgp);
pgp.setChecked(true);
@@ -12,6 +12,8 @@ import android.view.View;
import androidx.appcompat.app.AlertDialog;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
@@ -200,7 +202,7 @@ public final class MucDetailsContextMenuHelper {
activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
}
} else {
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.setTitle(R.string.ban_from_conference);
String jid = user.getRealJid().asBareJid().toString();
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 com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import java.util.Collections;
import java.util.Map;
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) {
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));
Pair<Map<String, String>, Map<String, String>> typeAndName = presences.toTypeAndNameMap();
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) {
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ public static void warnMutualPresenceSubscription(final Activity activity, final Conversation conversation, final OnPresenceSelected listener) {
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.setTitle(conversation.getContact().getJid().toString());
builder.setMessage(R.string.without_mutual_presence_updates);
builder.setNegativeButton(R.string.cancel, null);
@@ -31,8 +31,15 @@ package eu.siacs.conversations.ui.util;
import android.app.Activity;
import android.content.SharedPreferences;
-import android.content.res.TypedArray;
+import android.content.res.Configuration;
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.entities.Conversation;
@@ -42,149 +49,90 @@ import eu.siacs.conversations.utils.UIHelper;
public class SendButtonTool {
- public static SendButtonAction getAction(final Activity activity, final Conversation c, final String text) {
- if (activity == null) {
- return SendButtonAction.TEXT;
- }
- final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
- final boolean empty = text.length() == 0;
- final boolean conference = c.getMode() == Conversation.MODE_MULTI;
- if (c.getCorrectingMessage() != null && (empty || text.equals(c.getCorrectingMessage().getBody()))) {
- return SendButtonAction.CANCEL;
- } else if (conference && !c.getAccount().httpUploadAvailable()) {
- if (empty && c.getNextCounterpart() != null) {
- return SendButtonAction.CANCEL;
- } else {
- return SendButtonAction.TEXT;
- }
- } else {
- if (empty) {
- if (conference && c.getNextCounterpart() != null) {
- return SendButtonAction.CANCEL;
- } else {
- String setting = preferences.getString("quick_action", activity.getResources().getString(R.string.quick_action));
- if (!"none".equals(setting) && UIHelper.receivedLocationQuestion(c.getLatestMessage())) {
- return SendButtonAction.SEND_LOCATION;
- } else {
- if ("recent".equals(setting)) {
- setting = 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) {
- switch (action) {
- case TEXT:
- switch (status) {
- case CHAT:
- case ONLINE:
- return R.drawable.ic_send_text_online;
- case AWAY:
- return R.drawable.ic_send_text_away;
- 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();
+ public static SendButtonAction getAction(
+ final Activity activity, final Conversation c, final String text) {
+ if (activity == null) {
+ return SendButtonAction.TEXT;
+ }
+ final SharedPreferences preferences =
+ PreferenceManager.getDefaultSharedPreferences(activity);
+ final boolean empty = text.isEmpty();
+ final boolean conference = c.getMode() == Conversation.MODE_MULTI;
+ if (c.getCorrectingMessage() != null
+ && (empty || text.equals(c.getCorrectingMessage().getBody()))) {
+ return SendButtonAction.CANCEL;
+ } else if (conference && !c.getAccount().httpUploadAvailable()) {
+ if (empty && c.getNextCounterpart() != null) {
+ return SendButtonAction.CANCEL;
+ } else {
+ return SendButtonAction.TEXT;
+ }
+ } else {
+ if (empty) {
+ if (conference && c.getNextCounterpart() != null) {
+ return SendButtonAction.CANCEL;
+ } else {
+ String setting =
+ preferences.getString(
+ "quick_action",
+ activity.getResources().getString(R.string.quick_action));
+ if (!"none".equals(setting)
+ && UIHelper.receivedLocationQuestion(c.getLatestMessage())) {
+ return SendButtonAction.SEND_LOCATION;
+ } else {
+ if ("recent".equals(setting)) {
+ setting =
+ preferences.getString(
+ ConversationFragment.RECENTLY_USED_QUICK_ACTION,
+ SendButtonAction.TEXT.toString());
+ return SendButtonAction.valueOfOrDefault(setting);
+ } else {
+ return SendButtonAction.valueOfOrDefault(setting);
+ }
+ }
+ }
+ } else {
+ return SendButtonAction.TEXT;
+ }
+ }
+ }
- return res;
- }
+ public @DrawableRes static int getSendButtonImageResource(final SendButtonAction action) {
+ return switch (action) {
+ case TEXT -> R.drawable.ic_send_24dp;
+ case TAKE_PHOTO -> R.drawable.ic_camera_alt_24dp;
+ case SEND_LOCATION -> R.drawable.ic_location_pin_24dp;
+ case CHOOSE_PICTURE -> R.drawable.ic_image_24dp;
+ case RECORD_VIDEO -> R.drawable.ic_videocam_24dp;
+ case RECORD_VOICE -> R.drawable.ic_mic_24dp;
+ case CANCEL -> R.drawable.ic_cancel_24dp;
+ };
+ }
+ 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;
- }
-}
@@ -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;
+ }
+}
@@ -32,7 +32,9 @@ package eu.siacs.conversations.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
-public class ImmediateAutoCompleteTextView extends androidx.appcompat.widget.AppCompatAutoCompleteTextView {
+import com.google.android.material.textfield.MaterialAutoCompleteTextView;
+
+public class ImmediateAutoCompleteTextView extends MaterialAutoCompleteTextView {
public ImmediateAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -29,6 +29,8 @@ import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
+import androidx.core.content.ContextCompat;
+
import com.google.zxing.ResultPoint;
import java.util.HashMap;
@@ -58,25 +60,24 @@ public class ScannerView extends View {
public ScannerView(final Context context, final AttributeSet attrs) {
super(context, attrs);
-
- final Resources res = getResources();
- maskColor = res.getColor(R.color.black54);
- maskResultColor = res.getColor(R.color.black87);
- laserColor = res.getColor(R.color.red500);
- dotColor = res.getColor(R.color.orange500);
- dotResultColor = res.getColor(R.color.scan_result_dots);
+ final Resources resources = context.getResources();
+ maskColor = ContextCompat.getColor(context, R.color.black54);
+ maskResultColor = ContextCompat.getColor(context, R.color.black87);
+ laserColor = ContextCompat.getColor(context, R.color.red_500);
+ dotColor = ContextCompat.getColor(context, R.color.orange_500);
+ dotResultColor = ContextCompat.getColor(context, R.color.green_500);
maskPaint = new Paint();
maskPaint.setStyle(Style.FILL);
laserPaint = new Paint();
- laserPaint.setStrokeWidth(res.getDimensionPixelSize(R.dimen.scan_laser_width));
+ laserPaint.setStrokeWidth(resources.getDimensionPixelSize(R.dimen.scan_laser_width));
laserPaint.setStyle(Style.STROKE);
dotPaint = new Paint();
dotPaint.setAlpha(DOT_OPACITY);
dotPaint.setStyle(Style.STROKE);
- dotPaint.setStrokeWidth(res.getDimension(R.dimen.scan_dot_size));
+ dotPaint.setStrokeWidth(resources.getDimension(R.dimen.scan_dot_size));
dotPaint.setAntiAlias(true);
}
@@ -26,8 +26,6 @@ import android.widget.ListView;
import androidx.fragment.app.ListFragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import eu.siacs.conversations.ui.util.StyledAttributes;
-
/**
* Subclass of {@link androidx.fragment.app.ListFragment} which provides automatic support for
* providing the 'swipe-to-refresh' UX gesture by wrapping the the content view in a
@@ -56,7 +54,8 @@ public class SwipeRefreshListFragment extends ListFragment {
final Context context = getActivity();
if (context != null) {
- mSwipeRefreshLayout.setColorSchemeColors(StyledAttributes.getColor(context, androidx.appcompat.R.attr.colorAccent));
+ // TODO are default colors fine here?
+ //mSwipeRefreshLayout.setColorSchemeColors(StyledAttributes.getColor(context, androidx.appcompat.R.attr.colorAccent));
}
if (onRefreshListener != null) {
@@ -9,6 +9,7 @@ import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import eu.siacs.conversations.R;
@@ -18,6 +19,7 @@ public class UnreadCountCustomView extends View {
private int unreadCount;
private Paint paint, textPaint;
private int backgroundColor = 0xff326130;
+ private int textColor = Color.WHITE;
public UnreadCountCustomView(Context context) {
super(context);
@@ -38,7 +40,8 @@ public class UnreadCountCustomView extends View {
private void initXMLAttrs(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UnreadCountCustomView);
- setBackgroundColor(a.getColor(a.getIndex(0), ContextCompat.getColor(context, R.color.green700_desaturated)));
+ setBackgroundColor(a.getColor(a.getIndex(0), ContextCompat.getColor(context, R.color.md_theme_light_tertiaryContainer)));
+ this.textColor = a.getColor(a.getIndex(1),ContextCompat.getColor(context, R.color.md_theme_light_onTertiaryContainer));
a.recycle();
}
@@ -47,14 +50,14 @@ public class UnreadCountCustomView extends View {
paint.setColor(backgroundColor);
paint.setAntiAlias(true);
textPaint = new Paint();
- textPaint.setColor(Color.WHITE);
+ textPaint.setColor(textColor);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setAntiAlias(true);
textPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
}
@Override
- protected void onDraw(Canvas canvas) {
+ protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
float midx = canvas.getWidth() / 2.0f;
float midy = canvas.getHeight() / 2.0f;
@@ -61,11 +61,7 @@ public class AccountUtils {
final ArrayList<String> accounts = new ArrayList<>();
for (final Account account : service.getAccounts()) {
if (account.isEnabled()) {
- if (Config.DOMAIN_LOCK != null) {
- accounts.add(account.getJid().getEscapedLocal());
- } else {
- accounts.add(account.getJid().asBareJid().toEscapedString());
- }
+ accounts.add(account.getJid().asBareJid().toEscapedString());
}
}
return accounts;
@@ -10,6 +10,8 @@ import android.util.Log;
import androidx.appcompat.app.AlertDialog;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
@@ -72,8 +74,7 @@ public class ExceptionHelper {
report.append("SHA-1: ").append(CryptoHelper.getFingerprintCert(packageInfo.signatures[0].toByteArray())).append('\n');
}
report.append('\n');
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (final Exception e) {
return false;
}
String line;
@@ -83,7 +84,7 @@ public class ExceptionHelper {
}
file.close();
activity.deleteFile(FILENAME);
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity);
builder.setTitle(activity.getString(R.string.crash_report_title, activity.getString(R.string.app_name)));
builder.setMessage(activity.getString(R.string.crash_report_message, activity.getString(R.string.app_name)));
builder.setPositiveButton(activity.getText(R.string.send_now), (dialog, which) -> {
@@ -40,6 +40,8 @@ import android.util.LruCache;
import androidx.annotation.ColorInt;
+import com.google.android.material.color.MaterialColors;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -53,7 +55,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import eu.siacs.conversations.R;
-import eu.siacs.conversations.ui.util.StyledAttributes;
import eu.siacs.conversations.xmpp.Jid;
public class IrregularUnicodeDetector {
@@ -76,8 +77,8 @@ public class IrregularUnicodeDetector {
}
}
- public static Spannable style(Context context, Jid jid) {
- return style(jid, StyledAttributes.getColor(context, R.attr.color_warning));
+ public static Spannable style(final Context context, Jid jid) {
+ return style(jid, MaterialColors.getColor(context, com.google.android.material.R.attr.colorError,"colorError not found"));
}
private static Spannable style(Jid jid, @ColorInt int color) {
@@ -328,6 +328,8 @@ public final class MimeUtils {
add("image/x-xbitmap", "xbm");
add("image/x-xpixmap", "xpm");
add("image/x-xwindowdump", "xwd");
+ add("message/rfc822","eml");
+ add("message/rfc822","mime");
add("model/iges", "igs");
add("model/iges", "iges");
add("model/mesh", "msh");
@@ -49,6 +49,8 @@ import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
+import com.google.android.material.color.MaterialColors;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -94,10 +96,10 @@ public class StylingHelper {
format(editable, end, editable.length() - 1, textColor);
}
- public static void highlight(final Context context, final Editable editable, List<String> needles, boolean dark) {
- for (String needle : needles) {
+ public static void highlight(final TextView view, final Editable editable, final List<String> needles) {
+ for (final String needle : needles) {
if (!FtsUtils.isKeyword(needle)) {
- highlight(context, editable, needle, dark);
+ highlight(view, editable, needle);
}
}
}
@@ -124,14 +126,14 @@ public class StylingHelper {
return words;
}
- private static void highlight(final Context context, final Editable editable, String needle, boolean dark) {
+ private static void highlight(final TextView view, final Editable editable, final String needle) {
final int length = needle.length();
String string = editable.toString();
int start = indexOfIgnoreCase(string, needle, 0);
while (start != -1) {
int end = start + length;
- editable.setSpan(new BackgroundColorSpan(ContextCompat.getColor(context, dark ? R.color.blue_a100 : R.color.blue_a400)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
- editable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, dark ? R.color.black87 : R.color.white)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable.setSpan(new BackgroundColorSpan(MaterialColors.getColor(view, com.google.android.material.R.attr.colorPrimaryFixedDim)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
+ editable.setSpan(new ForegroundColorSpan(MaterialColors.getColor(view, com.google.android.material.R.attr.colorOnPrimaryFixed)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
start = indexOfIgnoreCase(string, needle, start + length);
}
@@ -141,8 +143,7 @@ public class StylingHelper {
if (start == 0 && charSequence.length() + 1 == end) {
return charSequence;
}
- if (charSequence instanceof Spannable) {
- Spannable spannable = (Spannable) charSequence;
+ if (charSequence instanceof Spannable spannable) {
Spannable sub = (Spannable) spannable.subSequence(start, end);
for (Class<? extends ParcelableSpan> clazz : SPAN_CLASSES) {
ParcelableSpan[] spannables = spannable.getSpans(start, end, clazz);
@@ -175,25 +176,14 @@ public class StylingHelper {
}
}
- public static boolean isDarkText(TextView textView) {
- int argb = textView.getCurrentTextColor();
- return Color.red(argb) + Color.green(argb) + Color.blue(argb) == 0;
- }
-
- private static ParcelableSpan createSpanForStyle(ImStyleParser.Style style) {
- switch (style.getKeyword()) {
- case "*":
- return new StyleSpan(Typeface.BOLD);
- case "_":
- return new StyleSpan(Typeface.ITALIC);
- case "~":
- return new StrikethroughSpan();
- case "`":
- case "```":
- return new TypefaceSpan("monospace");
- default:
- throw new AssertionError("Unknown Style");
- }
+ private static ParcelableSpan createSpanForStyle(final ImStyleParser.Style style) {
+ return switch (style.getKeyword()) {
+ case "*" -> new StyleSpan(Typeface.BOLD);
+ case "_" -> new StyleSpan(Typeface.ITALIC);
+ case "~" -> new StrikethroughSpan();
+ case "`", "```" -> new TypefaceSpan("monospace");
+ default -> throw new AssertionError("Unknown Style");
+ };
}
private static void makeKeywordOpaque(final Editable editable, int start, int end, @ColorInt int fallbackTextColor) {
@@ -1,117 +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.utils;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.os.Build;
-import android.preference.PreferenceManager;
-import android.util.TypedValue;
-import android.widget.TextView;
-
-import androidx.annotation.StyleRes;
-import androidx.core.content.ContextCompat;
-
-import com.google.android.material.snackbar.Snackbar;
-
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.ui.SettingsActivity;
-
-public class ThemeHelper {
-
- public static int find(final Context context) {
- final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- final Resources resources = context.getResources();
- final boolean dark = isDark(sharedPreferences, resources);
- final String fontSize = sharedPreferences.getString("font_size", resources.getString(R.string.default_font_size));
- switch (fontSize) {
- case "medium":
- return dark ? R.style.ConversationsTheme_Dark_Medium : R.style.ConversationsTheme_Medium;
- case "large":
- return dark ? R.style.ConversationsTheme_Dark_Large : R.style.ConversationsTheme_Large;
- default:
- return dark ? R.style.ConversationsTheme_Dark : R.style.ConversationsTheme;
- }
- }
-
- public static int findDialog(Context context) {
- final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- final Resources resources = context.getResources();
- final boolean dark = isDark(sharedPreferences, resources);
- final String fontSize = sharedPreferences.getString("font_size", resources.getString(R.string.default_font_size));
- switch (fontSize) {
- case "medium":
- return dark ? R.style.ConversationsTheme_Dark_Dialog_Medium : R.style.ConversationsTheme_Dialog_Medium;
- case "large":
- return dark ? R.style.ConversationsTheme_Dark_Dialog_Large : R.style.ConversationsTheme_Dialog_Large;
- default:
- return dark ? R.style.ConversationsTheme_Dark_Dialog : R.style.ConversationsTheme_Dialog;
- }
- }
-
- private static boolean isDark(final SharedPreferences sharedPreferences, final Resources resources) {
- final String setting = sharedPreferences.getString(SettingsActivity.THEME, resources.getString(R.string.theme));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && "automatic".equals(setting)) {
- return (resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
- } else {
- return "dark".equals(setting);
- }
- }
-
- public static boolean isDark(@StyleRes int id) {
- switch (id) {
- case R.style.ConversationsTheme_Dark:
- case R.style.ConversationsTheme_Dark_Large:
- case R.style.ConversationsTheme_Dark_Medium:
- return true;
- default:
- return false;
- }
- }
-
- public static void fix(Snackbar snackbar) {
- final Context context = snackbar.getContext();
- TypedArray typedArray = context.obtainStyledAttributes(new int[]{R.attr.TextSizeBody1});
- final float size = typedArray.getDimension(0,0f);
- typedArray.recycle();
- if (size != 0f) {
- final TextView text = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_text);
- final TextView action = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_action);
- if (text != null && action != null) {
- text.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
- action.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
- action.setTextColor(ContextCompat.getColor(context, R.color.blue_a100));
- }
- }
- }
-}