apply Material 3 theme to all activites
This commit is contained in:
parent
4968bde774
commit
6e43248135
|
@ -74,7 +74,7 @@ dependencies {
|
|||
implementation 'org.hsluv:hsluv:0.2'
|
||||
implementation 'org.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);
|
||||
}
|
||||
xmppConnectionService.createAccount(account);
|
||||
if (!jid.getEscapedLocal().equals(jid.getLocal())
|
||||
|| (this.username == null && username.length() < 3)) {
|
||||
binding.usernameLayout.setError(getString(R.string.invalid_username));
|
||||
binding.username.requestFocus();
|
||||
} else {
|
||||
binding.usernameLayout.setError(null);
|
||||
Account account = xmppConnectionService.findAccountByJid(jid);
|
||||
if (account == null) {
|
||||
account =
|
||||
new Account(
|
||||
jid,
|
||||
CryptoHelper.createPassword(new SecureRandom()));
|
||||
account.setOption(Account.OPTION_REGISTER, true);
|
||||
account.setOption(Account.OPTION_DISABLED, true);
|
||||
account.setOption(Account.OPTION_MAGIC_CREATE, true);
|
||||
account.setOption(Account.OPTION_FIXED_USERNAME, fixedUsername);
|
||||
if (this.preAuth != null) {
|
||||
account.setKey(
|
||||
Account.KEY_PRE_AUTH_REGISTRATION_TOKEN, this.preAuth);
|
||||
}
|
||||
xmppConnectionService.createAccount(account);
|
||||
}
|
||||
Intent intent =
|
||||
new Intent(MagicCreateActivity.this, EditAccountActivity.class);
|
||||
intent.putExtra("jid", account.getJid().asBareJid().toString());
|
||||
intent.putExtra("init", true);
|
||||
intent.setFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
Toast.makeText(
|
||||
MagicCreateActivity.this,
|
||||
R.string.secure_password_generated,
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
} catch (final IllegalArgumentException e) {
|
||||
binding.usernameLayout.setError(getString(R.string.invalid_username));
|
||||
binding.username.requestFocus();
|
||||
}
|
||||
Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class);
|
||||
intent.putExtra("jid", account.getJid().asBareJid().toString());
|
||||
intent.putExtra("init", true);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
Toast.makeText(MagicCreateActivity.this, R.string.secure_password_generated, Toast.LENGTH_SHORT).show();
|
||||
StartConversationActivity.addInviteUri(intent, getIntent());
|
||||
startActivity(intent);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
binding.username.setError(getString(R.string.invalid_username));
|
||||
binding.username.requestFocus();
|
||||
}
|
||||
});
|
||||
});
|
||||
binding.username.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 258 B |
Binary file not shown.
Before Width: | Height: | Size: 181 B |
Binary file not shown.
Before Width: | Height: | Size: 273 B |
Binary file not shown.
Before Width: | Height: | Size: 391 B |
Binary file not shown.
Before Width: | Height: | Size: 503 B |
|
@ -1,17 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"
|
||||
|
|
63
src/conversations/res/values/colors-themed.xml
Normal file
63
src/conversations/res/values/colors-themed.xml
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="md_theme_light_primary">#006E1C</color>
|
||||
<color name="md_theme_light_onPrimary">#FFFFFF</color>
|
||||
<color name="md_theme_light_primaryContainer">#98F994</color>
|
||||
<color name="md_theme_light_onPrimaryContainer">#002204</color>
|
||||
<color name="md_theme_light_secondary">#52634F</color>
|
||||
<color name="md_theme_light_onSecondary">#FFFFFF</color>
|
||||
<color name="md_theme_light_secondaryContainer">#D5E8CF</color>
|
||||
<color name="md_theme_light_onSecondaryContainer">#111F0F</color>
|
||||
<color name="md_theme_light_tertiary">#38656A</color>
|
||||
<color name="md_theme_light_onTertiary">#FFFFFF</color>
|
||||
<color name="md_theme_light_tertiaryContainer">#BCEBF0</color>
|
||||
<color name="md_theme_light_onTertiaryContainer">#002023</color>
|
||||
<color name="md_theme_light_error">#BA1A1A</color>
|
||||
<color name="md_theme_light_errorContainer">#FFDAD6</color>
|
||||
<color name="md_theme_light_onError">#FFFFFF</color>
|
||||
<color name="md_theme_light_onErrorContainer">#410002</color>
|
||||
<color name="md_theme_light_background">#FCFDF6</color>
|
||||
<color name="md_theme_light_onBackground">#1A1C19</color>
|
||||
<color name="md_theme_light_surface">#FCFDF6</color>
|
||||
<color name="md_theme_light_onSurface">#1A1C19</color>
|
||||
<color name="md_theme_light_surfaceVariant">#DEE5D8</color>
|
||||
<color name="md_theme_light_onSurfaceVariant">#424940</color>
|
||||
<color name="md_theme_light_outline">#72796F</color>
|
||||
<color name="md_theme_light_inverseOnSurface">#F0F1EB</color>
|
||||
<color name="md_theme_light_inverseSurface">#2F312D</color>
|
||||
<color name="md_theme_light_inversePrimary">#7DDC7A</color>
|
||||
<color name="md_theme_light_shadow">#000000</color>
|
||||
<color name="md_theme_light_surfaceTint">#006E1C</color>
|
||||
<color name="md_theme_light_outlineVariant">#C2C9BD</color>
|
||||
<color name="md_theme_light_scrim">#000000</color>
|
||||
<color name="md_theme_dark_primary">#7DDC7A</color>
|
||||
<color name="md_theme_dark_onPrimary">#00390A</color>
|
||||
<color name="md_theme_dark_primaryContainer">#005313</color>
|
||||
<color name="md_theme_dark_onPrimaryContainer">#98F994</color>
|
||||
<color name="md_theme_dark_secondary">#BACCB3</color>
|
||||
<color name="md_theme_dark_onSecondary">#253423</color>
|
||||
<color name="md_theme_dark_secondaryContainer">#3B4B38</color>
|
||||
<color name="md_theme_dark_onSecondaryContainer">#D5E8CF</color>
|
||||
<color name="md_theme_dark_tertiary">#A0CFD4</color>
|
||||
<color name="md_theme_dark_onTertiary">#00363B</color>
|
||||
<color name="md_theme_dark_tertiaryContainer">#1F4D52</color>
|
||||
<color name="md_theme_dark_onTertiaryContainer">#BCEBF0</color>
|
||||
<color name="md_theme_dark_error">#FFB4AB</color>
|
||||
<color name="md_theme_dark_errorContainer">#93000A</color>
|
||||
<color name="md_theme_dark_onError">#690005</color>
|
||||
<color name="md_theme_dark_onErrorContainer">#FFDAD6</color>
|
||||
<color name="md_theme_dark_background">#1A1C19</color>
|
||||
<color name="md_theme_dark_onBackground">#E2E3DD</color>
|
||||
<color name="md_theme_dark_surface">#1A1C19</color>
|
||||
<color name="md_theme_dark_onSurface">#E2E3DD</color>
|
||||
<color name="md_theme_dark_surfaceVariant">#424940</color>
|
||||
<color name="md_theme_dark_onSurfaceVariant">#C2C9BD</color>
|
||||
<color name="md_theme_dark_outline">#8C9388</color>
|
||||
<color name="md_theme_dark_inverseOnSurface">#1A1C19</color>
|
||||
<color name="md_theme_dark_inverseSurface">#E2E3DD</color>
|
||||
<color name="md_theme_dark_inversePrimary">#006E1C</color>
|
||||
<color name="md_theme_dark_shadow">#000000</color>
|
||||
<color name="md_theme_dark_surfaceTint">#7DDC7A</color>
|
||||
<color name="md_theme_dark_outlineVariant">#424940</color>
|
||||
<color name="md_theme_dark_scrim">#000000</color>
|
||||
</resources>
|
|
@ -47,7 +47,7 @@
|
|||
<!-- this foreground service type permission is exclusively used for import and export backup -->
|
||||
<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");
|
||||
|
||||
|
|
67
src/main/java/eu/siacs/conversations/Conversations.java
Normal file
67
src/main/java/eu/siacs/conversations/Conversations.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
package eu.siacs.conversations;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import com.google.android.material.color.DynamicColors;
|
||||
import com.google.android.material.color.DynamicColorsOptions;
|
||||
|
||||
public class Conversations extends Application {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
applyThemeSettings();
|
||||
}
|
||||
|
||||
public void applyThemeSettings() {
|
||||
final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
if (sharedPreferences == null) {
|
||||
return;
|
||||
}
|
||||
applyThemeSettings(sharedPreferences);
|
||||
}
|
||||
|
||||
private void applyThemeSettings(final SharedPreferences sharedPreferences) {
|
||||
AppCompatDelegate.setDefaultNightMode(getDesiredNightMode(this, sharedPreferences));
|
||||
var dynamicColorsOptions =
|
||||
new DynamicColorsOptions.Builder()
|
||||
.setPrecondition((activity, t) -> isDynamicColorsDesired(activity))
|
||||
.build();
|
||||
DynamicColors.applyToActivitiesIfAvailable(this, dynamicColorsOptions);
|
||||
}
|
||||
|
||||
public static int getDesiredNightMode(final Context context) {
|
||||
final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (sharedPreferences == null) {
|
||||
return AppCompatDelegate.getDefaultNightMode();
|
||||
}
|
||||
return getDesiredNightMode(context, sharedPreferences);
|
||||
}
|
||||
|
||||
public static boolean isDynamicColorsDesired(final Context context) {
|
||||
final var preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return preferences.getBoolean("dynamic_colors", false);
|
||||
}
|
||||
|
||||
private static int getDesiredNightMode(
|
||||
final Context context, final SharedPreferences sharedPreferences) {
|
||||
final String theme =
|
||||
sharedPreferences.getString("theme", context.getString(R.string.theme));
|
||||
return getDesiredNightMode(theme);
|
||||
}
|
||||
|
||||
public static int getDesiredNightMode(final String theme) {
|
||||
if ("automatic".equals(theme)) {
|
||||
return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
} else if ("light".equals(theme)) {
|
||||
return AppCompatDelegate.MODE_NIGHT_NO;
|
||||
} else {
|
||||
return AppCompatDelegate.MODE_NIGHT_YES;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,18 +41,18 @@ public class RtpSessionStatus {
|
|||
return new RtpSessionStatus(made, duration);
|
||||
}
|
||||
|
||||
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 android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||
import eu.siacs.conversations.utils.ThemeHelper;
|
||||
|
||||
import static eu.siacs.conversations.ui.XmppActivity.configureActionBar;
|
||||
|
||||
public class AboutActivity extends AppCompatActivity {
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ActivityAboutBinding;
|
||||
|
||||
public class AboutActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onResume(){
|
||||
super.onResume();
|
||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
|
47
src/main/java/eu/siacs/conversations/ui/Activities.java
Normal file
47
src/main/java/eu/siacs/conversations/ui/Activities.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package eu.siacs.conversations.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import com.google.android.material.elevation.SurfaceColors;
|
||||
|
||||
public final class Activities {
|
||||
|
||||
private Activities() {}
|
||||
|
||||
public static void setStatusAndNavigationBarColors(final Activity activity, final View view) {
|
||||
setStatusAndNavigationBarColors(activity, view, false);
|
||||
}
|
||||
|
||||
public static void setStatusAndNavigationBarColors(
|
||||
final Activity activity, final View view, final boolean raisedStatusBar) {
|
||||
final var isLightMode = isLightMode(activity);
|
||||
final var window = activity.getWindow();
|
||||
final var flags = view.getSystemUiVisibility();
|
||||
// an elevation of 4 matches the MaterialToolbar elevation
|
||||
if (raisedStatusBar) {
|
||||
window.setStatusBarColor(SurfaceColors.SURFACE_5.getColor(activity));
|
||||
} else {
|
||||
window.setStatusBarColor(SurfaceColors.SURFACE_0.getColor(activity));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
window.setNavigationBarColor(SurfaceColors.SURFACE_1.getColor(activity));
|
||||
if (isLightMode) {
|
||||
view.setSystemUiVisibility(
|
||||
flags
|
||||
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
| View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
|
||||
}
|
||||
} else if (isLightMode) {
|
||||
view.setSystemUiVisibility(flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLightMode(final Context context) {
|
||||
final int nightModeFlags =
|
||||
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
return nightModeFlags != Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
}
|
53
src/main/java/eu/siacs/conversations/ui/BaseActivity.java
Normal file
53
src/main/java/eu/siacs/conversations/ui/BaseActivity.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package eu.siacs.conversations.ui;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import eu.siacs.conversations.Conversations;
|
||||
import eu.siacs.conversations.ui.util.SettingsUtils;
|
||||
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
private Boolean isDynamicColors;
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final int desiredNightMode = Conversations.getDesiredNightMode(this);
|
||||
if (setDesiredNightMode(desiredNightMode)) {
|
||||
return;
|
||||
}
|
||||
final boolean isDynamicColors = Conversations.isDynamicColorsDesired(this);
|
||||
setDynamicColors(isDynamicColors);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume(){
|
||||
super.onResume();
|
||||
SettingsUtils.applyScreenshotPreventionSetting(this);
|
||||
}
|
||||
|
||||
public void setDynamicColors(final boolean isDynamicColors) {
|
||||
if (this.isDynamicColors == null) {
|
||||
this.isDynamicColors = isDynamicColors;
|
||||
} else {
|
||||
if (this.isDynamicColors != isDynamicColors) {
|
||||
Log.i(
|
||||
"Recreating {} because dynamic color setting has changed",
|
||||
getClass().getSimpleName());
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setDesiredNightMode(final int desiredNightMode) {
|
||||
if (desiredNightMode == AppCompatDelegate.getDefaultNightMode()) {
|
||||
return false;
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(desiredNightMode);
|
||||
Log.i("Recreating {} because desired night mode has changed", getClass().getSimpleName());
|
||||
recreate();
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import androidx.annotation.StringRes;
|
|||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.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);
|
||||
} else if (newPassword.trim().isEmpty()) {
|
||||
mNewPassword.requestFocus();
|
||||
mNewPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
|
||||
removeErrorsOnAllBut(mNewPasswordLayout);
|
||||
} else {
|
||||
mCurrentPasswordLayout.setError(null);
|
||||
mNewPasswordLayout.setError(null);
|
||||
xmppConnectionService.updateAccountPasswordOnServer(mAccount, newPassword, ChangePasswordActivity.this);
|
||||
mChangePasswordButton.setEnabled(false);
|
||||
mChangePasswordButton.setText(R.string.updating);
|
||||
}
|
||||
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()) {
|
||||
binding.newPassword.requestFocus();
|
||||
binding.newPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
|
||||
removeErrorsOnAllBut(binding.newPasswordLayout);
|
||||
} else {
|
||||
binding.currentPasswordLayout.setError(null);
|
||||
binding.newPasswordLayout.setError(null);
|
||||
xmppConnectionService.updateAccountPasswordOnServer(account, newPassword, ChangePasswordActivity.this);
|
||||
binding.changePasswordButton.setEnabled(false);
|
||||
binding.changePasswordButton.setText(R.string.updating);
|
||||
}
|
||||
}
|
||||
};
|
||||
private EditText mCurrentPassword;
|
||||
private EditText mNewPassword;
|
||||
private TextInputLayout mNewPasswordLayout;
|
||||
private TextInputLayout mCurrentPasswordLayout;
|
||||
|
||||
|
||||
|
||||
private Account mAccount;
|
||||
|
||||
@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 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;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.ui.adapter.AccountAdapter;
|
||||
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
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.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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 com.google.android.material.color.MaterialColors;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ItemMediaBinding;
|
||||
import eu.siacs.conversations.services.ExportBackupService;
|
||||
import eu.siacs.conversations.ui.XmppActivity;
|
||||
import eu.siacs.conversations.ui.util.Attachment;
|
||||
import eu.siacs.conversations.ui.util.ViewUtil;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.MediaBinding;
|
||||
import eu.siacs.conversations.services.ExportBackupService;
|
||||
import eu.siacs.conversations.ui.XmppActivity;
|
||||
import eu.siacs.conversations.ui.util.Attachment;
|
||||
import eu.siacs.conversations.ui.util.StyledAttributes;
|
||||
import eu.siacs.conversations.ui.util.ViewUtil;
|
||||
|
||||
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
|
||||
|
||||
public 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());
|
||||
}
|
||||
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)));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.ItemMediaPreviewBinding;
|
||||
import eu.siacs.conversations.persistance.FileBackend;
|
||||
import eu.siacs.conversations.ui.ConversationFragment;
|
||||
import eu.siacs.conversations.ui.XmppActivity;
|
||||
import eu.siacs.conversations.ui.util.Attachment;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.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.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> {
|
||||
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);
|
||||
viewHolder.indicator.setImageResource(R.drawable.ic_verified_user_24dp);
|
||||
} else {
|
||||
viewHolder.indicator.setImageResource(darkBackground ? R.drawable.ic_lock_white_18dp : R.drawable.ic_lock_black_18dp);
|
||||
}
|
||||
if (darkBackground) {
|
||||
viewHolder.indicator.setAlpha(0.7f);
|
||||
} 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;
|
||||
private MessageAdapter.BubbleColor bubbleColor = MessageAdapter.BubbleColor.SURFACE;
|
||||
|
||||
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);
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
166
src/main/java/eu/siacs/conversations/ui/util/ToolbarUtils.java
Normal file
166
src/main/java/eu/siacs/conversations/ui/util/ToolbarUtils.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package eu.siacs.conversations.ui.util;
|
||||
|
||||
import static java.util.Collections.max;
|
||||
import static java.util.Collections.min;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.ActionMenuView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ToolbarUtils {
|
||||
|
||||
private static final Comparator<View> VIEW_TOP_COMPARATOR =
|
||||
new Comparator<View>() {
|
||||
@Override
|
||||
public int compare(View view1, View view2) {
|
||||
return view1.getTop() - view2.getTop();
|
||||
}
|
||||
};
|
||||
|
||||
private ToolbarUtils() {
|
||||
// Private constructor to prevent unwanted construction.
|
||||
}
|
||||
|
||||
public static void resetActionBarOnClickListeners(@NonNull MaterialToolbar view) {
|
||||
final TextView title = getTitleTextView(view);
|
||||
final TextView subtitle = getSubtitleTextView(view);
|
||||
if (title != null) {
|
||||
title.setOnClickListener(null);
|
||||
}
|
||||
if (subtitle != null) {
|
||||
subtitle.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setActionBarOnClickListener(
|
||||
@NonNull MaterialToolbar view, @NonNull final View.OnClickListener onClickListener) {
|
||||
final TextView title = getTitleTextView(view);
|
||||
final TextView subtitle = getSubtitleTextView(view);
|
||||
if (title != null) {
|
||||
title.setOnClickListener(onClickListener);
|
||||
}
|
||||
if (subtitle != null) {
|
||||
subtitle.setOnClickListener(onClickListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextView getTitleTextView(@NonNull Toolbar toolbar) {
|
||||
List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getTitle());
|
||||
return textViews.isEmpty() ? null : min(textViews, VIEW_TOP_COMPARATOR);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextView getSubtitleTextView(@NonNull Toolbar toolbar) {
|
||||
List<TextView> textViews = getTextViewsWithText(toolbar, toolbar.getSubtitle());
|
||||
return textViews.isEmpty() ? null : max(textViews, VIEW_TOP_COMPARATOR);
|
||||
}
|
||||
|
||||
private static List<TextView> getTextViewsWithText(
|
||||
@NonNull Toolbar toolbar, CharSequence text) {
|
||||
List<TextView> textViews = new ArrayList<>();
|
||||
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||
View child = toolbar.getChildAt(i);
|
||||
if (child instanceof TextView textView) {
|
||||
if (TextUtils.equals(textView.getText(), text)) {
|
||||
textViews.add(textView);
|
||||
}
|
||||
}
|
||||
}
|
||||
return textViews;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ImageView getLogoImageView(@NonNull Toolbar toolbar) {
|
||||
return getImageView(toolbar, toolbar.getLogo());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ImageView getImageView(@NonNull Toolbar toolbar, @Nullable Drawable content) {
|
||||
if (content == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||
View child = toolbar.getChildAt(i);
|
||||
if (child instanceof ImageView imageView) {
|
||||
Drawable drawable = imageView.getDrawable();
|
||||
if (drawable != null
|
||||
&& drawable.getConstantState() != null
|
||||
&& drawable.getConstantState().equals(content.getConstantState())) {
|
||||
return imageView;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static View getSecondaryActionMenuItemView(@NonNull Toolbar toolbar) {
|
||||
ActionMenuView actionMenuView = getActionMenuView(toolbar);
|
||||
if (actionMenuView != null) {
|
||||
// Only return the first child of the ActionMenuView if there is more than one child
|
||||
if (actionMenuView.getChildCount() > 1) {
|
||||
return actionMenuView.getChildAt(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ActionMenuView getActionMenuView(@NonNull Toolbar toolbar) {
|
||||
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||
View child = toolbar.getChildAt(i);
|
||||
if (child instanceof ActionMenuView) {
|
||||
return (ActionMenuView) child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ImageButton getNavigationIconButton(@NonNull Toolbar toolbar) {
|
||||
Drawable navigationIcon = toolbar.getNavigationIcon();
|
||||
if (navigationIcon == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < toolbar.getChildCount(); i++) {
|
||||
View child = toolbar.getChildAt(i);
|
||||
if (child instanceof ImageButton imageButton) {
|
||||
if (imageButton.getDrawable() == navigationIcon) {
|
||||
return imageButton;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue