Merge pull request #675 from hjubb/notification_control

Fine-Grained Notification controls
This commit is contained in:
Niels Andriesse 2021-07-26 11:30:19 +10:00 committed by GitHub
commit c05c6049d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 362 additions and 103 deletions

View File

@ -2,6 +2,7 @@ package org.thoughtcrime.securesms;
import android.content.Context;
import android.content.DialogInterface;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@ -33,11 +34,10 @@ public class MuteDialog extends AlertDialog {
final long muteUntil;
switch (which) {
case 0: muteUntil = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); break;
case 1: muteUntil = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(2); break;
case 2: muteUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1); break;
case 3: muteUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7); break;
case 4: muteUntil = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(365); break;
case 4: muteUntil = Long.MAX_VALUE; break;
default: muteUntil = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); break;
}

View File

@ -24,7 +24,6 @@ import android.widget.Toast
import androidx.annotation.DimenRes
import androidx.appcompat.app.AlertDialog
import androidx.core.view.children
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
@ -53,17 +52,13 @@ import org.session.libsession.messaging.mentions.MentionsManager
import org.session.libsession.messaging.messages.control.DataExtractionNotification
import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
import org.session.libsession.messaging.messages.visible.LinkPreview.Companion.from
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation
import org.session.libsession.messaging.messages.visible.Quote.Companion.from
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.utilities.UpdateMessageData
import org.session.libsession.messaging.utilities.UpdateMessageData.Companion.fromJSON
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.fromSerialized
import org.session.libsession.utilities.MediaTypes
@ -116,6 +111,9 @@ import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.util.*
import java.util.*
import java.util.concurrent.ExecutionException
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
import kotlin.math.*
// Some things that seemingly belong to the input bar (e.g. the voice message recording UI) are actually
@ -502,7 +500,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
} else {
MarkReadReceiver.process(this, messages)
}
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this)
ApplicationContext.getInstance(this).messageNotifier.updateNotification(this, threadID)
}
override fun inputBarHeightChanged(newValue: Int) {
@ -720,7 +718,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
muteIconImageView.isVisible = thread.isMuted
conversationSubtitleView.isVisible = true
if (thread.isMuted) {
conversationSubtitleView.text = getString(R.string.ConversationActivity_muted_until_date, DateUtils.getFormattedDateTime(thread.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()))
if (thread.mutedUntil != Long.MAX_VALUE) {
conversationSubtitleView.text = getString(R.string.ConversationActivity_muted_until_date, DateUtils.getFormattedDateTime(thread.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()))
} else {
conversationSubtitleView.text = getString(R.string.ConversationActivity_muted_forever)
}
} else if (thread.isGroupRecipient) {
val openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadID)
if (openGroup != null) {

View File

@ -36,13 +36,14 @@ import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.guava.Optional
import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.*
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.groups.EditClosedGroupActivity
import org.thoughtcrime.securesms.groups.EditClosedGroupActivity.Companion.groupIDKey
import org.thoughtcrime.securesms.contacts.SelectContactsActivity
import org.thoughtcrime.securesms.util.getColorWithID
import org.thoughtcrime.securesms.util.BitmapUtil
import org.thoughtcrime.securesms.util.getColorWithID
import java.io.IOException
object ConversationMenuHelper {
@ -152,6 +153,7 @@ object ConversationMenuHelper {
R.id.menu_invite_to_open_group -> { inviteContacts(context, thread) }
R.id.menu_unmute_notifications -> { unmute(context, thread) }
R.id.menu_mute_notifications -> { mute(context, thread) }
R.id.menu_notification_settings -> { setNotifyType(context, thread) }
}
return true
}
@ -325,4 +327,11 @@ object ConversationMenuHelper {
DatabaseFactory.getRecipientDatabase(context).setMuted(thread, until)
}
}
private fun setNotifyType(context: Context, thread: Recipient) {
NotificationUtils.showNotifyDialog(context, thread) { notifyType ->
DatabaseFactory.getRecipientDatabase(context).setNotifyType(thread, notifyType)
}
}
}

View File

@ -0,0 +1,21 @@
package org.thoughtcrime.securesms.conversation.v2.utilities
import android.content.Context
import androidx.appcompat.app.AlertDialog
import network.loki.messenger.R
import org.session.libsession.utilities.recipients.Recipient
object NotificationUtils {
fun showNotifyDialog(context: Context, thread: Recipient, notifyTypeHandler: (Int)->Unit) {
val notifyTypes = context.resources.getStringArray(R.array.notify_types)
val currentSelected = thread.notifyType
AlertDialog.Builder(context)
.setSingleChoiceItems(notifyTypes,currentSelected) { d, newSelection ->
notifyTypeHandler(newSelection)
d.dismiss()
}
.setTitle(R.string.RecipientPreferenceActivity_notification_settings)
.show()
}
}

View File

@ -10,17 +10,18 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.*;
import org.session.libsignal.utilities.Base64;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.Util;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
import org.session.libsession.utilities.recipients.Recipient.RegisteredState;
import org.session.libsession.utilities.recipients.Recipient.UnidentifiedAccessMode;
import org.session.libsignal.utilities.Base64;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import java.io.Closeable;
import java.io.IOException;
@ -55,13 +56,14 @@ public class RecipientDatabase extends Database {
private static final String NOTIFICATION_CHANNEL = "notification_channel";
private static final String UNIDENTIFIED_ACCESS_MODE = "unidentified_access_mode";
private static final String FORCE_SMS_SELECTION = "force_sms_selection";
private static final String NOTIFY_TYPE = "notify_type"; // all, mentions only, none
private static final String[] RECIPIENT_PROJECTION = new String[] {
BLOCK, NOTIFICATION, CALL_RINGTONE, VIBRATE, CALL_VIBRATE, MUTE_UNTIL, COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, EXPIRE_MESSAGES, REGISTERED,
PROFILE_KEY, SYSTEM_DISPLAY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_CONTACT_URI,
SIGNAL_PROFILE_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING, NOTIFICATION_CHANNEL,
UNIDENTIFIED_ACCESS_MODE,
FORCE_SMS_SELECTION,
FORCE_SMS_SELECTION, NOTIFY_TYPE,
};
static final List<String> TYPED_RECIPIENT_PROJECTION = Stream.of(RECIPIENT_PROJECTION)
@ -95,6 +97,15 @@ public class RecipientDatabase extends Database {
UNIDENTIFIED_ACCESS_MODE + " INTEGER DEFAULT 0, " +
FORCE_SMS_SELECTION + " INTEGER DEFAULT 0);";
public static String getCreateNotificationTypeCommand() {
return "ALTER TABLE "+ TABLE_NAME + " " +
"ADD COLUMN " + NOTIFY_TYPE + " INTEGER DEFAULT 0;";
}
public static final int NOTIFY_TYPE_ALL = 0;
public static final int NOTIFY_TYPE_MENTIONS = 1;
public static final int NOTIFY_TYPE_NONE = 2;
public RecipientDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
super(context, databaseHelper);
}
@ -131,6 +142,7 @@ public class RecipientDatabase extends Database {
int messageVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
int callVibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(CALL_VIBRATE));
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
int notifyType = cursor.getInt(cursor.getColumnIndexOrThrow(NOTIFY_TYPE));
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
int defaultSubscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(DEFAULT_SUBSCRIPTION_ID));
int expireMessages = cursor.getInt(cursor.getColumnIndexOrThrow(EXPIRE_MESSAGES));
@ -167,6 +179,7 @@ public class RecipientDatabase extends Database {
}
return Optional.of(new RecipientSettings(blocked, muteUntil,
notifyType,
Recipient.VibrateState.fromId(messageVibrateState),
Recipient.VibrateState.fromId(callVibrateState),
Util.uri(messageRingtone), Util.uri(callRingtone),
@ -214,6 +227,18 @@ public class RecipientDatabase extends Database {
recipient.resolve().setMuted(until);
}
/**
*
* @param recipient to modify notifications for
* @param notifyType the new notification type {@link #NOTIFY_TYPE_ALL}, {@link #NOTIFY_TYPE_MENTIONS} or {@link #NOTIFY_TYPE_NONE}
*/
public void setNotifyType(@NonNull Recipient recipient, int notifyType) {
ContentValues values = new ContentValues();
values.put(NOTIFY_TYPE, notifyType);
updateOrInsert(recipient.getAddress(), values);
recipient.resolve().setNotifyType(notifyType);
}
public void setExpireMessages(@NonNull Recipient recipient, int expiration) {
recipient.setExpireMessages(expiration);

View File

@ -30,18 +30,18 @@ import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.utilities.Contact;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
import org.session.libsession.utilities.Contact;
import org.session.libsession.utilities.DelimiterUtil;
import org.session.libsession.utilities.DistributionTypes;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.Pair;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
@ -49,9 +49,9 @@ import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
import java.io.Closeable;
import java.util.HashMap;
@ -651,7 +651,7 @@ public class ThreadDatabase extends Database {
groupRecord = Optional.absent();
}
Recipient recipient = Recipient.from(context, address, settings, groupRecord, true);
Recipient recipient = Recipient.from(context, address, settings, groupRecord, false);
String body = cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET));
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));

View File

@ -10,26 +10,26 @@ import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;
import net.sqlcipher.database.SQLiteOpenHelper;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DraftDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
import org.thoughtcrime.securesms.database.JobDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.SearchDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.database.LokiAPIDatabase;
import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase;
import org.thoughtcrime.securesms.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.database.LokiUserDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;
import org.thoughtcrime.securesms.database.PushDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.SearchDatabase;
import org.thoughtcrime.securesms.database.SessionContactDatabase;
import org.thoughtcrime.securesms.database.SessionJobDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@ -58,9 +58,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int lokiV24 = 45;
private static final int lokiV25 = 46;
private static final int lokiV26 = 47;
private static final int lokiV27 = 48;
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
private static final int DATABASE_VERSION = lokiV26;
private static final int DATABASE_VERSION = lokiV27;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@ -296,6 +297,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(SessionContactDatabase.getCreateSessionContactTableCommand());
}
if (oldVersion < lokiV27) {
db.execSQL(RecipientDatabase.getCreateNotificationTypeCommand());
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();

View File

@ -1,16 +1,17 @@
package org.thoughtcrime.securesms.home
import android.os.Bundle
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.fragment_conversation_bottom_sheet.*
import network.loki.messenger.R
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.util.UiModeUtilities
public class ConversationOptionsBottomSheet : BottomSheetDialogFragment() {
public class ConversationOptionsBottomSheet : BottomSheetDialogFragment(), View.OnClickListener {
//FIXME AC: Supplying a recipient directly into the field from an activity
// is not the best idea. It doesn't survive configuration change.
@ -22,11 +23,25 @@ public class ConversationOptionsBottomSheet : BottomSheetDialogFragment() {
var onBlockTapped: (() -> Unit)? = null
var onUnblockTapped: (() -> Unit)? = null
var onDeleteTapped: (() -> Unit)? = null
var onNotificationTapped: (() -> Unit)? = null
var onSetMuteTapped: ((Boolean) -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_conversation_bottom_sheet, container, false)
}
override fun onClick(v: View?) {
when (v) {
detailsTextView -> onViewDetailsTapped?.invoke()
blockTextView -> onBlockTapped?.invoke()
unblockTextView -> onUnblockTapped?.invoke()
deleteTextView -> onDeleteTapped?.invoke()
notificationsTextView -> onNotificationTapped?.invoke()
unMuteNotificationsTextView -> onSetMuteTapped?.invoke(false)
muteNotificationsTextView -> onSetMuteTapped?.invoke(true)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (!this::recipient.isInitialized) { return dismiss() }
@ -34,13 +49,19 @@ public class ConversationOptionsBottomSheet : BottomSheetDialogFragment() {
detailsTextView.visibility = View.VISIBLE
unblockTextView.visibility = if (recipient.isBlocked) View.VISIBLE else View.GONE
blockTextView.visibility = if (recipient.isBlocked) View.GONE else View.VISIBLE
detailsTextView.setOnClickListener { onViewDetailsTapped?.invoke() }
blockTextView.setOnClickListener { onBlockTapped?.invoke() }
unblockTextView.setOnClickListener { onUnblockTapped?.invoke() }
detailsTextView.setOnClickListener(this)
blockTextView.setOnClickListener(this)
unblockTextView.setOnClickListener(this)
} else {
detailsTextView.visibility = View.GONE
}
deleteTextView.setOnClickListener { onDeleteTapped?.invoke() }
unMuteNotificationsTextView.isVisible = recipient.isMuted && !recipient.isLocalNumber
muteNotificationsTextView.isVisible = !recipient.isMuted && !recipient.isLocalNumber
unMuteNotificationsTextView.setOnClickListener(this)
muteNotificationsTextView.setOnClickListener(this)
notificationsTextView.isVisible = recipient.isGroupRecipient
notificationsTextView.setOnClickListener(this)
deleteTextView.setOnClickListener(this)
}
override fun onStart() {

View File

@ -14,9 +14,10 @@ import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.view_conversation.view.*
import network.loki.messenger.R
import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities.highlightMentions
import org.thoughtcrime.securesms.database.RecipientDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.util.DateUtils
import java.util.*
@ -59,7 +60,14 @@ class ConversationView : LinearLayout {
val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString()
conversationViewDisplayNameTextView.text = senderDisplayName
timestampTextView.text = DateUtils.getDisplayFormattedTimeSpanString(context, Locale.getDefault(), thread.date)
muteIndicatorImageView.visibility = if (thread.recipient.isMuted) VISIBLE else GONE
val recipient = thread.recipient
muteIndicatorImageView.isVisible = recipient.isMuted || recipient.notifyType != RecipientDatabase.NOTIFY_TYPE_ALL
val drawableRes = if (recipient.isMuted || recipient.notifyType == RecipientDatabase.NOTIFY_TYPE_NONE) {
R.drawable.ic_outline_notifications_off_24
} else {
R.drawable.ic_notifications_mentions
}
muteIndicatorImageView.setImageResource(drawableRes)
val rawSnippet = thread.getDisplayBody(context)
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
snippetTextView.text = snippet

View File

@ -35,8 +35,10 @@ import org.session.libsession.utilities.Util
import org.session.libsignal.utilities.ThreadUtils
import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.MuteDialog
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.conversation.v2.utilities.NotificationUtils
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.ThreadRecord
@ -44,14 +46,12 @@ import org.thoughtcrime.securesms.dms.CreatePrivateChatActivity
import org.thoughtcrime.securesms.groups.CreateClosedGroupActivity
import org.thoughtcrime.securesms.groups.JoinPublicChatActivity
import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
import org.thoughtcrime.securesms.util.*
import org.thoughtcrime.securesms.onboarding.SeedReminderViewDelegate
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.onboarding.SeedActivity
import org.thoughtcrime.securesms.onboarding.SeedReminderViewDelegate
import org.thoughtcrime.securesms.preferences.SettingsActivity
import org.thoughtcrime.securesms.util.IP2Country
import org.thoughtcrime.securesms.util.*
import java.io.IOException
import java.util.*
@ -257,6 +257,16 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
bottomSheet.dismiss()
deleteConversation(thread)
}
bottomSheet.onSetMuteTapped = { muted ->
bottomSheet.dismiss()
setConversationMuted(thread, muted)
}
bottomSheet.onNotificationTapped = {
bottomSheet.dismiss()
NotificationUtils.showNotifyDialog(this, thread.recipient) { notifyType ->
setNotifyType(thread, notifyType)
}
}
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
}
@ -292,6 +302,35 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
}.show()
}
private fun setConversationMuted(thread: ThreadRecord, isMuted: Boolean) {
if (!isMuted) {
ThreadUtils.queue {
DatabaseFactory.getRecipientDatabase(this).setMuted(thread.recipient, 0)
Util.runOnMain {
recyclerView.adapter!!.notifyDataSetChanged()
}
}
} else {
MuteDialog.show(this) { until: Long ->
ThreadUtils.queue {
DatabaseFactory.getRecipientDatabase(this).setMuted(thread.recipient, until)
Util.runOnMain {
recyclerView.adapter!!.notifyDataSetChanged()
}
}
}
}
}
private fun setNotifyType(thread: ThreadRecord, newNotifyType: Int) {
ThreadUtils.queue {
DatabaseFactory.getRecipientDatabase(this).setNotifyType(thread.recipient, newNotifyType)
Util.runOnMain {
recyclerView.adapter!!.notifyDataSetChanged()
}
}
}
private fun deleteConversation(thread: ThreadRecord) {
val threadID = thread.threadId
val recipient = thread.recipient

View File

@ -4,18 +4,21 @@ import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import network.loki.messenger.R;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.*;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.recipients.Recipient.VibrateState;
import network.loki.messenger.R;
public abstract class AbstractNotificationBuilder extends NotificationCompat.Builder {
@ -26,10 +29,11 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
protected Context context;
protected NotificationPrivacyPreference privacy;
protected final Bundle extras;
public AbstractNotificationBuilder(Context context, NotificationPrivacyPreference privacy) {
super(context);
extras = new Bundle();
this.context = context;
this.privacy = privacy;
@ -97,4 +101,10 @@ public abstract class AbstractNotificationBuilder extends NotificationCompat.Bui
return text.length() <= MAX_DISPLAY_LENGTH ? text
: text.subSequence(0, MAX_DISPLAY_LENGTH);
}
@Override
public Notification build() {
addExtras(extras);
return super.build();
}
}

View File

@ -41,26 +41,26 @@ import androidx.core.app.NotificationManagerCompat;
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier;
import org.session.libsession.utilities.Contact;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.ServiceUtil;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsignal.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.Util;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2;
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.ThreadDatabase;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
import org.thoughtcrime.securesms.util.SpanUtil;
import java.util.HashSet;
@ -87,6 +87,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
private static final String TAG = DefaultMessageNotifier.class.getSimpleName();
public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply";
public static final String LATEST_MESSAGE_ID_TAG = "extra_latest_message_id";
private static final int FOREGROUND_ID = 313399;
private static final int SUMMARY_NOTIFICATION_ID = 1338;
@ -272,16 +273,9 @@ public class DefaultMessageNotifier implements MessageNotifier {
lastAudibleNotification = System.currentTimeMillis();
}
if (notificationState.hasMultipleThreads()) {
if (Build.VERSION.SDK_INT >= 23) {
for (long threadId : notificationState.getThreads()) {
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
}
}
sendMultipleThreadNotification(context, notificationState, signal);
} else {
sendSingleThreadNotification(context, notificationState, signal, false);
boolean hasMultipleThreads = notificationState.hasMultipleThreads();
for (long threadId : notificationState.getThreads()) {
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), signal, hasMultipleThreads);
}
cancelOrphanedNotifications(context, notificationState);
@ -312,7 +306,20 @@ public class DefaultMessageNotifier implements MessageNotifier {
List<NotificationItem> notifications = notificationState.getNotifications();
Recipient recipient = notifications.get(0).getRecipient();
int notificationId = (int) (SUMMARY_NOTIFICATION_ID + (bundled ? notifications.get(0).getThreadId() : 0));
String messageIdTag = String.valueOf(notifications.get(0).getId());
NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
for (StatusBarNotification notification: notificationManager.getActiveNotifications()) {
if (messageIdTag.equals(notification.getNotification().extras.getString(LATEST_MESSAGE_ID_TAG))) {
return;
}
}
long timestamp = notifications.get(0).getTimestamp();
if (timestamp != 0) builder.setWhen(timestamp);
builder.putStringExtra(LATEST_MESSAGE_ID_TAG, messageIdTag);
builder.setThread(notifications.get(0).getRecipient());
builder.setMessageCount(notificationState.getMessageCount());
@ -325,11 +332,6 @@ public class DefaultMessageNotifier implements MessageNotifier {
builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY);
builder.setAutoCancel(true);
long timestamp = notifications.get(0).getTimestamp();
if (timestamp != 0) builder.setWhen(timestamp);
long threadID = notifications.get(0).getThreadId();
ReplyMethod replyMethod = ReplyMethod.forRecipient(context, recipient);
boolean canReply = SessionMetaProtocol.canUserReplyToNotification(recipient);
@ -493,7 +495,16 @@ public class DefaultMessageNotifier implements MessageNotifier {
}
if (threadRecipients == null || !threadRecipients.isMuted()) {
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, slideDeck));
if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_MENTIONS) {
// check if mentioned here
if (body.toString().contains("@"+TextSecurePreferences.getLocalNumber(context))) {
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, slideDeck));
}
} else if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_NONE) {
// do nothing, no notifications
} else {
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, slideDeck));
}
}
}

View File

@ -15,33 +15,38 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.text.SpannableStringBuilder;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationCompat.Action;
import androidx.core.app.RemoteInput;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.session.libsession.avatars.ContactColors;
import org.session.libsession.avatars.ContactPhoto;
import org.session.libsession.avatars.GeneratedContactPhoto;
import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.SessionContactDatabase;
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import network.loki.messenger.R;
public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder {
@ -58,6 +63,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
{
super(context, privacy);
setSmallIcon(R.drawable.ic_notification);
setColor(context.getResources().getColor(R.color.textsecure_primary));
setCategory(NotificationCompat.CATEGORY_MESSAGE);
@ -198,6 +204,10 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
return R.string.MessageNotifier_reply;
}
public void putStringExtra(String key, String value) {
extras.putString(key,value);
}
public void addMessageBody(@NonNull Recipient threadRecipient,
@NonNull Recipient individualRecipient,
@Nullable CharSequence messageBody)

View File

@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="4.622348dp"
android:height="5.15937dp"
android:viewportWidth="4.622348"
android:viewportHeight="5.15937"
android:tint="?attr/colorControlNormal">
<path
android:pathData="m2.11667,0.00001c-0.2196,0 -0.39687,0.17727 -0.39687,0.39687v0.18035c-0.75671,0.17992 -1.19062,0.85682 -1.19062,1.67174v1.32291l-0.52917,0.52917v0.26458h4.23333v-0.26458l-0.52917,-0.52917v-0.22427h-0.28939c-0.06727,0 -0.13303,-0.006 -0.19792,-0.015v0.21601,0.32969l-2.15852,-0.0418v-1.5875c0,-0.65617 0.39952,-1.19063 1.05833,-1.19063 0.02183,0 0.04274,0.002 0.06408,0.004 0.11927,-0.18142 0.27784,-0.33414 0.46302,-0.44803 -0.04232,-0.0139 -0.08562,-0.0261 -0.13023,-0.0367v-0.18035c0,-0.2196 -0.17727,-0.39687 -0.39687,-0.39687zM1.5875,4.63021c0,0.29104 0.23812,0.52916 0.52917,0.52916 0.29104,0 0.52917,-0.23812 0.52917,-0.52916z"
android:strokeWidth="0.26458332"
android:fillColor="#000000"/>
<path
android:pathData="m3.35531,0.57755c-0.6994,0 -1.26703,0.56762 -1.26703,1.26702 0,0.6994 0.56763,1.26703 1.26703,1.26703h0.63351v-0.2534h-0.63351c-0.54989,0 -1.01362,-0.46374 -1.01362,-1.01363 0,-0.54989 0.46373,-1.01362 1.01362,-1.01362 0.54989,0 1.01362,0.46373 1.01362,1.01362v0.18119c0,0.10009 -0.08996,0.19892 -0.19005,0.19892 -0.1001,0 -0.19005,-0.0988 -0.19005,-0.19892v-0.18119c0,-0.3497 -0.28381,-0.63351 -0.63351,-0.63351 -0.3497,0 -0.63351,0.28381 -0.63351,0.63351 0,0.3497 0.28381,0.63352 0.63351,0.63352 0.17485,0 0.3345,-0.071 0.44853,-0.18625 0.08236,0.11276 0.22426,0.18625 0.37504,0.18625 0.2496,0 0.44346,-0.20273 0.44346,-0.45233v-0.18119c0,-0.6994 -0.56763,-1.26702 -1.26703,-1.26702zM3.35531,2.22468c-0.21033,0 -0.38011,-0.16978 -0.38011,-0.38011 0,-0.21032 0.16978,-0.3801 0.38011,-0.3801 0.21033,0 0.38011,0.16978 0.38011,0.3801 0,0.21033 -0.16978,0.38011 -0.38011,0.38011z"
android:strokeWidth="0.12670289"
android:fillColor="#000000"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M10.01,21.01c0,1.1 0.89,1.99 1.99,1.99s1.99,-0.89 1.99,-1.99h-3.98zM12,6c2.76,0 5,2.24 5,5v7L7,18v-7c0,-2.76 2.24,-5 5,-5zM12,1.5c-0.83,0 -1.5,0.67 -1.5,1.5v1.17C7.36,4.85 5,7.65 5,11v6l-2,2v1h18v-1l-2,-2v-6c0,-3.35 -2.36,-6.15 -5.5,-6.83L13.5,3c0,-0.83 -0.67,-1.5 -1.5,-1.5zM11,8h2v4h-2zM11,14h2v2h-2z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zM18,16v-5c0,-3.07 -1.63,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.64,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2zM16,17L8,17v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5v6zM7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42z"/>
</vector>

View File

@ -32,6 +32,33 @@
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/muteNotificationsTextView"
style="@style/BottomSheetActionItem"
android:drawableStart="@drawable/ic_outline_notifications_off_24"
android:text="@string/MuteDialog_mute_notifications"
tools:visibility="visible"
android:visibility="gone"
/>
<TextView
android:id="@+id/unMuteNotificationsTextView"
style="@style/BottomSheetActionItem"
android:drawableStart="@drawable/ic_outline_notifications_active_24"
android:text="@string/conversation_muted__unmute"
tools:visibility="visible"
android:visibility="gone"
/>
<TextView
android:id="@+id/notificationsTextView"
style="@style/BottomSheetActionItem"
android:drawableStart="@drawable/ic_outline_notification_important_24"
android:text="@string/RecipientPreferenceActivity_notification_settings"
tools:visibility="visible"
android:visibility="gone"
/>
<TextView
android:id="@+id/deleteTextView"
style="@style/BottomSheetActionItem"

View File

@ -13,4 +13,8 @@
android:title="@string/conversation__menu_leave_group"
app:showAsAction="collapseActionView"/>
<item
android:title="@string/RecipientPreferenceActivity_notification_settings"
android:id="@+id/menu_notification_settings"/>
</menu>

View File

@ -6,4 +6,8 @@
android:title="@string/ConversationActivity_invite_to_open_group"
android:id="@+id/menu_invite_to_open_group" />
<item
android:title="@string/RecipientPreferenceActivity_notification_settings"
android:id="@+id/menu_notification_settings"/>
</menu>

View File

@ -187,7 +187,7 @@
<item>@string/arrays__mute_for_two_hours</item>
<item>@string/arrays__mute_for_one_day</item>
<item>@string/arrays__mute_for_seven_days</item>
<item>@string/arrays__mute_for_one_year</item>
<item>@string/arrays__mute_forever</item>
</string-array>
<string-array name="pref_notification_privacy_entries">
@ -244,5 +244,10 @@
<item>1</item>
<item>2</item>
</string-array>
<string-array name="notify_types">
<item>@string/notify_type_all</item>
<item>@string/notify_type_mentions</item>
<item>@string/notify_type_none</item>
</string-array>
</resources>

View File

@ -75,6 +75,7 @@
<string name="ConversationActivity_message">Message</string>
<string name="ConversationActivity_compose">Compose</string>
<string name="ConversationActivity_muted_until_date">Muted until %1$s</string>
<string name="ConversationActivity_muted_forever">Muted forever</string>
<string name="ConversationActivity_member_count">%1$d members</string>
<string name="ConversationActivity_open_group_guidelines">Community Guidelines</string>
@ -247,6 +248,7 @@
<string name="RecipientPreferenceActivity_unblock_this_contact_question">Unblock this contact?</string>
<string name="RecipientPreferenceActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact">You will once again be able to receive messages and calls from this contact.</string>
<string name="RecipientPreferenceActivity_unblock">Unblock</string>
<string name="RecipientPreferenceActivity_notification_settings">Notification Settings</string>
<!-- Slide -->
<string name="Slide_image">Image</string>
@ -481,6 +483,7 @@
<string name="arrays__mute_for_one_day">Mute for 1 day</string>
<string name="arrays__mute_for_seven_days">Mute for 7 days</string>
<string name="arrays__mute_for_one_year">Mute for 1 year</string>
<string name="arrays__mute_forever">Mute forever</string>
<string name="arrays__settings_default">Settings default</string>
<string name="arrays__enabled">Enabled</string>
@ -888,4 +891,7 @@
<string name="dialog_send_seed_title">Warning</string>
<string name="dialog_send_seed_explanation">This is your recovery phrase. If you send it to someone they\'ll have full access to your account.</string>
<string name="dialog_send_seed_send_button_title">Send</string>
<string name="notify_type_all">All</string>
<string name="notify_type_mentions">Mentions</string>
<string name="notify_type_none">None</string>
</resources>

View File

@ -26,29 +26,28 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.function.Consumer;
import com.esotericsoftware.kryo.util.Null;
import org.greenrobot.eventbus.EventBus;
import org.session.libsession.database.StorageProtocol;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.avatars.TransparentContactPhoto;
import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.recipients.RecipientProvider.RecipientDetails;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.avatars.ContactColors;
import org.session.libsession.avatars.ContactPhoto;
import org.session.libsession.avatars.GroupRecordContactPhoto;
import org.session.libsession.avatars.ProfileContactPhoto;
import org.session.libsession.avatars.SystemContactPhoto;
import org.session.libsession.utilities.ProfilePictureModifiedEvent;
import org.session.libsession.avatars.TransparentContactPhoto;
import org.session.libsession.database.StorageProtocol;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.FutureTaskListener;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.ListenableFutureTask;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.ProfilePictureModifiedEvent;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.RecipientProvider.RecipientDetails;
import org.session.libsignal.utilities.Log;
import org.session.libsignal.utilities.guava.Optional;
import java.util.Collections;
import java.util.HashSet;
@ -80,6 +79,7 @@ public class Recipient implements RecipientModifiedListener {
private @Nullable Uri messageRingtone = null;
private @Nullable Uri callRingtone = null;
public long mutedUntil = 0;
public int notifyType = 0;
private boolean blocked = false;
private VibrateState messageVibrate = VibrateState.DEFAULT;
private VibrateState callVibrate = VibrateState.DEFAULT;
@ -249,6 +249,7 @@ public class Recipient implements RecipientModifiedListener {
this.messageRingtone = details.messageRingtone;
this.callRingtone = details.callRingtone;
this.mutedUntil = details.mutedUntil;
this.notifyType = details.notifyType;
this.blocked = details.blocked;
this.messageVibrate = details.messageVibrateState;
this.callVibrate = details.callVibrateState;
@ -547,6 +548,14 @@ public class Recipient implements RecipientModifiedListener {
notifyListeners();
}
public void setNotifyType(int notifyType) {
synchronized (this) {
this.notifyType = notifyType;
}
notifyListeners();
}
public synchronized boolean isBlocked() {
return blocked;
}
@ -769,6 +778,7 @@ public class Recipient implements RecipientModifiedListener {
public static class RecipientSettings {
private final boolean blocked;
private final long muteUntil;
private final int notifyType;
private final VibrateState messageVibrateState;
private final VibrateState callVibrateState;
private final Uri messageRingtone;
@ -790,6 +800,7 @@ public class Recipient implements RecipientModifiedListener {
private final boolean forceSmsSelection;
public RecipientSettings(boolean blocked, long muteUntil,
int notifyType,
@NonNull VibrateState messageVibrateState,
@NonNull VibrateState callVibrateState,
@Nullable Uri messageRingtone,
@ -812,6 +823,7 @@ public class Recipient implements RecipientModifiedListener {
{
this.blocked = blocked;
this.muteUntil = muteUntil;
this.notifyType = notifyType;
this.messageVibrateState = messageVibrateState;
this.callVibrateState = callVibrateState;
this.messageRingtone = messageRingtone;
@ -845,6 +857,10 @@ public class Recipient implements RecipientModifiedListener {
return muteUntil;
}
public int getNotifyType() {
return notifyType;
}
public @NonNull VibrateState getMessageVibrateState() {
return messageVibrateState;
}

View File

@ -23,19 +23,20 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsession.R;
import org.session.libsession.messaging.MessagingModuleConfiguration;
import org.session.libsignal.utilities.guava.Optional;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.GroupRecord;
import org.session.libsession.utilities.ListenableFutureTask;
import org.session.libsession.utilities.MaterialColor;
import org.session.libsession.utilities.SoftHashMap;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
import org.session.libsession.utilities.recipients.Recipient.RegisteredState;
import org.session.libsession.utilities.recipients.Recipient.UnidentifiedAccessMode;
import org.session.libsession.utilities.recipients.Recipient.VibrateState;
import org.session.libsession.utilities.ListenableFutureTask;
import org.session.libsession.utilities.SoftHashMap;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
import org.session.libsignal.utilities.guava.Optional;
import java.util.HashMap;
import java.util.LinkedList;
@ -44,8 +45,6 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import org.session.libsession.R;
class RecipientProvider {
@SuppressWarnings("unused")
@ -168,6 +167,7 @@ class RecipientProvider {
@Nullable final Uri messageRingtone;
@Nullable final Uri callRingtone;
final long mutedUntil;
final int notifyType;
@Nullable final VibrateState messageVibrateState;
@Nullable final VibrateState callVibrateState;
final boolean blocked;
@ -197,6 +197,7 @@ class RecipientProvider {
this.messageRingtone = settings != null ? settings.getMessageRingtone() : null;
this.callRingtone = settings != null ? settings.getCallRingtone() : null;
this.mutedUntil = settings != null ? settings.getMuteUntil() : 0;
this.notifyType = settings != null ? settings.getNotifyType() : 0;
this.messageVibrateState = settings != null ? settings.getMessageVibrateState() : null;
this.callVibrateState = settings != null ? settings.getCallVibrateState() : null;
this.blocked = settings != null && settings.isBlocked();