mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Merge pull request #682 from hjubb/startup_performance
Startup Time & UX Improvements
This commit is contained in:
commit
3d57adc465
@ -35,7 +35,6 @@ dependencies {
|
|||||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||||
implementation 'androidx.exifinterface:exifinterface:1.2.0'
|
implementation 'androidx.exifinterface:exifinterface:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-common-java8:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-common-java8:2.3.1'
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms;
|
package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@ -26,7 +27,6 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||||
import androidx.multidex.MultiDexApplication;
|
|
||||||
|
|
||||||
import org.conscrypt.Conscrypt;
|
import org.conscrypt.Conscrypt;
|
||||||
import org.session.libsession.avatars.AvatarHelper;
|
import org.session.libsession.avatars.AvatarHelper;
|
||||||
@ -104,7 +104,7 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
|
|||||||
*
|
*
|
||||||
* @author Moxie Marlinspike
|
* @author Moxie Marlinspike
|
||||||
*/
|
*/
|
||||||
public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver {
|
public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver {
|
||||||
|
|
||||||
public static final String PREFERENCES_NAME = "SecureSMS-Preferences";
|
public static final String PREFERENCES_NAME = "SecureSMS-Preferences";
|
||||||
|
|
||||||
@ -180,12 +180,15 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
Log.i(TAG, "App is now visible.");
|
Log.i(TAG, "App is now visible.");
|
||||||
KeyCachingService.onAppForegrounded(this);
|
KeyCachingService.onAppForegrounded(this);
|
||||||
|
|
||||||
|
ThreadUtils.queue(()->{
|
||||||
if (poller != null) {
|
if (poller != null) {
|
||||||
poller.setCaughtUp(false);
|
poller.setCaughtUp(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
startPollingIfNeeded();
|
startPollingIfNeeded();
|
||||||
|
|
||||||
OpenGroupManager.INSTANCE.startPolling();
|
OpenGroupManager.INSTANCE.startPolling();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,10 +87,7 @@ import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper
|
|||||||
import org.thoughtcrime.securesms.conversation.v2.messages.*
|
import org.thoughtcrime.securesms.conversation.v2.messages.*
|
||||||
import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar
|
import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar
|
||||||
import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel
|
import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager
|
import org.thoughtcrime.securesms.conversation.v2.utilities.*
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.ResendMessageUtilities
|
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
|
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
@ -230,6 +227,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
setUpRecyclerView()
|
setUpRecyclerView()
|
||||||
setUpToolBar()
|
setUpToolBar()
|
||||||
setUpInputBar()
|
setUpInputBar()
|
||||||
|
setUpLinkPreviewObserver()
|
||||||
restoreDraftIfNeeded()
|
restoreDraftIfNeeded()
|
||||||
addOpenGroupGuidelinesIfNeeded()
|
addOpenGroupGuidelinesIfNeeded()
|
||||||
scrollToBottomButton.setOnClickListener { conversationRecyclerView.smoothScrollToPosition(0) }
|
scrollToBottomButton.setOnClickListener { conversationRecyclerView.smoothScrollToPosition(0) }
|
||||||
@ -240,7 +238,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
updateSubtitle()
|
updateSubtitle()
|
||||||
getLatestOpenGroupInfoIfNeeded()
|
getLatestOpenGroupInfoIfNeeded()
|
||||||
setUpBlockedBanner()
|
setUpBlockedBanner()
|
||||||
setUpLinkPreviewObserver()
|
|
||||||
searchBottomBar.setEventListener(this)
|
searchBottomBar.setEventListener(this)
|
||||||
setUpSearchResultObserver()
|
setUpSearchResultObserver()
|
||||||
scrollToFirstUnreadMessageIfNeeded()
|
scrollToFirstUnreadMessageIfNeeded()
|
||||||
@ -322,6 +319,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
val size = resources.getDimension(sizeID).roundToInt()
|
val size = resources.getDimension(sizeID).roundToInt()
|
||||||
profilePictureView.layoutParams = LinearLayout.LayoutParams(size, size)
|
profilePictureView.layoutParams = LinearLayout.LayoutParams(size, size)
|
||||||
profilePictureView.glide = glide
|
profilePictureView.glide = glide
|
||||||
|
MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded(threadID, this)
|
||||||
profilePictureView.update(thread, threadID)
|
profilePictureView.update(thread, threadID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1206,7 +1204,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
val sortedMessages = messages.sortedBy { it.dateSent }
|
val sortedMessages = messages.sortedBy { it.dateSent }
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
for (message in sortedMessages) {
|
for (message in sortedMessages) {
|
||||||
val body = MentionUtilities.highlightMentions(message.body, message.threadId, this)
|
val body = MentionUtilities.highlightMentions(message.body, threadID, this)
|
||||||
if (TextUtils.isEmpty(body)) { continue }
|
if (TextUtils.isEmpty(body)) { continue }
|
||||||
val formattedTimestamp = DateUtils.getDisplayFormattedTimeSpanString(this, Locale.getDefault(), message.timestamp)
|
val formattedTimestamp = DateUtils.getDisplayFormattedTimeSpanString(this, Locale.getDefault(), message.timestamp)
|
||||||
builder.append("$formattedTimestamp: $body").append('\n')
|
builder.append("$formattedTimestamp: $body").append('\n')
|
||||||
|
@ -10,7 +10,6 @@ import androidx.annotation.ColorInt
|
|||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.text.toSpannable
|
import androidx.core.text.toSpannable
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import kotlinx.android.synthetic.main.view_link_preview.view.*
|
|
||||||
import kotlinx.android.synthetic.main.view_quote.view.*
|
import kotlinx.android.synthetic.main.view_quote.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
|
@ -10,10 +10,9 @@ import android.os.Bundle
|
|||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.util.DisplayMetrics
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.RelativeLayout
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.loader.app.LoaderManager
|
import androidx.loader.app.LoaderManager
|
||||||
@ -21,9 +20,11 @@ import androidx.loader.content.Loader
|
|||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import kotlinx.android.synthetic.main.activity_home.*
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
|
import kotlinx.android.synthetic.main.seed_reminder_stub.view.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
@ -65,8 +66,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||||
super.onCreate(savedInstanceState, isReady)
|
super.onCreate(savedInstanceState, isReady)
|
||||||
// Double check that the long poller is up
|
|
||||||
(applicationContext as ApplicationContext).startPollingIfNeeded()
|
|
||||||
// Set content view
|
// Set content view
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
// Set custom toolbar
|
// Set custom toolbar
|
||||||
@ -75,21 +74,24 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
glide = GlideApp.with(this)
|
glide = GlideApp.with(this)
|
||||||
// Set up toolbar buttons
|
// Set up toolbar buttons
|
||||||
profileButton.glide = glide
|
profileButton.glide = glide
|
||||||
updateProfileButton()
|
|
||||||
profileButton.setOnClickListener { openSettings() }
|
profileButton.setOnClickListener { openSettings() }
|
||||||
pathStatusViewContainer.disableClipping()
|
pathStatusViewContainer.disableClipping()
|
||||||
pathStatusViewContainer.setOnClickListener { showPath() }
|
pathStatusViewContainer.setOnClickListener { showPath() }
|
||||||
// Set up seed reminder view
|
// Set up seed reminder view
|
||||||
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
||||||
if (!hasViewedSeed) {
|
if (!hasViewedSeed) {
|
||||||
|
seedReminderStub.isVisible = true
|
||||||
|
seedReminderStub.apply {
|
||||||
|
val seedReminderView = this.seedReminderView
|
||||||
val seedReminderViewTitle = SpannableString("You're almost finished! 80%") // Intentionally not yet translated
|
val seedReminderViewTitle = SpannableString("You're almost finished! 80%") // Intentionally not yet translated
|
||||||
seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
seedReminderView.title = seedReminderViewTitle
|
seedReminderView.title = seedReminderViewTitle
|
||||||
seedReminderView.subtitle = resources.getString(R.string.view_seed_reminder_subtitle_1)
|
seedReminderView.subtitle = resources.getString(R.string.view_seed_reminder_subtitle_1)
|
||||||
seedReminderView.setProgress(80, false)
|
seedReminderView.setProgress(80, false)
|
||||||
seedReminderView.delegate = this
|
seedReminderView.delegate = this@HomeActivity
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
seedReminderView.visibility = View.GONE
|
seedReminderStub.isVisible = false
|
||||||
}
|
}
|
||||||
// Set up recycler view
|
// Set up recycler view
|
||||||
val cursor = DatabaseFactory.getThreadDatabase(this).conversationList
|
val cursor = DatabaseFactory.getThreadDatabase(this).conversationList
|
||||||
@ -101,6 +103,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
// Set up empty state view
|
// Set up empty state view
|
||||||
createNewPrivateChatButton.setOnClickListener { createNewPrivateChat() }
|
createNewPrivateChatButton.setOnClickListener { createNewPrivateChat() }
|
||||||
|
IP2Country.configureIfNeeded(this@HomeActivity)
|
||||||
// This is a workaround for the fact that CursorRecyclerViewAdapter doesn't actually auto-update (even though it says it will)
|
// This is a workaround for the fact that CursorRecyclerViewAdapter doesn't actually auto-update (even though it says it will)
|
||||||
LoaderManager.getInstance(this).restartLoader(0, null, object : LoaderManager.LoaderCallbacks<Cursor> {
|
LoaderManager.getInstance(this).restartLoader(0, null, object : LoaderManager.LoaderCallbacks<Cursor> {
|
||||||
|
|
||||||
@ -117,28 +120,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
homeAdapter.changeCursor(null)
|
homeAdapter.changeCursor(null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Set up gradient view
|
|
||||||
val gradientViewLayoutParams = gradientView.layoutParams as RelativeLayout.LayoutParams
|
|
||||||
val displayMetrics = DisplayMetrics()
|
|
||||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
|
||||||
val height = displayMetrics.heightPixels
|
|
||||||
gradientViewLayoutParams.topMargin = (0.15 * height.toFloat()).toInt()
|
|
||||||
// Set up new conversation button set
|
// Set up new conversation button set
|
||||||
newConversationButtonSet.delegate = this
|
newConversationButtonSet.delegate = this
|
||||||
// Set up typing observer
|
|
||||||
ApplicationContext.getInstance(this).typingStatusRepository.typingThreads.observe(this, Observer<Set<Long>> { threadIDs ->
|
|
||||||
val adapter = recyclerView.adapter as HomeAdapter
|
|
||||||
adapter.typingThreadIDs = threadIDs ?: setOf()
|
|
||||||
})
|
|
||||||
// Set up remaining components if needed
|
|
||||||
val application = ApplicationContext.getInstance(this)
|
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
|
|
||||||
if (userPublicKey != null) {
|
|
||||||
OpenGroupManager.startPolling()
|
|
||||||
JobQueue.shared.resumePendingJobs()
|
|
||||||
}
|
|
||||||
IP2Country.configureIfNeeded(this)
|
|
||||||
application.registerForFCMIfNeeded(false)
|
|
||||||
// Observe blocked contacts changed events
|
// Observe blocked contacts changed events
|
||||||
val broadcastReceiver = object : BroadcastReceiver() {
|
val broadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
|
||||||
@ -148,12 +131,32 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
}
|
}
|
||||||
this.broadcastReceiver = broadcastReceiver
|
this.broadcastReceiver = broadcastReceiver
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, IntentFilter("blockedContactsChanged"))
|
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, IntentFilter("blockedContactsChanged"))
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launchWhenStarted {
|
||||||
|
launch(Dispatchers.IO) {
|
||||||
|
// Double check that the long poller is up
|
||||||
|
(applicationContext as ApplicationContext).startPollingIfNeeded()
|
||||||
// update things based on TextSecurePrefs (profile info etc)
|
// update things based on TextSecurePrefs (profile info etc)
|
||||||
|
// Set up typing observer
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
ApplicationContext.getInstance(this@HomeActivity).typingStatusRepository.typingThreads.observe(this@HomeActivity, Observer<Set<Long>> { threadIDs ->
|
||||||
|
val adapter = recyclerView.adapter as HomeAdapter
|
||||||
|
adapter.typingThreadIDs = threadIDs ?: setOf()
|
||||||
|
})
|
||||||
|
updateProfileButton()
|
||||||
TextSecurePreferences.events.filter { it == TextSecurePreferences.PROFILE_NAME_PREF }.collect {
|
TextSecurePreferences.events.filter { it == TextSecurePreferences.PROFILE_NAME_PREF }.collect {
|
||||||
updateProfileButton()
|
updateProfileButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set up remaining components if needed
|
||||||
|
val application = ApplicationContext.getInstance(this@HomeActivity)
|
||||||
|
application.registerForFCMIfNeeded(false)
|
||||||
|
val userPublicKey = TextSecurePreferences.getLocalNumber(this@HomeActivity)
|
||||||
|
if (userPublicKey != null) {
|
||||||
|
OpenGroupManager.startPolling()
|
||||||
|
JobQueue.shared.resumePendingJobs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
EventBus.getDefault().register(this@HomeActivity)
|
EventBus.getDefault().register(this@HomeActivity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +169,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis
|
|||||||
profileButton.update()
|
profileButton.update()
|
||||||
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this)
|
||||||
if (hasViewedSeed) {
|
if (hasViewedSeed) {
|
||||||
seedReminderView.visibility = View.GONE
|
seedReminderStub.visibility = View.GONE
|
||||||
}
|
}
|
||||||
if (TextSecurePreferences.getConfigurationMessageSynced(this)) {
|
if (TextSecurePreferences.getConfigurationMessageSynced(this)) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
|
|||||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
|
|
||||||
class HomeAdapter(context: Context, cursor: Cursor) : CursorRecyclerViewAdapter<HomeAdapter.ViewHolder>(context, cursor) {
|
class HomeAdapter(context: Context, cursor: Cursor?) : CursorRecyclerViewAdapter<HomeAdapter.ViewHolder>(context, cursor) {
|
||||||
private val threadDatabase = DatabaseFactory.getThreadDatabase(context)
|
private val threadDatabase = DatabaseFactory.getThreadDatabase(context)
|
||||||
lateinit var glide: GlideRequests
|
lateinit var glide: GlideRequests
|
||||||
var typingThreadIDs = setOf<Long>()
|
var typingThreadIDs = setOf<Long>()
|
||||||
|
@ -40,6 +40,7 @@ import androidx.core.app.NotificationCompat;
|
|||||||
import androidx.core.app.NotificationManagerCompat;
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier;
|
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier;
|
||||||
|
import org.session.libsession.utilities.Address;
|
||||||
import org.session.libsession.utilities.Contact;
|
import org.session.libsession.utilities.Contact;
|
||||||
import org.session.libsession.utilities.ServiceUtil;
|
import org.session.libsession.utilities.ServiceUtil;
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
@ -49,6 +50,7 @@ import org.session.libsignal.utilities.Util;
|
|||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
import org.thoughtcrime.securesms.contactshare.ContactUtil;
|
import org.thoughtcrime.securesms.contactshare.ContactUtil;
|
||||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2;
|
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2;
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionManagerUtilities;
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities;
|
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||||
@ -58,6 +60,7 @@ import org.thoughtcrime.securesms.database.ThreadDatabase;
|
|||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||||
|
import org.thoughtcrime.securesms.database.model.Quote;
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
|
import org.thoughtcrime.securesms.util.SessionMetaProtocol;
|
||||||
@ -66,6 +69,7 @@ import org.thoughtcrime.securesms.util.SpanUtil;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -273,9 +277,13 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
lastAudibleNotification = System.currentTimeMillis();
|
lastAudibleNotification = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasMultipleThreads = notificationState.hasMultipleThreads();
|
if (notificationState.hasMultipleThreads()) {
|
||||||
for (long threadId : notificationState.getThreads()) {
|
for (long threadId : notificationState.getThreads()) {
|
||||||
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), signal, hasMultipleThreads);
|
sendSingleThreadNotification(context, new NotificationState(notificationState.getNotificationsForThread(threadId)), false, true);
|
||||||
|
}
|
||||||
|
sendMultipleThreadNotification(context, notificationState, signal);
|
||||||
|
} else if (notificationState.getMessageCount() > 0){
|
||||||
|
sendSingleThreadNotification(context, notificationState, signal, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelOrphanedNotifications(context, notificationState);
|
cancelOrphanedNotifications(context, notificationState);
|
||||||
@ -323,8 +331,11 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
|
|
||||||
builder.setThread(notifications.get(0).getRecipient());
|
builder.setThread(notifications.get(0).getRecipient());
|
||||||
builder.setMessageCount(notificationState.getMessageCount());
|
builder.setMessageCount(notificationState.getMessageCount());
|
||||||
|
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(notifications.get(0).getThreadId(),context);
|
||||||
builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(),
|
builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(),
|
||||||
MentionUtilities.highlightMentions(notifications.get(0).getText(), notifications.get(0).getThreadId(), context),
|
MentionUtilities.highlightMentions(notifications.get(0).getText(),
|
||||||
|
notifications.get(0).getThreadId(),
|
||||||
|
context),
|
||||||
notifications.get(0).getSlideDeck());
|
notifications.get(0).getSlideDeck());
|
||||||
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
builder.setContentIntent(notifications.get(0).getPendingIntent(context));
|
||||||
builder.setDeleteIntent(notificationState.getDeleteIntent(context));
|
builder.setDeleteIntent(notificationState.getDeleteIntent(context));
|
||||||
@ -497,7 +508,15 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
if (threadRecipients == null || !threadRecipients.isMuted()) {
|
if (threadRecipients == null || !threadRecipients.isMuted()) {
|
||||||
if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_MENTIONS) {
|
if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_MENTIONS) {
|
||||||
// check if mentioned here
|
// check if mentioned here
|
||||||
if (body.toString().contains("@"+TextSecurePreferences.getLocalNumber(context))) {
|
boolean isQuoteMentioned = false;
|
||||||
|
if (record instanceof MmsMessageRecord) {
|
||||||
|
Quote quote = ((MmsMessageRecord) record).getQuote();
|
||||||
|
Address quoteAddress = quote != null ? quote.getAuthor() : null;
|
||||||
|
String serializedAddress = quoteAddress != null ? quoteAddress.serialize() : null;
|
||||||
|
isQuoteMentioned = serializedAddress != null && Objects.equals(TextSecurePreferences.getLocalNumber(context), serializedAddress);
|
||||||
|
}
|
||||||
|
if (body.toString().contains("@"+TextSecurePreferences.getLocalNumber(context))
|
||||||
|
|| isQuoteMentioned) {
|
||||||
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, slideDeck));
|
notificationState.addNotification(new NotificationItem(id, mms, recipient, conversationRecipient, threadRecipients, threadId, body, timestamp, slideDeck));
|
||||||
}
|
}
|
||||||
} else if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_NONE) {
|
} else if (threadRecipients != null && threadRecipients.notifyType == RecipientDatabase.NOTIFY_TYPE_NONE) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
|
|
||||||
<gradient
|
<gradient
|
||||||
|
android:centerY="0.75"
|
||||||
android:centerColor="?attr/home_gradient_start"
|
android:centerColor="?attr/home_gradient_start"
|
||||||
android:endColor="?attr/home_gradient_end"
|
android:endColor="?attr/home_gradient_end"
|
||||||
android:angle="270" />
|
android:angle="270" />
|
||||||
|
@ -70,8 +70,9 @@
|
|||||||
android:background="?android:dividerHorizontal"
|
android:background="?android:dividerHorizontal"
|
||||||
android:elevation="1dp" />
|
android:elevation="1dp" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.onboarding.SeedReminderView
|
<ViewStub
|
||||||
android:id="@+id/seedReminderView"
|
android:id="@+id/seedReminderStub"
|
||||||
|
android:layout="@layout/seed_reminder_stub"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
|
6
app/src/main/res/layout/seed_reminder_stub.xml
Normal file
6
app/src/main/res/layout/seed_reminder_stub.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<org.thoughtcrime.securesms.onboarding.SeedReminderView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/seedReminderView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
Loading…
x
Reference in New Issue
Block a user