Detailed changes
@@ -78,6 +78,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -114,7 +115,7 @@ public class NotificationService {
private static final String INCOMING_CALLS_NOTIFICATION_CHANNEL = "incoming_calls_channel";
private static final String INCOMING_CALLS_NOTIFICATION_CHANNEL_PREFIX =
"incoming_calls_channel#";
- private static final String MESSAGES_NOTIFICATION_CHANNEL = "messages";
+ public static final String MESSAGES_NOTIFICATION_CHANNEL = "messages";
NotificationService(final XmppConnectionService service) {
this.mXmppConnectionService = service;
@@ -229,25 +230,8 @@ public class NotificationService {
missedCallsChannel.setGroup("calls");
notificationManager.createNotificationChannel(missedCallsChannel);
- final NotificationChannel messagesChannel =
- new NotificationChannel(
- MESSAGES_NOTIFICATION_CHANNEL,
- c.getString(R.string.messages_channel_name),
- NotificationManager.IMPORTANCE_HIGH);
- messagesChannel.setShowBadge(true);
- messagesChannel.setSound(
- RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
- new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setUsage(AudioAttributes.USAGE_NOTIFICATION)
- .build());
- messagesChannel.setLightColor(LED_COLOR);
- final int dat = 70;
- final long[] pattern = {0, 3 * dat, dat, dat};
- messagesChannel.setVibrationPattern(pattern);
- messagesChannel.enableVibration(true);
- messagesChannel.enableLights(true);
- messagesChannel.setGroup("chats");
+ final var messagesChannel =
+ prepareMessagesChannel(mXmppConnectionService, MESSAGES_NOTIFICATION_CHANNEL);
notificationManager.createNotificationChannel(messagesChannel);
final NotificationChannel silentMessagesChannel =
new NotificationChannel(
@@ -278,6 +262,41 @@ public class NotificationService {
notificationManager.createNotificationChannel(deliveryFailedChannel);
}
+ @RequiresApi(api = Build.VERSION_CODES.R)
+ public static void createConversationChannel(
+ final Context context, final ShortcutInfoCompat shortcut) {
+ final var messagesChannel = prepareMessagesChannel(context, UUID.randomUUID().toString());
+ messagesChannel.setName(shortcut.getShortLabel());
+ messagesChannel.setConversationId(MESSAGES_NOTIFICATION_CHANNEL, shortcut.getId());
+ final var notificationManager = context.getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(messagesChannel);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.O)
+ private static NotificationChannel prepareMessagesChannel(
+ final Context context, final String id) {
+ final NotificationChannel messagesChannel =
+ new NotificationChannel(
+ id,
+ context.getString(R.string.messages_channel_name),
+ NotificationManager.IMPORTANCE_HIGH);
+ messagesChannel.setShowBadge(true);
+ messagesChannel.setSound(
+ RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
+ new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION)
+ .build());
+ messagesChannel.setLightColor(LED_COLOR);
+ final int dat = 70;
+ final long[] pattern = {0, 3 * dat, dat, dat};
+ messagesChannel.setVibrationPattern(pattern);
+ messagesChannel.enableVibration(true);
+ messagesChannel.enableLights(true);
+ messagesChannel.setGroup("chats");
+ return messagesChannel;
+ }
+
@RequiresApi(api = Build.VERSION_CODES.O)
private static void createInitialIncomingCallChannelIfNecessary(final Context context) {
final var currentIteration = getCurrentIncomingCallChannelIteration(context);
@@ -93,6 +93,12 @@ public class ShortcutService {
}
}
+ public ShortcutInfoCompat getShortcutInfo(final Contact contact) {
+ final var conversation = xmppConnectionService.find(contact);
+ final var uuid = conversation == null ? null : conversation.getUuid();
+ return getShortcutInfo(contact, uuid);
+ }
+
public ShortcutInfoCompat getShortcutInfo(final Contact contact, final String conversation) {
final ShortcutInfoCompat.Builder builder =
new ShortcutInfoCompat.Builder(xmppConnectionService, getShortcutId(contact))
@@ -199,9 +205,7 @@ public class ShortcutService {
public Intent createShortcut(final Contact contact, final boolean legacy) {
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !legacy) {
- final var conversation = xmppConnectionService.find(contact);
- final var uuid = conversation == null ? null : conversation.getUuid();
- final var shortcut = getShortcutInfo(contact, uuid);
+ final var shortcut = getShortcutInfo(contact);
intent =
ShortcutManagerCompat.createShortcutResultIntent(
xmppConnectionService, shortcut);
@@ -2302,6 +2302,7 @@ public class XmppConnectionService extends Service {
Config.LOGTAG,
account.getJid().asBareJid() + ": pushing bookmark via Bookmarks 2");
final Element item = mIqGenerator.publishBookmarkItem(bookmark);
+ Log.d(Config.LOGTAG, "publishing: " + item.toString());
pushNodeAndEnforcePublishOptions(
account,
Namespace.BOOKMARKS2,
@@ -2873,6 +2874,7 @@ public class XmppConnectionService extends Service {
existing.getMode() == Conversational.MODE_MULTI,
null));
this.conversations.add(existing);
+ // TODO push bookmark
updateConversationUi();
return existing;
}
@@ -1,9 +1,13 @@
package eu.siacs.conversations.ui;
+import static eu.siacs.conversations.entities.Bookmark.printableValue;
+import static eu.siacs.conversations.utils.StringUtils.changed;
+
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.SpannableStringBuilder;
@@ -14,20 +18,14 @@ import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
-
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import eu.siacs.conversations.Config;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ActivityMucDetailsBinding;
-import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.entities.Bookmark;
import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Conversational;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.MucOptions.User;
import eu.siacs.conversations.services.XmppConnectionService;
@@ -50,14 +48,19 @@ import eu.siacs.conversations.utils.StringUtils;
import eu.siacs.conversations.utils.StylingHelper;
import eu.siacs.conversations.utils.XmppUri;
import eu.siacs.conversations.xmpp.Jid;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
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 class ConferenceDetailsActivity extends XmppActivity
+ implements OnConversationUpdate,
+ OnMucRosterUpdate,
+ XmppConnectionService.OnAffiliationChanged,
+ XmppConnectionService.OnConfigurationPushed,
+ XmppConnectionService.OnRoomDestroy,
+ TextWatcher,
+ OnMediaLoaded {
public static final String ACTION_VIEW_MUC = "view_muc";
private Conversation mConversation;
@@ -68,26 +71,25 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
private boolean mAdvancedMode = false;
- private final UiCallback<Conversation> renameCallback = new UiCallback<Conversation>() {
- @Override
- public void success(Conversation object) {
- displayToast(getString(R.string.your_nick_has_been_changed));
- runOnUiThread(() -> {
- updateView();
- });
-
- }
-
- @Override
- public void error(final int errorCode, Conversation object) {
- displayToast(getString(errorCode));
- }
+ private final UiCallback<Conversation> renameCallback =
+ new UiCallback<Conversation>() {
+ @Override
+ public void success(Conversation object) {
+ displayToast(getString(R.string.your_nick_has_been_changed));
+ runOnUiThread(
+ () -> {
+ updateView();
+ });
+ }
- @Override
- public void userInputRequired(PendingIntent pi, Conversation object) {
+ @Override
+ public void error(final int errorCode, Conversation object) {
+ displayToast(getString(errorCode));
+ }
- }
- };
+ @Override
+ public void userInputRequired(PendingIntent pi, Conversation object) {}
+ };
public static void open(final Activity activity, final Conversation conversation) {
Intent intent = new Intent(activity, ConferenceDetailsActivity.class);
@@ -96,37 +98,45 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
activity.startActivity(intent);
}
- private final OnClickListener mNotifyStatusClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ConferenceDetailsActivity.this);
- builder.setTitle(R.string.pref_notification_settings);
- String[] choices = {
- getString(R.string.notify_on_all_messages),
- getString(R.string.notify_only_when_highlighted),
- getString(R.string.notify_never)
- };
- final AtomicInteger choice;
- if (mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0) == Long.MAX_VALUE) {
- choice = new AtomicInteger(2);
- } else {
- choice = new AtomicInteger(mConversation.alwaysNotify() ? 0 : 1);
- }
- builder.setSingleChoiceItems(choices, choice.get(), (dialog, which) -> choice.set(which));
- builder.setNegativeButton(R.string.cancel, null);
- builder.setPositiveButton(R.string.ok, (dialog, which) -> {
- if (choice.get() == 2) {
- mConversation.setMutedTill(Long.MAX_VALUE);
- } else {
- mConversation.setMutedTill(0);
- mConversation.setAttribute(Conversation.ATTRIBUTE_ALWAYS_NOTIFY, String.valueOf(choice.get() == 0));
+ private final OnClickListener mNotifyStatusClickListener =
+ new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final MaterialAlertDialogBuilder builder =
+ new MaterialAlertDialogBuilder(ConferenceDetailsActivity.this);
+ builder.setTitle(R.string.pref_notification_settings);
+ String[] choices = {
+ getString(R.string.notify_on_all_messages),
+ getString(R.string.notify_only_when_highlighted),
+ getString(R.string.notify_never)
+ };
+ final AtomicInteger choice;
+ if (mConversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0)
+ == Long.MAX_VALUE) {
+ choice = new AtomicInteger(2);
+ } else {
+ choice = new AtomicInteger(mConversation.alwaysNotify() ? 0 : 1);
+ }
+ builder.setSingleChoiceItems(
+ choices, choice.get(), (dialog, which) -> choice.set(which));
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setPositiveButton(
+ R.string.ok,
+ (dialog, which) -> {
+ if (choice.get() == 2) {
+ mConversation.setMutedTill(Long.MAX_VALUE);
+ } else {
+ mConversation.setMutedTill(0);
+ mConversation.setAttribute(
+ Conversation.ATTRIBUTE_ALWAYS_NOTIFY,
+ String.valueOf(choice.get() == 0));
+ }
+ xmppConnectionService.updateConversation(mConversation);
+ updateView();
+ });
+ builder.create().show();
}
- xmppConnectionService.updateConversation(mConversation);
- updateView();
- });
- builder.create().show();
- }
- };
+ };
private final OnClickListener mChangeConferenceSettings =
new OnClickListener() {
@@ -185,37 +195,56 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.changeConferenceButton.setOnClickListener(this.mChangeConferenceSettings);
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
- this.binding.editNickButton.setOnClickListener(v -> quickEdit(mConversation.getMucOptions().getActualNick(),
- R.string.nickname,
- value -> {
- if (xmppConnectionService.renameInMuc(mConversation, value, renameCallback)) {
- return null;
- } else {
- return getString(R.string.invalid_muc_nick);
- }
- }));
+ this.binding.editNickButton.setOnClickListener(
+ v ->
+ quickEdit(
+ mConversation.getMucOptions().getActualNick(),
+ R.string.nickname,
+ value -> {
+ if (xmppConnectionService.renameInMuc(
+ mConversation, value, renameCallback)) {
+ return null;
+ } else {
+ return getString(R.string.invalid_muc_nick);
+ }
+ }));
this.mAdvancedMode = getPreferences().getBoolean("advanced_muc_mode", false);
this.binding.mucInfoMore.setVisibility(this.mAdvancedMode ? View.VISIBLE : View.GONE);
this.binding.notificationStatusButton.setOnClickListener(this.mNotifyStatusClickListener);
- this.binding.yourPhoto.setOnClickListener(v -> {
- final MucOptions mucOptions = mConversation.getMucOptions();
- if (!mucOptions.hasVCards()) {
- Toast.makeText(this, R.string.host_does_not_support_group_chat_avatars, Toast.LENGTH_SHORT).show();
- return;
- }
- if (!mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
- Toast.makeText(this, R.string.only_the_owner_can_change_group_chat_avatar, Toast.LENGTH_SHORT).show();
- return;
- }
- final Intent intent = new Intent(this, PublishGroupChatProfilePictureActivity.class);
- intent.putExtra("uuid", mConversation.getUuid());
- startActivity(intent);
- });
- this.binding.editMucNameButton.setContentDescription(getString(R.string.edit_name_and_topic));
+ this.binding.yourPhoto.setOnClickListener(
+ v -> {
+ final MucOptions mucOptions = mConversation.getMucOptions();
+ if (!mucOptions.hasVCards()) {
+ Toast.makeText(
+ this,
+ R.string.host_does_not_support_group_chat_avatars,
+ Toast.LENGTH_SHORT)
+ .show();
+ return;
+ }
+ if (!mucOptions
+ .getSelf()
+ .getAffiliation()
+ .ranks(MucOptions.Affiliation.OWNER)) {
+ Toast.makeText(
+ this,
+ R.string.only_the_owner_can_change_group_chat_avatar,
+ Toast.LENGTH_SHORT)
+ .show();
+ return;
+ }
+ final Intent intent =
+ new Intent(this, PublishGroupChatProfilePictureActivity.class);
+ intent.putExtra("uuid", mConversation.getUuid());
+ startActivity(intent);
+ });
+ this.binding.editMucNameButton.setContentDescription(
+ getString(R.string.edit_name_and_topic));
this.binding.editMucNameButton.setOnClickListener(this::onMucEditButtonClicked);
this.binding.mucEditTitle.addTextChangedListener(this);
this.binding.mucEditSubject.addTextChangedListener(this);
- this.binding.mucEditSubject.addTextChangedListener(new StylingHelper.MessageEditorStyler(this.binding.mucEditSubject));
+ this.binding.mucEditSubject.addTextChangedListener(
+ new StylingHelper.MessageEditorStyler(this.binding.mucEditSubject));
this.mMediaAdapter = new MediaAdapter(this, R.dimen.media_size);
this.mUserPreviewAdapter = new UserPreviewAdapter();
this.binding.media.setAdapter(mMediaAdapter);
@@ -223,17 +252,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
GridManager.setupLayoutManager(this, this.binding.media, R.dimen.media_size);
GridManager.setupLayoutManager(this, this.binding.users, R.dimen.media_size);
this.binding.invite.setOnClickListener(v -> inviteToConversation(mConversation));
- this.binding.showUsers.setOnClickListener(v -> {
- Intent intent = new Intent(this, MucUsersActivity.class);
- intent.putExtra("uuid", mConversation.getUuid());
- startActivity(intent);
- });
+ this.binding.showUsers.setOnClickListener(
+ v -> {
+ Intent intent = new Intent(this, MucUsersActivity.class);
+ intent.putExtra("uuid", mConversation.getUuid());
+ startActivity(intent);
+ });
}
@Override
public void onStart() {
super.onStart();
- binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
+ binding.mediaWrapper.setVisibility(
+ Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
}
@Override
@@ -261,23 +292,43 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.mAdvancedMode = !menuItem.isChecked();
menuItem.setChecked(this.mAdvancedMode);
getPreferences().edit().putBoolean("advanced_muc_mode", mAdvancedMode).apply();
- final boolean online = mConversation != null && mConversation.getMucOptions().online();
- this.binding.mucInfoMore.setVisibility(this.mAdvancedMode && online ? View.VISIBLE : View.GONE);
+ final boolean online =
+ mConversation != null && mConversation.getMucOptions().online();
+ this.binding.mucInfoMore.setVisibility(
+ this.mAdvancedMode && online ? View.VISIBLE : View.GONE);
invalidateOptionsMenu();
updateView();
break;
+ case R.id.action_custom_notifications:
+ if (mConversation != null) {
+ configureCustomNotifications(mConversation);
+ }
+ break;
}
return super.onOptionsItemSelected(menuItem);
}
+ private void configureCustomNotifications(final Conversation conversation) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R
+ || conversation.getMode() != Conversational.MODE_MULTI) {
+ return;
+ }
+ final var shortcut =
+ xmppConnectionService
+ .getShortcutService()
+ .getShortcutInfo(conversation.getMucOptions());
+ configureCustomNotification(shortcut);
+ }
+
@Override
- public boolean onContextItemSelected(MenuItem item) {
+ public boolean onContextItemSelected(@NonNull final MenuItem item) {
final User user = mUserPreviewAdapter.getSelectedUser();
if (user == null) {
Toast.makeText(this, R.string.unable_to_perform_this_action, Toast.LENGTH_SHORT).show();
return true;
}
- if (!MucDetailsContextMenuHelper.onContextItemSelected(item, mUserPreviewAdapter.getSelectedUser(), this)) {
+ if (!MucDetailsContextMenuHelper.onContextItemSelected(
+ item, mUserPreviewAdapter.getSelectedUser(), this)) {
return super.onContextItemSelected(item);
}
return true;
@@ -292,7 +343,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.editMucNameButton.setContentDescription(getString(R.string.cancel));
final String name = mucOptions.getName();
this.binding.mucEditTitle.setText("");
- final boolean owner = mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER);
+ final boolean owner =
+ mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER);
if (owner || printableValue(name)) {
this.binding.mucEditTitle.setVisibility(View.VISIBLE);
if (name != null) {
@@ -312,8 +364,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.mucEditSubject.requestFocus();
}
} else {
- String subject = this.binding.mucEditSubject.isEnabled() ? this.binding.mucEditSubject.getEditableText().toString().trim() : null;
- String name = this.binding.mucEditTitle.isEnabled() ? this.binding.mucEditTitle.getEditableText().toString().trim() : null;
+ String subject =
+ this.binding.mucEditSubject.isEnabled()
+ ? this.binding.mucEditSubject.getEditableText().toString().trim()
+ : null;
+ String name =
+ this.binding.mucEditTitle.isEnabled()
+ ? this.binding.mucEditTitle.getEditableText().toString().trim()
+ : null;
onMucInfoUpdated(subject, name);
SoftKeyboardUtils.hideSoftKeyboard(this);
hideEditor();
@@ -324,7 +382,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.mucEditor.setVisibility(View.GONE);
this.binding.mucDisplay.setVisibility(View.VISIBLE);
this.binding.editMucNameButton.setImageResource(R.drawable.ic_edit_24dp);
- this.binding.editMucNameButton.setContentDescription(getString(R.string.edit_name_and_topic));
+ this.binding.editMucNameButton.setContentDescription(
+ getString(R.string.edit_name_and_topic));
}
private void onMucInfoUpdated(String subject, String name) {
@@ -332,7 +391,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
if (mucOptions.canChangeSubject() && changed(mucOptions.getSubject(), subject)) {
xmppConnectionService.pushSubjectToConference(mConversation, subject);
}
- if (mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER) && changed(mucOptions.getName(), name)) {
+ if (mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER)
+ && changed(mucOptions.getName(), name)) {
Bundle options = new Bundle();
options.putString("muc#roomconfig_persistentroom", "1");
options.putString("muc#roomconfig_roomname", StringUtils.nullOnEmpty(name));
@@ -340,12 +400,13 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
}
-
@Override
protected String getShareableUri(boolean http) {
if (mConversation != null) {
if (http) {
- return "https://conversations.im/j/" + XmppUri.lameUrlEncode(mConversation.getJid().asBareJid().toEscapedString());
+ return "https://conversations.im/j/"
+ + XmppUri.lameUrlEncode(
+ mConversation.getJid().asBareJid().toEscapedString());
} else {
return "xmpp:" + mConversation.getJid().asBareJid() + "?join";
}
@@ -364,7 +425,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
return true;
}
menuItemSaveBookmark.setVisible(mConversation.getBookmark() == null);
- menuItemDestroyRoom.setVisible(mConversation.getMucOptions().getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER));
+ menuItemDestroyRoom.setVisible(
+ mConversation
+ .getMucOptions()
+ .getSelf()
+ .getAffiliation()
+ .ranks(MucOptions.Affiliation.OWNER));
return true;
}
@@ -377,32 +443,40 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
final MenuItem destroy = menu.findItem(R.id.action_destroy_room);
destroy.setTitle(groupChat ? R.string.destroy_room : R.string.destroy_channel);
AccountUtils.showHideMenuItems(menu);
+ final MenuItem customNotifications = menu.findItem(R.id.action_custom_notifications);
+ customNotifications.setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R);
return super.onCreateOptionsMenu(menu);
}
@Override
- public void onMediaLoaded(List<Attachment> attachments) {
- runOnUiThread(() -> {
- int limit = GridManager.getCurrentColumnCount(binding.media);
- mMediaAdapter.setAttachments(attachments.subList(0, Math.min(limit, attachments.size())));
- binding.mediaWrapper.setVisibility(attachments.size() > 0 ? View.VISIBLE : View.GONE);
- });
-
+ public void onMediaLoaded(final List<Attachment> attachments) {
+ runOnUiThread(
+ () -> {
+ final int limit = GridManager.getCurrentColumnCount(binding.media);
+ mMediaAdapter.setAttachments(
+ attachments.subList(0, Math.min(limit, attachments.size())));
+ binding.mediaWrapper.setVisibility(
+ attachments.isEmpty() ? View.GONE : View.VISIBLE);
+ });
}
-
protected void saveAsBookmark() {
- xmppConnectionService.saveConversationAsBookmark(mConversation, mConversation.getMucOptions().getName());
+ xmppConnectionService.saveConversationAsBookmark(
+ mConversation, mConversation.getMucOptions().getName());
}
protected void destroyRoom() {
final boolean groupChat = mConversation != null && mConversation.isPrivateAndNonAnonymous();
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) -> {
- xmppConnectionService.destroyRoom(mConversation, ConferenceDetailsActivity.this);
- });
+ builder.setMessage(
+ groupChat ? R.string.destroy_room_dialog : R.string.destroy_channel_dialog);
+ builder.setPositiveButton(
+ R.string.ok,
+ (dialog, which) -> {
+ xmppConnectionService.destroyRoom(
+ mConversation, ConferenceDetailsActivity.this);
+ });
builder.setNegativeButton(R.string.cancel, null);
final AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
@@ -424,7 +498,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
if (Compatibility.hasStoragePermission(this)) {
final int limit = GridManager.getCurrentColumnCount(this.binding.media);
xmppConnectionService.getAttachments(this.mConversation, limit, this);
- this.binding.showMedia.setOnClickListener((v) -> MediaBrowserActivity.launch(this, mConversation));
+ this.binding.showMedia.setOnClickListener(
+ (v) -> MediaBrowserActivity.launch(this, mConversation));
}
updateView();
}
@@ -448,15 +523,24 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
final MucOptions mucOptions = mConversation.getMucOptions();
final User self = mucOptions.getSelf();
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);
+ 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));
if (mConversation.isPrivateAndNonAnonymous()) {
- this.binding.jid.setText(getString(R.string.hosted_on, mConversation.getJid().getDomain()));
+ this.binding.jid.setText(
+ getString(R.string.hosted_on, mConversation.getJid().getDomain()));
} else {
this.binding.jid.setText(mConversation.getJid().asBareJid().toEscapedString());
}
- AvatarWorkerTask.loadAvatar(mConversation, binding.yourPhoto, R.dimen.avatar_on_details_screen_size);
+ AvatarWorkerTask.loadAvatar(
+ mConversation, binding.yourPhoto, R.dimen.avatar_on_details_screen_size);
String roomName = mucOptions.getName();
String subject = mucOptions.getSubject();
final boolean hasTitle;
@@ -477,7 +561,12 @@ 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( 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.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());
@@ -495,7 +584,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
this.binding.mucConferenceType.setText(MucConfiguration.describe(this, mucOptions));
} else if (!mucOptions.isPrivateAndNonAnonymous() && mucOptions.nonanonymous()) {
this.binding.mucSettings.setVisibility(View.VISIBLE);
- this.binding.mucConferenceType.setText(R.string.group_chat_will_make_your_jabber_id_public);
+ this.binding.mucConferenceType.setText(
+ R.string.group_chat_will_make_your_jabber_id_public);
} else {
this.binding.mucSettings.setVisibility(View.GONE);
}
@@ -518,50 +608,64 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
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(R.drawable.ic_notifications_off_24dp);
+ 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(R.drawable.ic_notifications_paused_24dp);
+ 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(R.drawable.ic_notifications_24dp);
+ this.binding.notificationStatusButton.setImageResource(
+ R.drawable.ic_notifications_24dp);
} else {
this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted);
- this.binding.notificationStatusButton.setImageResource(R.drawable.ic_notifications_none_24dp);
+ this.binding.notificationStatusButton.setImageResource(
+ R.drawable.ic_notifications_none_24dp);
}
final List<User> users = mucOptions.getUsers();
- Collections.sort(users, (a, b) -> {
- if (b.getAffiliation().outranks(a.getAffiliation())) {
- return 1;
- } else if (a.getAffiliation().outranks(b.getAffiliation())) {
- return -1;
- } else {
- if (a.getAvatar() != null && b.getAvatar() == null) {
- return -1;
- } else if (a.getAvatar() == null && b.getAvatar() != null) {
- return 1;
- } else {
- return a.getComparableName().compareToIgnoreCase(b.getComparableName());
- }
- }
- });
- this.mUserPreviewAdapter.submitList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
+ Collections.sort(
+ users,
+ (a, b) -> {
+ if (b.getAffiliation().outranks(a.getAffiliation())) {
+ return 1;
+ } else if (a.getAffiliation().outranks(b.getAffiliation())) {
+ return -1;
+ } else {
+ if (a.getAvatar() != null && b.getAvatar() == null) {
+ return -1;
+ } else if (a.getAvatar() == null && b.getAvatar() != null) {
+ return 1;
+ } else {
+ return a.getComparableName().compareToIgnoreCase(b.getComparableName());
+ }
+ }
+ });
+ this.mUserPreviewAdapter.submitList(
+ MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
this.binding.invite.setVisibility(mucOptions.canInvite() ? View.VISIBLE : View.GONE);
this.binding.showUsers.setVisibility(users.size() > 0 ? View.VISIBLE : View.GONE);
- this.binding.showUsers.setText(getResources().getQuantityString(R.plurals.view_users, users.size(), users.size()));
- this.binding.usersWrapper.setVisibility(users.size() > 0 || mucOptions.canInvite() ? View.VISIBLE : View.GONE);
+ this.binding.showUsers.setText(
+ getResources().getQuantityString(R.plurals.view_users, users.size(), users.size()));
+ this.binding.usersWrapper.setVisibility(
+ users.size() > 0 || mucOptions.canInvite() ? View.VISIBLE : View.GONE);
if (users.size() == 0) {
- this.binding.noUsersHints.setText(mucOptions.isPrivateAndNonAnonymous() ? R.string.no_users_hint_group_chat : R.string.no_users_hint_channel);
+ this.binding.noUsersHints.setText(
+ mucOptions.isPrivateAndNonAnonymous()
+ ? R.string.no_users_hint_group_chat
+ : R.string.no_users_hint_channel);
this.binding.noUsersHints.setVisibility(View.VISIBLE);
} else {
this.binding.noUsersHints.setVisibility(View.GONE);
}
-
}
public static String getStatus(Context context, User user, final boolean advanced) {
if (advanced) {
- return String.format("%s (%s)", context.getString(user.getAffiliation().getResId()), context.getString(user.getRole().getResId()));
+ return String.format(
+ "%s (%s)",
+ context.getString(user.getAffiliation().getResId()),
+ context.getString(user.getRole().getResId()));
} else {
return context.getString(user.getAffiliation().getResId());
}
@@ -571,7 +675,6 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
return getStatus(this, user, mAdvancedMode);
}
-
@Override
public void onAffiliationChangedSuccessful(Jid jid) {
refreshUi();
@@ -590,7 +693,11 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
@Override
public void onRoomDestroyFailed() {
final boolean groupChat = mConversation != null && mConversation.isPrivateAndNonAnonymous();
- displayToast(getString(groupChat ? R.string.could_not_destroy_room : R.string.could_not_destroy_channel));
+ displayToast(
+ getString(
+ groupChat
+ ? R.string.could_not_destroy_room
+ : R.string.could_not_destroy_channel));
}
@Override
@@ -604,23 +711,20 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
private void displayToast(final String msg) {
- runOnUiThread(() -> {
- if (isFinishing()) {
- return;
- }
- ToastCompat.makeText(this, msg, Toast.LENGTH_SHORT).show();
- });
+ runOnUiThread(
+ () -> {
+ if (isFinishing()) {
+ return;
+ }
+ ToastCompat.makeText(this, msg, Toast.LENGTH_SHORT).show();
+ });
}
@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(Editable s) {
@@ -629,8 +733,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
final MucOptions mucOptions = mConversation.getMucOptions();
if (this.binding.mucEditor.getVisibility() == View.VISIBLE) {
- boolean subjectChanged = changed(binding.mucEditSubject.getEditableText().toString(), mucOptions.getSubject());
- boolean nameChanged = changed(binding.mucEditTitle.getEditableText().toString(), mucOptions.getName());
+ 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(R.drawable.ic_save_24dp);
this.binding.editMucNameButton.setContentDescription(getString(R.string.save));
@@ -640,5 +750,4 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
}
}
-
}
@@ -26,23 +26,14 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;
-
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.databinding.DataBindingUtil;
-
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
-
-import org.openintents.openpgp.util.OpenPgpUtils;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
import eu.siacs.conversations.AppSettings;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
@@ -78,48 +69,72 @@ import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.XmppConnection;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.openintents.openpgp.util.OpenPgpUtils;
-public class ContactDetailsActivity extends OmemoActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated, OnMediaLoaded {
+public class ContactDetailsActivity extends OmemoActivity
+ implements OnAccountUpdate,
+ OnRosterUpdate,
+ OnUpdateBlocklist,
+ OnKeyStatusUpdated,
+ OnMediaLoaded {
public static final String ACTION_VIEW_CONTACT = "view_contact";
private final int REQUEST_SYNC_CONTACTS = 0x28cf;
ActivityContactDetailsBinding binding;
private MediaAdapter mMediaAdapter;
private Contact contact;
- private final DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() {
+ private final DialogInterface.OnClickListener removeFromRoster =
+ new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- xmppConnectionService.deleteContactOnServer(contact);
- }
- };
- private final OnCheckedChangeListener mOnSendCheckedChange = new OnCheckedChangeListener() {
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
- xmppConnectionService.stopPresenceUpdatesTo(contact);
- } else {
- contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ xmppConnectionService.deleteContactOnServer(contact);
}
- } else {
- contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
- xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.getPresenceGenerator().stopPresenceUpdatesTo(contact));
- }
- }
- };
- private final OnCheckedChangeListener mOnReceiveCheckedChange = new OnCheckedChangeListener() {
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.getPresenceGenerator().requestPresenceUpdatesFrom(contact));
- } else {
- xmppConnectionService.sendPresencePacket(contact.getAccount(), xmppConnectionService.getPresenceGenerator().stopPresenceUpdatesFrom(contact));
- }
- }
- };
+ };
+ private final OnCheckedChangeListener mOnSendCheckedChange =
+ new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
+ xmppConnectionService.stopPresenceUpdatesTo(contact);
+ } else {
+ contact.setOption(Contact.Options.PREEMPTIVE_GRANT);
+ }
+ } else {
+ contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
+ xmppConnectionService.sendPresencePacket(
+ contact.getAccount(),
+ xmppConnectionService
+ .getPresenceGenerator()
+ .stopPresenceUpdatesTo(contact));
+ }
+ }
+ };
+ private final OnCheckedChangeListener mOnReceiveCheckedChange =
+ new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ xmppConnectionService.sendPresencePacket(
+ contact.getAccount(),
+ xmppConnectionService
+ .getPresenceGenerator()
+ .requestPresenceUpdatesFrom(contact));
+ } else {
+ xmppConnectionService.sendPresencePacket(
+ contact.getAccount(),
+ xmppConnectionService
+ .getPresenceGenerator()
+ .stopPresenceUpdatesFrom(contact));
+ }
+ }
+ };
private Jid accountJid;
private Jid contactJid;
private boolean showDynamicTags = false;
@@ -130,14 +145,18 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
private void checkContactPermissionAndShowAddDialog() {
if (hasContactsPermission()) {
showAddToPhoneBookDialog();
- } else if (QuickConversationsService.isContactListIntegration(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
+ } else if (QuickConversationsService.isContactListIntegration(this)
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ requestPermissions(
+ new String[] {Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS);
}
}
private boolean hasContactsPermission() {
- if (QuickConversationsService.isContactListIntegration(this) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
+ if (QuickConversationsService.isContactListIntegration(this)
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ return checkSelfPermission(Manifest.permission.READ_CONTACTS)
+ == PackageManager.PERMISSION_GRANTED;
} else {
return true;
}
@@ -145,9 +164,10 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
private void showAddToPhoneBookDialog() {
final Jid jid = contact.getJid();
- final boolean quicksyContact = AbstractQuickConversationsService.isQuicksy()
- && Config.QUICKSY_DOMAIN.equals(jid.getDomain())
- && jid.getLocal() != null;
+ final boolean quicksyContact =
+ AbstractQuickConversationsService.isQuicksy()
+ && Config.QUICKSY_DOMAIN.equals(jid.getDomain())
+ && jid.getLocal() != null;
final String value;
if (quicksyContact) {
value = PhoneNumberUtilWrapper.toFormattedPhoneNumber(this, jid);
@@ -158,24 +178,33 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
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);
- builder.setPositiveButton(getString(R.string.add), (dialog, which) -> {
- final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
- intent.setType(Contacts.CONTENT_ITEM_TYPE);
- if (quicksyContact) {
- intent.putExtra(Intents.Insert.PHONE, value);
- } else {
- intent.putExtra(Intents.Insert.IM_HANDLE, value);
- intent.putExtra(Intents.Insert.IM_PROTOCOL, CommonDataKinds.Im.PROTOCOL_JABBER);
- //TODO for modern use we want PROTOCOL_CUSTOM and an extra field with a value of 'XMPP'
- // however we don’t have such a field and thus have to use the legacy PROTOCOL_JABBER
- }
- intent.putExtra("finishActivityOnSaveCompleted", true);
- try {
- startActivityForResult(intent, 0);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(ContactDetailsActivity.this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show();
- }
- });
+ builder.setPositiveButton(
+ getString(R.string.add),
+ (dialog, which) -> {
+ final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+ intent.setType(Contacts.CONTENT_ITEM_TYPE);
+ if (quicksyContact) {
+ intent.putExtra(Intents.Insert.PHONE, value);
+ } else {
+ intent.putExtra(Intents.Insert.IM_HANDLE, value);
+ intent.putExtra(
+ Intents.Insert.IM_PROTOCOL, CommonDataKinds.Im.PROTOCOL_JABBER);
+ // TODO for modern use we want PROTOCOL_CUSTOM and an extra field with a
+ // value of 'XMPP'
+ // however we don’t have such a field and thus have to use the legacy
+ // PROTOCOL_JABBER
+ }
+ intent.putExtra("finishActivityOnSaveCompleted", true);
+ try {
+ startActivityForResult(intent, 0);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(
+ ContactDetailsActivity.this,
+ R.string.no_application_found_to_view_contact,
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ });
builder.create().show();
}
@@ -203,7 +232,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override
protected String getShareableUri(boolean http) {
if (http) {
- return "https://conversations.im/i/" + XmppUri.lameUrlEncode(contact.getJid().asBareJid().toEscapedString());
+ return "https://conversations.im/i/"
+ + XmppUri.lameUrlEncode(contact.getJid().asBareJid().toEscapedString());
} else {
return "xmpp:" + contact.getJid().asBareJid().toEscapedString();
}
@@ -212,7 +242,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- showInactiveOmemo = savedInstanceState != null && savedInstanceState.getBoolean("show_inactive_omemo", false);
+ showInactiveOmemo =
+ savedInstanceState != null
+ && savedInstanceState.getBoolean("show_inactive_omemo", false);
if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
try {
this.accountJid = Jid.ofEscaped(getIntent().getExtras().getString(EXTRA_ACCOUNT));
@@ -229,10 +261,11 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
setSupportActionBar(binding.toolbar);
configureActionBar(getSupportActionBar());
- binding.showInactiveDevices.setOnClickListener(v -> {
- showInactiveOmemo = !showInactiveOmemo;
- populateView();
- });
+ binding.showInactiveDevices.setOnClickListener(
+ v -> {
+ showInactiveOmemo = !showInactiveOmemo;
+ populateView();
+ });
binding.addContactButton.setOnClickListener(v -> showAddToRosterDialog(contact));
mMediaAdapter = new MediaAdapter(this, R.dimen.media_size);
@@ -252,12 +285,14 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
this.showDynamicTags = preferences.getBoolean(AppSettings.SHOW_DYNAMIC_TAGS, false);
this.showLastSeen = preferences.getBoolean("last_activity", false);
- binding.mediaWrapper.setVisibility(Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
+ binding.mediaWrapper.setVisibility(
+ Compatibility.hasStoragePermission(this) ? View.VISIBLE : View.GONE);
mMediaAdapter.setAttachments(Collections.emptyList());
}
@Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(
+ int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// TODO check for Camera / Scan permission
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0)
@@ -289,19 +324,29 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
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),
- removeFromRoster).create().show();
+ .setMessage(
+ JidDialog.style(
+ this,
+ R.string.remove_contact_text,
+ contact.getJid().toEscapedString()))
+ .setPositiveButton(getString(R.string.delete), removeFromRoster)
+ .create()
+ .show();
break;
case R.id.action_edit_contact:
- Uri systemAccount = contact.getSystemAccount();
+ final Uri systemAccount = contact.getSystemAccount();
if (systemAccount == null) {
- quickEdit(contact.getServerName(), R.string.contact_name, value -> {
- contact.setServerName(value);
- ContactDetailsActivity.this.xmppConnectionService.pushContactToServer(contact);
- populateView();
- return null;
- }, true);
+ quickEdit(
+ contact.getServerName(),
+ R.string.contact_name,
+ value -> {
+ contact.setServerName(value);
+ ContactDetailsActivity.this.xmppConnectionService
+ .pushContactToServer(contact);
+ populateView();
+ return null;
+ },
+ true);
} else {
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setDataAndType(systemAccount, Contacts.CONTENT_ITEM_TYPE);
@@ -309,29 +354,42 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
- Toast.makeText(ContactDetailsActivity.this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show();
+ Toast.makeText(
+ ContactDetailsActivity.this,
+ R.string.no_application_found_to_view_contact,
+ Toast.LENGTH_SHORT)
+ .show();
}
-
}
break;
- case R.id.action_block:
+ case R.id.action_block, R.id.action_unblock:
BlockContactDialog.show(this, contact);
break;
- case R.id.action_unblock:
- BlockContactDialog.show(this, contact);
+ case R.id.action_custom_notifications:
+ configureCustomNotifications(contact);
break;
}
return super.onOptionsItemSelected(menuItem);
}
+ private void configureCustomNotifications(final Contact contact) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return;
+ }
+ final var shortcut = xmppConnectionService.getShortcutService().getShortcutInfo(contact);
+ configureCustomNotification(shortcut);
+ }
+
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.contact_details, menu);
AccountUtils.showHideMenuItems(menu);
- MenuItem block = menu.findItem(R.id.action_block);
- MenuItem unblock = menu.findItem(R.id.action_unblock);
- MenuItem edit = menu.findItem(R.id.action_edit_contact);
- MenuItem delete = menu.findItem(R.id.action_delete_contact);
+ final MenuItem block = menu.findItem(R.id.action_block);
+ final MenuItem unblock = menu.findItem(R.id.action_unblock);
+ final MenuItem edit = menu.findItem(R.id.action_edit_contact);
+ final MenuItem delete = menu.findItem(R.id.action_delete_contact);
+ final MenuItem customNotifications = menu.findItem(R.id.action_custom_notifications);
+ customNotifications.setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R);
if (contact == null) {
return true;
}
@@ -374,7 +432,11 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
binding.statusMessage.setVisibility(View.VISIBLE);
final Spannable span = new SpannableString(message);
if (Emoticons.isOnlyEmoji(message)) {
- span.setSpan(new RelativeSizeSpan(2.0f), 0, message.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ span.setSpan(
+ new RelativeSizeSpan(2.0f),
+ 0,
+ message.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
binding.statusMessage.setText(span);
} else {
@@ -398,14 +460,16 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
binding.detailsSendPresence.setText(R.string.send_presence_updates);
} else {
binding.detailsSendPresence.setText(R.string.preemptively_grant);
- binding.detailsSendPresence.setChecked(contact.getOption(Contact.Options.PREEMPTIVE_GRANT));
+ binding.detailsSendPresence.setChecked(
+ contact.getOption(Contact.Options.PREEMPTIVE_GRANT));
}
if (contact.getOption(Contact.Options.TO)) {
binding.detailsReceivePresence.setText(R.string.receive_presence_updates);
binding.detailsReceivePresence.setChecked(true);
} else {
binding.detailsReceivePresence.setText(R.string.ask_for_presence_updates);
- binding.detailsReceivePresence.setChecked(contact.getOption(Contact.Options.ASKING));
+ binding.detailsReceivePresence.setChecked(
+ contact.getOption(Contact.Options.ASKING));
}
if (contact.getAccount().isOnlineAndConnected()) {
binding.detailsReceivePresence.setEnabled(true);
@@ -431,7 +495,11 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
&& contact.getLastseen() > 0
&& contact.getPresences().allOrNonSupport(Namespace.IDLE)) {
binding.detailsLastseen.setVisibility(View.VISIBLE);
- binding.detailsLastseen.setText(UIHelper.lastseen(getApplicationContext(), contact.isActive(), contact.getLastseen()));
+ binding.detailsLastseen.setText(
+ UIHelper.lastseen(
+ getApplicationContext(),
+ contact.isActive(),
+ contact.getLastseen()));
} else {
binding.detailsLastseen.setVisibility(View.GONE);
}
@@ -440,7 +508,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
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);
+ AvatarWorkerTask.loadAvatar(
+ contact, binding.detailsContactBadge, R.dimen.avatar_on_details_screen_size);
binding.detailsContactBadge.setOnClickListener(this::onBadgeClick);
binding.detailsContactKeys.removeAllViews();
@@ -448,7 +517,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
final LayoutInflater inflater = getLayoutInflater();
final AxolotlService axolotlService = contact.getAccount().getAxolotlService();
if (Config.supportOmemo() && axolotlService != null) {
- final Collection<XmppAxolotlSession> sessions = axolotlService.findSessionsForContact(contact);
+ final Collection<XmppAxolotlSession> sessions =
+ axolotlService.findSessionsForContact(contact);
boolean anyActive = false;
for (XmppAxolotlSession session : sessions) {
anyActive = session.getTrust().isActive();
@@ -478,9 +548,13 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
showUnverifiedWarning = true;
}
}
- binding.unverifiedWarning.setVisibility(showUnverifiedWarning ? View.VISIBLE : View.GONE);
+ binding.unverifiedWarning.setVisibility(
+ showUnverifiedWarning ? View.VISIBLE : View.GONE);
if (showsInactive || skippedInactive) {
- binding.showInactiveDevices.setText(showsInactive ? R.string.hide_inactive_devices : R.string.show_inactive_devices);
+ binding.showInactiveDevices.setText(
+ showsInactive
+ ? R.string.hide_inactive_devices
+ : R.string.show_inactive_devices);
binding.showInactiveDevices.setVisibility(View.VISIBLE);
} else {
binding.showInactiveDevices.setVisibility(View.GONE);
@@ -489,7 +563,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
binding.showInactiveDevices.setVisibility(View.GONE);
}
final boolean isCameraFeatureAvailable = isCameraFeatureAvailable();
- binding.scanButton.setVisibility(hasKeys && isCameraFeatureAvailable ? View.VISIBLE : View.GONE);
+ binding.scanButton.setVisibility(
+ hasKeys && isCameraFeatureAvailable ? View.VISIBLE : View.GONE);
if (hasKeys) {
binding.scanButton.setOnClickListener((v) -> ScanActivity.scan(this));
}
@@ -500,7 +575,9 @@ 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.setTextColor(MaterialColors.getColor(keyType, com.google.android.material.R.attr.colorPrimaryVariant));
+ 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());
@@ -512,7 +589,8 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
binding.keysWrapper.setVisibility(hasKeys ? View.VISIBLE : View.GONE);
final List<ListItem.Tag> tagList = contact.getTags(this);
- final boolean hasMetaTags = contact.isBlocked() || contact.getShownStatus() != Presence.Status.OFFLINE;
+ final boolean hasMetaTags =
+ contact.isBlocked() || contact.getShownStatus() != Presence.Status.OFFLINE;
if ((tagList.isEmpty() && !hasMetaTags) || !this.showDynamicTags) {
binding.tags.setVisibility(View.GONE);
} else {
@@ -521,9 +599,13 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
final ImmutableList.Builder<Integer> viewIdBuilder = new ImmutableList.Builder<>();
for (final ListItem.Tag tag : tagList) {
final String name = tag.getName();
- final TextView tv = (TextView) inflater.inflate(R.layout.item_tag, binding.tags, false);
+ final TextView tv =
+ (TextView) inflater.inflate(R.layout.item_tag, binding.tags, false);
tv.setText(name);
- tv.setBackgroundTintList(ColorStateList.valueOf(MaterialColors.harmonizeWithPrimary(this,XEP0392Helper.rgbFromNick(name))));
+ tv.setBackgroundTintList(
+ ColorStateList.valueOf(
+ MaterialColors.harmonizeWithPrimary(
+ this, XEP0392Helper.rgbFromNick(name))));
final int id = ViewCompat.generateViewId();
tv.setId(id);
viewIdBuilder.add(id);
@@ -531,11 +613,14 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
if (contact.isBlocked()) {
final TextView tv =
- (TextView)
- inflater.inflate(
- R.layout.item_tag, binding.tags, false);
+ (TextView) inflater.inflate(R.layout.item_tag, binding.tags, false);
tv.setText(R.string.blocked);
- tv.setBackgroundTintList(ColorStateList.valueOf(MaterialColors.harmonizeWithPrimary(tv.getContext(), ContextCompat.getColor(tv.getContext(),R.color.gray_800))));
+ tv.setBackgroundTintList(
+ ColorStateList.valueOf(
+ MaterialColors.harmonizeWithPrimary(
+ tv.getContext(),
+ ContextCompat.getColor(
+ tv.getContext(), R.color.gray_800))));
final int id = ViewCompat.generateViewId();
tv.setId(id);
viewIdBuilder.add(id);
@@ -544,9 +629,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
final Presence.Status status = contact.getShownStatus();
if (status != Presence.Status.OFFLINE) {
final TextView tv =
- (TextView)
- inflater.inflate(
- R.layout.item_tag, binding.tags, false);
+ (TextView) inflater.inflate(R.layout.item_tag, binding.tags, false);
UIHelper.setStatus(tv, status);
final int id = ViewCompat.generateViewId();
tv.setId(id);
@@ -599,8 +682,10 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
if (Compatibility.hasStoragePermission(this)) {
final int limit = GridManager.getCurrentColumnCount(this.binding.media);
- xmppConnectionService.getAttachments(account, contact.getJid().asBareJid(), limit, this);
- this.binding.showMedia.setOnClickListener((v) -> MediaBrowserActivity.launch(this, contact));
+ xmppConnectionService.getAttachments(
+ account, contact.getJid().asBareJid(), limit, this);
+ this.binding.showMedia.setOnClickListener(
+ (v) -> MediaBrowserActivity.launch(this, contact));
}
populateView();
}
@@ -613,7 +698,9 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override
protected void processFingerprintVerification(XmppUri uri) {
- if (contact != null && contact.getJid().asBareJid().equals(uri.getJid()) && uri.hasFingerprints()) {
+ if (contact != null
+ && contact.getJid().asBareJid().equals(uri.getJid())
+ && uri.hasFingerprints()) {
if (xmppConnectionService.verifyFingerprints(contact, uri.getFingerprints())) {
Toast.makeText(this, R.string.verified_fingerprints, Toast.LENGTH_SHORT).show();
}
@@ -624,11 +711,13 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
@Override
public void onMediaLoaded(List<Attachment> attachments) {
- runOnUiThread(() -> {
- int limit = GridManager.getCurrentColumnCount(binding.media);
- mMediaAdapter.setAttachments(attachments.subList(0, Math.min(limit, attachments.size())));
- binding.mediaWrapper.setVisibility(attachments.size() > 0 ? View.VISIBLE : View.GONE);
- });
-
+ runOnUiThread(
+ () -> {
+ int limit = GridManager.getCurrentColumnCount(binding.media);
+ mMediaAdapter.setAttachments(
+ attachments.subList(0, Math.min(limit, attachments.size())));
+ binding.mediaWrapper.setVisibility(
+ attachments.size() > 0 ? View.VISIBLE : View.GONE);
+ });
}
}
@@ -2,6 +2,7 @@ package eu.siacs.conversations.ui;
import android.Manifest;
import android.annotation.SuppressLint;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
@@ -15,7 +16,6 @@ import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
@@ -31,6 +31,7 @@ import android.os.IBinder;
import android.os.PowerManager;
import android.os.SystemClock;
import android.preference.PreferenceManager;
+import android.provider.Settings;
import android.text.Html;
import android.text.InputType;
import android.util.DisplayMetrics;
@@ -42,19 +43,19 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Toast;
-
import androidx.annotation.BoolRes;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate;
+import androidx.core.content.pm.ShortcutInfoCompat;
+import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.databinding.DataBindingUtil;
-
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
-
import eu.siacs.conversations.AppSettings;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.Config;
@@ -70,6 +71,7 @@ import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.entities.Reaction;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.BarcodeProvider;
+import eu.siacs.conversations.services.NotificationService;
import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
@@ -79,16 +81,13 @@ import eu.siacs.conversations.ui.util.SettingsUtils;
import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
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.xmpp.Jid;
import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
-
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
@@ -112,50 +111,58 @@ public abstract class XmppActivity extends ActionBarActivity {
protected boolean mUsingEnterKey = false;
protected boolean mUseTor = false;
protected Toast mToast;
- public Runnable onOpenPGPKeyPublished = () -> Toast.makeText(XmppActivity.this, R.string.openpgp_has_been_published, Toast.LENGTH_SHORT).show();
+ public Runnable onOpenPGPKeyPublished =
+ () ->
+ Toast.makeText(
+ XmppActivity.this,
+ R.string.openpgp_has_been_published,
+ Toast.LENGTH_SHORT)
+ .show();
protected ConferenceInvite mPendingConferenceInvite = null;
- protected ServiceConnection mConnection = new ServiceConnection() {
+ protected ServiceConnection mConnection =
+ new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- XmppConnectionBinder binder = (XmppConnectionBinder) service;
- xmppConnectionService = binder.getService();
- xmppConnectionServiceBound = true;
- registerListeners();
- onBackendConnected();
- }
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ XmppConnectionBinder binder = (XmppConnectionBinder) service;
+ xmppConnectionService = binder.getService();
+ xmppConnectionServiceBound = true;
+ registerListeners();
+ onBackendConnected();
+ }
- @Override
- public void onServiceDisconnected(ComponentName arg0) {
- xmppConnectionServiceBound = false;
- }
- };
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ xmppConnectionServiceBound = false;
+ }
+ };
private DisplayMetrics metrics;
private long mLastUiRefresh = 0;
private final Handler mRefreshUiHandler = new Handler();
- private final Runnable mRefreshUiRunnable = () -> {
- mLastUiRefresh = SystemClock.elapsedRealtime();
- refreshUiReal();
- };
- private final UiCallback<Conversation> adhocCallback = new UiCallback<Conversation>() {
- @Override
- public void success(final Conversation conversation) {
- runOnUiThread(() -> {
- switchToConversation(conversation);
- hideToast();
- });
- }
-
- @Override
- public void error(final int errorCode, Conversation object) {
- runOnUiThread(() -> replaceToast(getString(errorCode)));
- }
+ private final Runnable mRefreshUiRunnable =
+ () -> {
+ mLastUiRefresh = SystemClock.elapsedRealtime();
+ refreshUiReal();
+ };
+ private final UiCallback<Conversation> adhocCallback =
+ new UiCallback<Conversation>() {
+ @Override
+ public void success(final Conversation conversation) {
+ runOnUiThread(
+ () -> {
+ switchToConversation(conversation);
+ hideToast();
+ });
+ }
- @Override
- public void userInputRequired(PendingIntent pi, Conversation object) {
+ @Override
+ public void error(final int errorCode, Conversation object) {
+ runOnUiThread(() -> replaceToast(getString(errorCode)));
+ }
- }
- };
+ @Override
+ public void userInputRequired(PendingIntent pi, Conversation object) {}
+ };
public static boolean cancelPotentialWork(Message message, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
@@ -212,7 +219,7 @@ public abstract class XmppActivity extends ActionBarActivity {
}
}
- abstract protected void refreshUiReal();
+ protected abstract void refreshUiReal();
@Override
public void onStart() {
@@ -248,6 +255,41 @@ public abstract class XmppActivity extends ActionBarActivity {
}
}
+ @RequiresApi(api = Build.VERSION_CODES.R)
+ protected void configureCustomNotification(final ShortcutInfoCompat shortcut) {
+ final var notificationManager = getSystemService(NotificationManager.class);
+ final var channel =
+ notificationManager.getNotificationChannel(
+ NotificationService.MESSAGES_NOTIFICATION_CHANNEL, shortcut.getId());
+ if (channel != null && channel.getConversationId() != null) {
+ ShortcutManagerCompat.pushDynamicShortcut(this, shortcut);
+ openNotificationSettings(shortcut);
+ } else {
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.custom_notifications)
+ .setMessage(R.string.custom_notifications_enable)
+ .setPositiveButton(
+ R.string.continue_btn,
+ (d, w) -> {
+ NotificationService.createConversationChannel(this, shortcut);
+ ShortcutManagerCompat.pushDynamicShortcut(this, shortcut);
+ openNotificationSettings(shortcut);
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .create()
+ .show();
+ }
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.R)
+ protected void openNotificationSettings(final ShortcutInfoCompat shortcut) {
+ final var intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
+ intent.putExtra(
+ Settings.EXTRA_CHANNEL_ID, NotificationService.MESSAGES_NOTIFICATION_CHANNEL);
+ intent.putExtra(Settings.EXTRA_CONVERSATION_ID, shortcut.getId());
+ startActivity(intent);
+ }
public boolean hasPgp() {
return xmppConnectionService.getPgpEngine() != null;
@@ -257,16 +299,20 @@ public abstract class XmppActivity extends ActionBarActivity {
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))));
+ builder.setMessage(
+ Html.fromHtml(
+ getString(
+ R.string.openkeychain_required_long,
+ getString(R.string.app_name))));
builder.setNegativeButton(getString(R.string.cancel), null);
- builder.setNeutralButton(getString(R.string.restart),
+ builder.setNeutralButton(
+ getString(R.string.restart),
(dialog, which) -> {
if (xmppConnectionServiceBound) {
unbindService(mConnection);
xmppConnectionServiceBound = false;
}
- stopService(new Intent(XmppActivity.this,
- XmppConnectionService.class));
+ stopService(new Intent(XmppActivity.this, XmppConnectionService.class));
finish();
});
builder.setPositiveButton(
@@ -344,58 +390,89 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void deleteAccount(final Account account, final Runnable postDelete) {
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);
+ final CheckBox deleteFromServer = dialogView.findViewById(R.id.delete_from_server);
builder.setView(dialogView);
builder.setTitle(R.string.mgmt_account_delete);
- builder.setPositiveButton(getString(R.string.delete),null);
+ builder.setPositiveButton(getString(R.string.delete), null);
builder.setNegativeButton(getString(R.string.cancel), null);
final AlertDialog dialog = builder.create();
- dialog.setOnShowListener(dialogInterface->{
- final Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
- button.setOnClickListener(v -> {
- final boolean unregister = deleteFromServer.isChecked();
- if (unregister) {
- if (account.isOnlineAndConnected()) {
- deleteFromServer.setEnabled(false);
- button.setText(R.string.please_wait);
- button.setEnabled(false);
- xmppConnectionService.unregisterAccount(account, result -> {
- runOnUiThread(()->{
- if (result) {
- dialog.dismiss();
- if (postDelete != null) {
- postDelete.run();
+ dialog.setOnShowListener(
+ dialogInterface -> {
+ final Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ button.setOnClickListener(
+ v -> {
+ final boolean unregister = deleteFromServer.isChecked();
+ if (unregister) {
+ if (account.isOnlineAndConnected()) {
+ deleteFromServer.setEnabled(false);
+ button.setText(R.string.please_wait);
+ button.setEnabled(false);
+ xmppConnectionService.unregisterAccount(
+ account,
+ result -> {
+ runOnUiThread(
+ () -> {
+ if (result) {
+ dialog.dismiss();
+ if (postDelete != null) {
+ postDelete.run();
+ }
+ if (xmppConnectionService
+ .getAccounts()
+ .size()
+ == 0
+ && Config
+ .MAGIC_CREATE_DOMAIN
+ != null) {
+ final Intent intent =
+ SignupUtils
+ .getSignUpIntent(
+ this);
+ intent.setFlags(
+ Intent
+ .FLAG_ACTIVITY_NEW_TASK
+ | Intent
+ .FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ }
+ } else {
+ deleteFromServer.setEnabled(
+ true);
+ button.setText(R.string.delete);
+ button.setEnabled(true);
+ Toast.makeText(
+ this,
+ R.string
+ .could_not_delete_account_from_server,
+ Toast
+ .LENGTH_LONG)
+ .show();
+ }
+ });
+ });
+ } else {
+ Toast.makeText(
+ this,
+ R.string.not_connected_try_again,
+ Toast.LENGTH_LONG)
+ .show();
}
- if (xmppConnectionService.getAccounts().size() == 0 && Config.MAGIC_CREATE_DOMAIN != null) {
+ } else {
+ xmppConnectionService.deleteAccount(account);
+ dialog.dismiss();
+ if (xmppConnectionService.getAccounts().size() == 0
+ && Config.MAGIC_CREATE_DOMAIN != null) {
final Intent intent = SignupUtils.getSignUpIntent(this);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
+ } else if (postDelete != null) {
+ postDelete.run();
}
- } else {
- deleteFromServer.setEnabled(true);
- button.setText(R.string.delete);
- button.setEnabled(true);
- Toast.makeText(this,R.string.could_not_delete_account_from_server,Toast.LENGTH_LONG).show();
}
});
- });
- } else {
- Toast.makeText(this,R.string.not_connected_try_again,Toast.LENGTH_LONG).show();
- }
- } else {
- xmppConnectionService.deleteAccount(account);
- dialog.dismiss();
- if (xmppConnectionService.getAccounts().size() == 0 && Config.MAGIC_CREATE_DOMAIN != null) {
- final Intent intent = SignupUtils.getSignUpIntent(this);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- startActivity(intent);
- } else if (postDelete != null) {
- postDelete.run();
- }
- }
- });
- });
+ });
dialog.show();
}
@@ -403,61 +480,75 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void registerListeners() {
if (this instanceof XmppConnectionService.OnConversationUpdate) {
- this.xmppConnectionService.setOnConversationListChangedListener((XmppConnectionService.OnConversationUpdate) this);
+ this.xmppConnectionService.setOnConversationListChangedListener(
+ (XmppConnectionService.OnConversationUpdate) this);
}
if (this instanceof XmppConnectionService.OnAccountUpdate) {
- this.xmppConnectionService.setOnAccountListChangedListener((XmppConnectionService.OnAccountUpdate) this);
+ this.xmppConnectionService.setOnAccountListChangedListener(
+ (XmppConnectionService.OnAccountUpdate) this);
}
if (this instanceof XmppConnectionService.OnCaptchaRequested) {
- this.xmppConnectionService.setOnCaptchaRequestedListener((XmppConnectionService.OnCaptchaRequested) this);
+ this.xmppConnectionService.setOnCaptchaRequestedListener(
+ (XmppConnectionService.OnCaptchaRequested) this);
}
if (this instanceof XmppConnectionService.OnRosterUpdate) {
- this.xmppConnectionService.setOnRosterUpdateListener((XmppConnectionService.OnRosterUpdate) this);
+ this.xmppConnectionService.setOnRosterUpdateListener(
+ (XmppConnectionService.OnRosterUpdate) this);
}
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
- this.xmppConnectionService.setOnMucRosterUpdateListener((XmppConnectionService.OnMucRosterUpdate) this);
+ this.xmppConnectionService.setOnMucRosterUpdateListener(
+ (XmppConnectionService.OnMucRosterUpdate) this);
}
if (this instanceof OnUpdateBlocklist) {
this.xmppConnectionService.setOnUpdateBlocklistListener((OnUpdateBlocklist) this);
}
if (this instanceof XmppConnectionService.OnShowErrorToast) {
- this.xmppConnectionService.setOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this);
+ this.xmppConnectionService.setOnShowErrorToastListener(
+ (XmppConnectionService.OnShowErrorToast) this);
}
if (this instanceof OnKeyStatusUpdated) {
this.xmppConnectionService.setOnKeyStatusUpdatedListener((OnKeyStatusUpdated) this);
}
if (this instanceof XmppConnectionService.OnJingleRtpConnectionUpdate) {
- this.xmppConnectionService.setOnRtpConnectionUpdateListener((XmppConnectionService.OnJingleRtpConnectionUpdate) this);
+ this.xmppConnectionService.setOnRtpConnectionUpdateListener(
+ (XmppConnectionService.OnJingleRtpConnectionUpdate) this);
}
}
protected void unregisterListeners() {
if (this instanceof XmppConnectionService.OnConversationUpdate) {
- this.xmppConnectionService.removeOnConversationListChangedListener((XmppConnectionService.OnConversationUpdate) this);
+ this.xmppConnectionService.removeOnConversationListChangedListener(
+ (XmppConnectionService.OnConversationUpdate) this);
}
if (this instanceof XmppConnectionService.OnAccountUpdate) {
- this.xmppConnectionService.removeOnAccountListChangedListener((XmppConnectionService.OnAccountUpdate) this);
+ this.xmppConnectionService.removeOnAccountListChangedListener(
+ (XmppConnectionService.OnAccountUpdate) this);
}
if (this instanceof XmppConnectionService.OnCaptchaRequested) {
- this.xmppConnectionService.removeOnCaptchaRequestedListener((XmppConnectionService.OnCaptchaRequested) this);
+ this.xmppConnectionService.removeOnCaptchaRequestedListener(
+ (XmppConnectionService.OnCaptchaRequested) this);
}
if (this instanceof XmppConnectionService.OnRosterUpdate) {
- this.xmppConnectionService.removeOnRosterUpdateListener((XmppConnectionService.OnRosterUpdate) this);
+ this.xmppConnectionService.removeOnRosterUpdateListener(
+ (XmppConnectionService.OnRosterUpdate) this);
}
if (this instanceof XmppConnectionService.OnMucRosterUpdate) {
- this.xmppConnectionService.removeOnMucRosterUpdateListener((XmppConnectionService.OnMucRosterUpdate) this);
+ this.xmppConnectionService.removeOnMucRosterUpdateListener(
+ (XmppConnectionService.OnMucRosterUpdate) this);
}
if (this instanceof OnUpdateBlocklist) {
this.xmppConnectionService.removeOnUpdateBlocklistListener((OnUpdateBlocklist) this);
}
if (this instanceof XmppConnectionService.OnShowErrorToast) {
- this.xmppConnectionService.removeOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this);
+ this.xmppConnectionService.removeOnShowErrorToastListener(
+ (XmppConnectionService.OnShowErrorToast) this);
}
if (this instanceof OnKeyStatusUpdated) {
this.xmppConnectionService.removeOnNewKeysAvailableListener((OnKeyStatusUpdated) this);
}
if (this instanceof XmppConnectionService.OnJingleRtpConnectionUpdate) {
- this.xmppConnectionService.removeRtpConnectionUpdateListener((XmppConnectionService.OnJingleRtpConnectionUpdate) this);
+ this.xmppConnectionService.removeRtpConnectionUpdateListener(
+ (XmppConnectionService.OnJingleRtpConnectionUpdate) this);
}
}
@@ -465,7 +556,9 @@ public abstract class XmppActivity extends ActionBarActivity {
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
- startActivity(new Intent(this, eu.siacs.conversations.ui.activity.SettingsActivity.class));
+ startActivity(
+ new Intent(
+ this, eu.siacs.conversations.ui.activity.SettingsActivity.class));
break;
case R.id.action_privacy_policy:
openPrivacyPolicy();
@@ -500,7 +593,8 @@ public abstract class XmppActivity extends ActionBarActivity {
}
}
- public void selectPresence(final Conversation conversation, final PresenceSelector.OnPresenceSelected listener) {
+ public void selectPresence(
+ final Conversation conversation, final PresenceSelector.OnPresenceSelected listener) {
final Contact contact = conversation.getContact();
if (contact.showInRoster() || contact.isSelf()) {
final Presences presences = contact.getPresences();
@@ -521,7 +615,8 @@ public abstract class XmppActivity extends ActionBarActivity {
}
} else if (presences.size() == 1) {
final String presence = presences.toResourceArray()[0];
- conversation.setNextCounterpart(PresenceSelector.getNextCounterpart(contact, presence));
+ conversation.setNextCounterpart(
+ PresenceSelector.getNextCounterpart(contact, presence));
listener.onPresenceSelected();
} else {
PresenceSelector.showPresenceSelectionDialog(this, conversation, listener);
@@ -536,7 +631,8 @@ public abstract class XmppActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
metrics = getResources().getDisplayMetrics();
- this.isCameraFeatureAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
+ this.isCameraFeatureAvailable =
+ getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
protected boolean isCameraFeatureAvailable() {
@@ -546,14 +642,16 @@ public abstract class XmppActivity extends ActionBarActivity {
protected boolean isOptimizingBattery() {
final PowerManager pm = getSystemService(PowerManager.class);
return !pm.isIgnoringBatteryOptimizations(getPackageName());
-}
+ }
protected boolean isAffectedByDataSaver() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ final ConnectivityManager cm =
+ (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null
&& cm.isActiveNetworkMetered()
- && Compatibility.getRestrictBackgroundStatus(cm) == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
+ && Compatibility.getRestrictBackgroundStatus(cm)
+ == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
} else {
return false;
}
@@ -564,7 +662,8 @@ public abstract class XmppActivity extends ActionBarActivity {
}
private boolean useTor() {
- return QuickConversationsService.isConversations() && getBooleanPreference("use_tor", R.bool.use_tor);
+ return QuickConversationsService.isConversations()
+ && getBooleanPreference("use_tor", R.bool.use_tor);
}
protected SharedPreferences getPreferences() {
@@ -599,7 +698,13 @@ public abstract class XmppActivity extends ActionBarActivity {
switchToConversation(conversation, null, false, nick, true, false);
}
- private void switchToConversation(Conversation conversation, String text, boolean asQuote, String nick, boolean pm, boolean doNotAppend) {
+ private void switchToConversation(
+ Conversation conversation,
+ String text,
+ boolean asQuote,
+ String nick,
+ boolean pm,
+ boolean doNotAppend) {
Intent intent = new Intent(this, ConversationsActivity.class);
intent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION);
intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());
@@ -647,7 +752,10 @@ public abstract class XmppActivity extends ActionBarActivity {
intent.putExtra("jid", account.getJid().asBareJid().toEscapedString());
intent.putExtra("init", init);
if (init) {
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_ACTIVITY_NO_ANIMATION);
}
if (fingerprint != null) {
intent.putExtra("fingerprint", fingerprint);
@@ -671,85 +779,113 @@ public abstract class XmppActivity extends ActionBarActivity {
}
protected void inviteToConversation(Conversation conversation) {
- startActivityForResult(ChooseContactActivity.create(this, conversation), REQUEST_INVITE_TO_CONVERSATION);
+ startActivityForResult(
+ ChooseContactActivity.create(this, conversation), REQUEST_INVITE_TO_CONVERSATION);
}
- protected void announcePgp(final Account account, final Conversation conversation, Intent intent, final Runnable onSuccess) {
+ protected void announcePgp(
+ final Account account,
+ final Conversation conversation,
+ Intent intent,
+ final Runnable onSuccess) {
if (account.getPgpId() == 0) {
choosePgpSignId(account);
} else {
final String status = Strings.nullToEmpty(account.getPresenceStatusMessage());
- xmppConnectionService.getPgpEngine().generateSignature(intent, account, status, new UiCallback<String>() {
-
- @Override
- public void userInputRequired(final PendingIntent pi, final String signature) {
- try {
- startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0,Compatibility.pgpStartIntentSenderOptions());
- } catch (final SendIntentException ignored) {
- }
- }
+ xmppConnectionService
+ .getPgpEngine()
+ .generateSignature(
+ intent,
+ account,
+ status,
+ new UiCallback<String>() {
+
+ @Override
+ public void userInputRequired(
+ final PendingIntent pi, final String signature) {
+ try {
+ startIntentSenderForResult(
+ pi.getIntentSender(),
+ REQUEST_ANNOUNCE_PGP,
+ null,
+ 0,
+ 0,
+ 0,
+ Compatibility.pgpStartIntentSenderOptions());
+ } catch (final SendIntentException ignored) {
+ }
+ }
- @Override
- public void success(String signature) {
- account.setPgpSignature(signature);
- xmppConnectionService.databaseBackend.updateAccount(account);
- xmppConnectionService.sendPresence(account);
- if (conversation != null) {
- conversation.setNextEncryption(Message.ENCRYPTION_PGP);
- xmppConnectionService.updateConversation(conversation);
- refreshUi();
- }
- if (onSuccess != null) {
- runOnUiThread(onSuccess);
- }
- }
+ @Override
+ public void success(String signature) {
+ account.setPgpSignature(signature);
+ xmppConnectionService.databaseBackend.updateAccount(account);
+ xmppConnectionService.sendPresence(account);
+ if (conversation != null) {
+ conversation.setNextEncryption(Message.ENCRYPTION_PGP);
+ xmppConnectionService.updateConversation(conversation);
+ refreshUi();
+ }
+ if (onSuccess != null) {
+ runOnUiThread(onSuccess);
+ }
+ }
- @Override
- public void error(int error, String signature) {
- if (error == 0) {
- account.setPgpSignId(0);
- account.unsetPgpSignature();
- xmppConnectionService.databaseBackend.updateAccount(account);
- choosePgpSignId(account);
- } else {
- displayErrorDialog(error);
- }
- }
- });
+ @Override
+ public void error(int error, String signature) {
+ if (error == 0) {
+ account.setPgpSignId(0);
+ account.unsetPgpSignature();
+ xmppConnectionService.databaseBackend.updateAccount(
+ account);
+ choosePgpSignId(account);
+ } else {
+ displayErrorDialog(error);
+ }
+ }
+ });
}
}
protected void choosePgpSignId(final Account account) {
- xmppConnectionService.getPgpEngine().chooseKey(account, new UiCallback<>() {
- @Override
- public void success(final Account a) {
- }
-
- @Override
- public void error(int errorCode, Account object) {
-
- }
-
- @Override
- public void userInputRequired(PendingIntent pi, Account object) {
- try {
- startIntentSenderForResult(pi.getIntentSender(),
- REQUEST_CHOOSE_PGP_ID, null, 0, 0, 0, Compatibility.pgpStartIntentSenderOptions());
- } catch (final SendIntentException ignored) {
- }
- }
- });
+ xmppConnectionService
+ .getPgpEngine()
+ .chooseKey(
+ account,
+ new UiCallback<>() {
+ @Override
+ public void success(final Account a) {}
+
+ @Override
+ public void error(int errorCode, Account object) {}
+
+ @Override
+ public void userInputRequired(PendingIntent pi, Account object) {
+ try {
+ startIntentSenderForResult(
+ pi.getIntentSender(),
+ REQUEST_CHOOSE_PGP_ID,
+ null,
+ 0,
+ 0,
+ 0,
+ Compatibility.pgpStartIntentSenderOptions());
+ } catch (final SendIntentException ignored) {
+ }
+ }
+ });
}
protected void displayErrorDialog(final int errorCode) {
- runOnUiThread(() -> {
- final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(XmppActivity.this);
- builder.setTitle(getString(R.string.error));
- builder.setMessage(errorCode);
- builder.setNeutralButton(R.string.accept, null);
- builder.create().show();
- });
-
+ runOnUiThread(
+ () -> {
+ final MaterialAlertDialogBuilder builder =
+ new MaterialAlertDialogBuilder(XmppActivity.this);
+ builder.setTitle(getString(R.string.error));
+ builder.setMessage(errorCode);
+ builder.setNeutralButton(R.string.accept, null);
+ builder.create().show();
+ });
}
protected void showAddToRosterDialog(final Contact contact) {
@@ -757,7 +893,9 @@ public abstract class XmppActivity extends ActionBarActivity {
builder.setTitle(contact.getJid().toString());
builder.setMessage(getString(R.string.not_in_roster));
builder.setNegativeButton(getString(R.string.cancel), null);
- builder.setPositiveButton(getString(R.string.add_contact), (dialog, which) -> xmppConnectionService.createContact(contact, true));
+ builder.setPositiveButton(
+ getString(R.string.add_contact),
+ (dialog, which) -> xmppConnectionService.createContact(contact, true));
builder.create().show();
}
@@ -766,13 +904,15 @@ public abstract class XmppActivity extends ActionBarActivity {
builder.setTitle(contact.getJid().toString());
builder.setMessage(R.string.request_presence_updates);
builder.setNegativeButton(R.string.cancel, null);
- builder.setPositiveButton(R.string.request_now,
+ builder.setPositiveButton(
+ R.string.request_now,
(dialog, which) -> {
if (xmppConnectionServiceBound) {
- xmppConnectionService.sendPresencePacket(contact
- .getAccount(), xmppConnectionService
- .getPresenceGenerator()
- .requestPresenceUpdatesFrom(contact));
+ xmppConnectionService.sendPresencePacket(
+ contact.getAccount(),
+ xmppConnectionService
+ .getPresenceGenerator()
+ .requestPresenceUpdatesFrom(contact));
}
});
builder.create().show();
@@ -782,7 +922,11 @@ public abstract class XmppActivity extends ActionBarActivity {
quickEdit(previousValue, callback, hint, false, false);
}
- protected void quickEdit(String previousValue, @StringRes int hint, OnValueEdited callback, boolean permitEmpty) {
+ protected void quickEdit(
+ String previousValue,
+ @StringRes int hint,
+ OnValueEdited callback,
+ boolean permitEmpty) {
quickEdit(previousValue, callback, hint, false, permitEmpty);
}
@@ -791,15 +935,19 @@ public abstract class XmppActivity extends ActionBarActivity {
}
@SuppressLint("InflateParams")
- private void quickEdit(final String previousValue,
- final OnValueEdited callback,
- final @StringRes int hint,
- boolean password,
- boolean permitEmpty) {
+ private void quickEdit(
+ final String previousValue,
+ final OnValueEdited callback,
+ final @StringRes int hint,
+ boolean password,
+ boolean permitEmpty) {
final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
- final DialogQuickeditBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.dialog_quickedit, null, false);
+ final DialogQuickeditBinding binding =
+ DataBindingUtil.inflate(
+ getLayoutInflater(), R.layout.dialog_quickedit, null, false);
if (password) {
- binding.inputEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ binding.inputEditText.setInputType(
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
}
builder.setPositiveButton(R.string.accept, null);
if (hint != 0) {
@@ -814,33 +962,39 @@ public abstract class XmppActivity extends ActionBarActivity {
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(d -> SoftKeyboardUtils.showKeyboard(binding.inputEditText));
dialog.show();
- View.OnClickListener clickListener = v -> {
- String value = binding.inputEditText.getText().toString();
- if (!value.equals(previousValue) && (!value.trim().isEmpty() || permitEmpty)) {
- String error = callback.onValueEdited(value);
- if (error != null) {
- binding.inputLayout.setError(error);
- return;
- }
- }
- SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
- dialog.dismiss();
- };
+ View.OnClickListener clickListener =
+ v -> {
+ String value = binding.inputEditText.getText().toString();
+ if (!value.equals(previousValue) && (!value.trim().isEmpty() || permitEmpty)) {
+ String error = callback.onValueEdited(value);
+ if (error != null) {
+ binding.inputLayout.setError(error);
+ return;
+ }
+ }
+ SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
+ dialog.dismiss();
+ };
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(clickListener);
- dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener((v -> {
- SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
- dialog.dismiss();
- }));
+ dialog.getButton(DialogInterface.BUTTON_NEGATIVE)
+ .setOnClickListener(
+ (v -> {
+ SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
+ dialog.dismiss();
+ }));
dialog.setCanceledOnTouchOutside(false);
- dialog.setOnDismissListener(dialog1 -> {
- SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
- });
+ dialog.setOnDismissListener(
+ dialog1 -> {
+ SoftKeyboardUtils.hideSoftKeyboard(binding.inputEditText);
+ });
}
protected boolean hasStoragePermission(int requestCode) {
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);
+ if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(
+ new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
return false;
} else {
return true;
@@ -876,7 +1030,8 @@ public abstract class XmppActivity extends ActionBarActivity {
}
protected boolean manuallyChangePresence() {
- return getBooleanPreference(AppSettings.MANUALLY_CHANGE_PRESENCE, R.bool.manually_change_presence);
+ return getBooleanPreference(
+ AppSettings.MANUALLY_CHANGE_PRESENCE, R.bool.manually_change_presence);
}
protected String getShareableUri() {
@@ -906,16 +1061,21 @@ public abstract class XmppActivity extends ActionBarActivity {
PgpEngine pgp = XmppActivity.this.xmppConnectionService.getPgpEngine();
try {
startIntentSenderForResult(
- pgp.getIntentForKey(keyId).getIntentSender(), 0, null, 0,
- 0, 0, Compatibility.pgpStartIntentSenderOptions());
+ pgp.getIntentForKey(keyId).getIntentSender(),
+ 0,
+ null,
+ 0,
+ 0,
+ 0,
+ Compatibility.pgpStartIntentSenderOptions());
} catch (final Throwable e) {
- Log.d(Config.LOGTAG,"could not launch OpenKeyChain", e);
+ Log.d(Config.LOGTAG, "could not launch OpenKeyChain", e);
Toast.makeText(XmppActivity.this, R.string.openpgp_error, Toast.LENGTH_SHORT).show();
}
}
@Override
- protected void onResume(){
+ protected void onResume() {
super.onResume();
SettingsUtils.applyScreenshotSetting(this);
}
@@ -947,11 +1107,27 @@ public abstract class XmppActivity extends ActionBarActivity {
final int black;
final int white;
if (Activities.isNightMode(this)) {
- 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");
+ 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");
+ 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);
@@ -978,7 +1154,10 @@ public abstract class XmppActivity extends ActionBarActivity {
public void loadBitmap(Message message, ImageView imageView) {
Bitmap bm;
try {
- bm = xmppConnectionService.getFileBackend().getThumbnail(message, (int) (metrics.density * 288), true);
+ bm =
+ xmppConnectionService
+ .getFileBackend()
+ .getThumbnail(message, (int) (metrics.density * 288), true);
} catch (IOException e) {
bm = null;
}
@@ -991,8 +1170,7 @@ public abstract class XmppActivity extends ActionBarActivity {
imageView.setBackgroundColor(0xff333333);
imageView.setImageDrawable(null);
final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
- final AsyncDrawable asyncDrawable = new AsyncDrawable(
- getResources(), null, task);
+ final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), null, task);
imageView.setImageDrawable(asyncDrawable);
try {
task.execute(message);
@@ -1035,7 +1213,8 @@ public abstract class XmppActivity extends ActionBarActivity {
return false;
} else {
jids.add(conversation.getJid().asBareJid());
- return service.createAdhocConference(conversation.getAccount(), null, jids, activity.adhocCallback);
+ return service.createAdhocConference(
+ conversation.getAccount(), null, jids, activity.adhocCallback);
}
}
}
@@ -1057,7 +1236,9 @@ public abstract class XmppActivity extends ActionBarActivity {
try {
final XmppActivity activity = find(imageViewReference);
if (activity != null && activity.xmppConnectionService != null) {
- return activity.xmppConnectionService.getFileBackend().getThumbnail(message, (int) (activity.metrics.density * 288), false);
+ return activity.xmppConnectionService
+ .getFileBackend()
+ .getThumbnail(message, (int) (activity.metrics.density * 288), false);
} else {
return null;
}
@@ -1,64 +1,70 @@
<?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_edit_contact"
android:icon="@drawable/ic_edit_24dp"
android:orderInCategory="10"
- app:showAsAction="always"
- android:title="@string/action_edit_contact"/>
+ android:title="@string/action_edit_contact"
+ app:showAsAction="always" />
<item
android:id="@+id/action_share"
android:icon="@drawable/ic_share_24dp"
android:orderInCategory="15"
- app:showAsAction="always"
- android:title="@string/share_uri_with">
+ android:title="@string/share_uri_with"
+ app:showAsAction="always">
<menu>
<item
android:id="@+id/action_share_uri"
- android:title="@string/share_as_uri"/>
+ android:title="@string/share_as_uri" />
<item
android:id="@+id/action_share_http"
- android:title="@string/share_as_http"/>
+ android:title="@string/share_as_http" />
<item
android:id="@+id/action_show_qr_code"
- android:title="@string/show_qr_code"/>
+ android:title="@string/show_qr_code" />
</menu>
</item>
<item
android:id="@+id/action_delete_contact"
android:orderInCategory="10"
- app:showAsAction="never"
- android:title="@string/action_delete_contact"/>
+ android:title="@string/action_delete_contact"
+ app:showAsAction="never" />
<item
android:id="@+id/action_block"
android:orderInCategory="72"
- app:showAsAction="never"
- android:title="@string/action_block_contact"/>
+ android:title="@string/action_block_contact"
+ app:showAsAction="never" />
<item
android:id="@+id/action_unblock"
android:orderInCategory="73"
- app:showAsAction="never"
- android:title="@string/action_unblock_contact"/>
+ android:title="@string/action_unblock_contact"
+ app:showAsAction="never" />
+
+ <item
+ android:id="@+id/action_custom_notifications"
+ android:orderInCategory="75"
+ android:title="@string/custom_notifications"
+ app:showAsAction="never" />
<item
android:id="@+id/action_accounts"
android:orderInCategory="90"
- app:showAsAction="never"
- android:title="@string/action_accounts"/>
+ android:title="@string/action_accounts"
+ app:showAsAction="never" />
<item
android:id="@+id/action_account"
android:orderInCategory="90"
android:title="@string/action_account"
- app:showAsAction="never"/>
+ app:showAsAction="never" />
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
- app:showAsAction="never"
- android:title="@string/action_settings"/>
+ android:title="@string/action_settings"
+ app:showAsAction="never" />
</menu>
@@ -1,57 +1,62 @@
<?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_share"
android:icon="@drawable/ic_share_24dp"
android:orderInCategory="15"
- app:showAsAction="ifRoom"
- android:title="@string/share_uri_with">
+ android:title="@string/share_uri_with"
+ app:showAsAction="ifRoom">
<menu>
<item
android:id="@+id/action_share_uri"
- android:title="@string/share_as_uri"/>
+ android:title="@string/share_as_uri" />
<item
android:id="@+id/action_share_http"
- android:title="@string/share_as_http"/>
+ android:title="@string/share_as_http" />
<item
android:id="@+id/action_show_qr_code"
- android:title="@string/show_qr_code"/>
+ android:title="@string/show_qr_code" />
</menu>
</item>
<item
android:id="@+id/action_save_as_bookmark"
android:orderInCategory="80"
- app:showAsAction="never"
- android:title="@string/save_as_bookmark"/>
+ android:title="@string/save_as_bookmark"
+ app:showAsAction="never" />
<item
android:id="@+id/action_destroy_room"
android:orderInCategory="82"
- app:showAsAction="never"
- android:title="@string/destroy_room"/>
+ android:title="@string/destroy_room"
+ app:showAsAction="never" />
<item
android:id="@+id/action_advanced_mode"
android:checkable="true"
android:checked="false"
android:orderInCategory="85"
- app:showAsAction="never"
- android:title="@string/advanced_mode"/>
+ android:title="@string/advanced_mode"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/action_custom_notifications"
+ android:orderInCategory="89"
+ android:title="@string/custom_notifications"
+ app:showAsAction="never" />
<item
android:id="@+id/action_accounts"
android:orderInCategory="90"
- app:showAsAction="never"
- android:title="@string/action_accounts"/>
+ android:title="@string/action_accounts"
+ app:showAsAction="never" />
<item
android:id="@+id/action_account"
android:orderInCategory="90"
android:title="@string/action_account"
- app:showAsAction="never"/>
+ app:showAsAction="never" />
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
- app:showAsAction="never"
- android:title="@string/action_settings"/>
+ android:title="@string/action_settings"
+ app:showAsAction="never" />
</menu>
@@ -1097,4 +1097,6 @@
<string name="pref_call_integration_summary">Calls from this app interact with regular phone calls, such as ending one call when another starts.</string>
<string name="pref_align_start">Left-aligned messages</string>
<string name="pref_align_start_summary">Display all messages, including sent ones, on the left side for a uniform chat layout.</string>
+ <string name="custom_notifications">Custom notifications</string>
+ <string name="custom_notifications_enable">Enable customized notification settings (importance, sound, vibration) settings for this conversation?</string>
</resources>