mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-24 02:25:19 +00:00
Fix banner display
This commit is contained in:
parent
97ffea040f
commit
b44ff69d8d
@ -51,12 +51,10 @@
|
|||||||
android:inflatedId="@+id/unverified_banner"
|
android:inflatedId="@+id/unverified_banner"
|
||||||
android:layout="@layout/conversation_activity_unverified_banner_stub" />
|
android:layout="@layout/conversation_activity_unverified_banner_stub" />
|
||||||
|
|
||||||
<ViewStub
|
<org.thoughtcrime.securesms.loki.SessionRestoreBannerView
|
||||||
android:id="@+id/session_restore_banner_stub"
|
android:id="@+id/sessionRestoreBannerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:inflatedId="@+id/session_restore_banner"
|
|
||||||
android:layout="@layout/conversation_activity_unverified_banner_stub" />
|
|
||||||
|
|
||||||
<ViewStub
|
<ViewStub
|
||||||
android:id="@+id/reminder_stub"
|
android:id="@+id/reminder_stub"
|
||||||
|
@ -1,31 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/session_restore_banner"
|
android:id="@+id/sessionRestoreBanner"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/core_grey_60"
|
android:background="@color/core_grey_60"
|
||||||
android:focusable="true"
|
|
||||||
android:nextFocusDown="@+id/cancel"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingStart="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingTop="24dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingEnd="8dp"
|
android:paddingRight="8dp"
|
||||||
android:paddingBottom="8dp"
|
android:visibility="visible"
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/restoreTitle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="18sp"
|
|
||||||
tools:text="@string/session_restore_banner_title" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/restoreText"
|
android:id="@+id/restoreText"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -40,7 +26,6 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
@ -48,7 +33,8 @@
|
|||||||
android:id="@+id/dismissButton"
|
android:id="@+id/dismissButton"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="36dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
android:text="@string/session_restore_banner_dismiss_button_title" />
|
android:text="@string/session_restore_banner_dismiss_button_title" />
|
||||||
|
|
||||||
<android.support.v4.widget.Space
|
<android.support.v4.widget.Space
|
||||||
@ -59,7 +45,8 @@
|
|||||||
android:id="@+id/restoreButton"
|
android:id="@+id/restoreButton"
|
||||||
style="@style/Button.Borderless"
|
style="@style/Button.Borderless"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="36dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
android:text="@string/session_restore_banner_restore_button_title" />
|
android:text="@string/session_restore_banner_restore_button_title" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private boolean isFriendsWithAnyDevice = false;
|
private boolean isFriendsWithAnyDevice = false;
|
||||||
|
|
||||||
// Restoration
|
// Restoration
|
||||||
protected Stub<SessionRestoreBannerView> sessionRestoreBannerView;
|
protected SessionRestoreBannerView sessionRestoreBannerView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreCreate() {
|
protected void onPreCreate() {
|
||||||
@ -428,6 +428,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sessionRestoreBannerView.setOnRestore(() -> {
|
||||||
|
this.restoreSession();
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
sessionRestoreBannerView.setOnDismiss(() -> {
|
||||||
|
// TODO: Maybe silence for x minutes?
|
||||||
|
DatabaseFactory.getLokiThreadDatabase(ConversationActivity.this).removeAllSessionRestoreDevices(threadId);
|
||||||
|
updateSessionRestoreBanner();
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
|
||||||
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, this);
|
LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, this);
|
||||||
|
|
||||||
if (this.recipient.isGroupRecipient()) {
|
if (this.recipient.isGroupRecipient()) {
|
||||||
@ -496,6 +507,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
DatabaseFactory.getLokiThreadDatabase(this).setDelegate(this);
|
DatabaseFactory.getLokiThreadDatabase(this).setDelegate(this);
|
||||||
updateInputPanel();
|
updateInputPanel();
|
||||||
|
|
||||||
|
updateSessionRestoreBanner();
|
||||||
|
|
||||||
Log.i(TAG, "onResume() Finished: " + (System.currentTimeMillis() - getIntent().getLongExtra(TIMING_EXTRA, 0)));
|
Log.i(TAG, "onResume() Finished: " + (System.currentTimeMillis() - getIntent().getLongExtra(TIMING_EXTRA, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,11 +1509,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
|
|
||||||
protected void updateSessionRestoreBanner() {
|
protected void updateSessionRestoreBanner() {
|
||||||
Set<String> devices = DatabaseFactory.getLokiThreadDatabase(this).getSessionRestoreDevices(threadId);
|
Set<String> devices = DatabaseFactory.getLokiThreadDatabase(this).getSessionRestoreDevices(threadId);
|
||||||
SessionRestoreBannerView view = sessionRestoreBannerView.get();
|
|
||||||
if (devices.size() > 0) {
|
if (devices.size() > 0) {
|
||||||
view.show();
|
sessionRestoreBannerView.update(recipient);
|
||||||
|
sessionRestoreBannerView.show();
|
||||||
} else {
|
} else {
|
||||||
view.hide();
|
sessionRestoreBannerView.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1600,18 +1613,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
inputPanel = ViewUtil.findById(this, R.id.bottom_panel);
|
inputPanel = ViewUtil.findById(this, R.id.bottom_panel);
|
||||||
searchNav = ViewUtil.findById(this, R.id.conversation_search_nav);
|
searchNav = ViewUtil.findById(this, R.id.conversation_search_nav);
|
||||||
mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView);
|
mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView);
|
||||||
sessionRestoreBannerView = ViewUtil.findStubById(this, R.id.session_restore_banner_stub);
|
sessionRestoreBannerView = ViewUtil.findById(this, R.id.sessionRestoreBannerView);
|
||||||
sessionRestoreBannerView.get().setRecipient(recipient);
|
|
||||||
sessionRestoreBannerView.get().setOnRestore(() -> {
|
|
||||||
this.restoreSession();
|
|
||||||
return Unit.INSTANCE;
|
|
||||||
});
|
|
||||||
sessionRestoreBannerView.get().setOnDismiss(() -> {
|
|
||||||
// TODO: Maybe silence for x minutes?
|
|
||||||
// TODO: Remove devices?
|
|
||||||
sessionRestoreBannerView.get().hide();
|
|
||||||
return Unit.INSTANCE;
|
|
||||||
});
|
|
||||||
|
|
||||||
ImageButton quickCameraToggle = ViewUtil.findById(this, R.id.quick_camera_toggle);
|
ImageButton quickCameraToggle = ViewUtil.findById(this, R.id.quick_camera_toggle);
|
||||||
ImageButton inlineAttachmentButton = ViewUtil.findById(this, R.id.inline_attachment_button);
|
ImageButton inlineAttachmentButton = ViewUtil.findById(this, R.id.inline_attachment_button);
|
||||||
@ -2233,7 +2235,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
@Override
|
@Override
|
||||||
public void handleSessionRestoreDevicesChanged(long threadId) {
|
public void handleSessionRestoreDevicesChanged(long threadId) {
|
||||||
if (threadId == this.threadId) {
|
if (threadId == this.threadId) {
|
||||||
updateSessionRestoreBanner();
|
runOnUiThread(this::updateSessionRestoreBanner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.database.StickerDatabase;
|
|||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
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.SmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
||||||
@ -275,11 +276,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator());
|
LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator());
|
||||||
|
|
||||||
// Loki - Handle session reset logic
|
// Loki - Handle session reset logic
|
||||||
/*
|
|
||||||
if (!envelope.isFriendRequest() && cipher.getSessionStatus(envelope) == null && envelope.isPreKeySignalMessage()) {
|
if (!envelope.isFriendRequest() && cipher.getSessionStatus(envelope) == null && envelope.isPreKeySignalMessage()) {
|
||||||
cipher.validateBackgroundMessage(envelope, envelope.getContent());
|
cipher.validateBackgroundMessage(envelope, envelope.getContent());
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Loki - Ignore any friend requests that we got before restoration
|
// Loki - Ignore any friend requests that we got before restoration
|
||||||
if (envelope.isFriendRequest() && envelope.getTimestamp() < TextSecurePreferences.getRestorationTime(context)) {
|
if (envelope.isFriendRequest() && envelope.getTimestamp() < TextSecurePreferences.getRestorationTime(context)) {
|
||||||
@ -1385,17 +1384,39 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SmsMessageRecord getLastMessage(String sender) {
|
||||||
|
try {
|
||||||
|
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||||
|
Recipient recipient = Recipient.from(context, Address.fromSerialized(sender), false);
|
||||||
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient);
|
||||||
|
if (threadID < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int messageCount = smsDatabase.getMessageCountForThread(threadID);
|
||||||
|
if (messageCount <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long lastMessageID = smsDatabase.getIDForMessageAtIndex(threadID, messageCount - 1);
|
||||||
|
return smsDatabase.getMessage(lastMessageID);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleCorruptMessage(@NonNull String sender, int senderDevice, long timestamp,
|
private void handleCorruptMessage(@NonNull String sender, int senderDevice, long timestamp,
|
||||||
@NonNull Optional<Long> smsMessageId)
|
@NonNull Optional<Long> smsMessageId)
|
||||||
{
|
{
|
||||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||||
|
|
||||||
if (!smsMessageId.isPresent()) {
|
if (!smsMessageId.isPresent()) {
|
||||||
|
SmsMessageRecord lastMessage = getLastMessage(sender);
|
||||||
|
if (lastMessage == null || !SmsDatabase.Types.isFailedDecryptType(lastMessage.getType())) {
|
||||||
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
||||||
|
|
||||||
if (insertResult.isPresent()) {
|
if (insertResult.isPresent()) {
|
||||||
smsDatabase.markAsDecryptFailed(insertResult.get().getMessageId());
|
smsDatabase.markAsDecryptFailed(insertResult.get().getMessageId());
|
||||||
// MessageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
MessageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
smsDatabase.markAsDecryptFailed(smsMessageId.get());
|
smsDatabase.markAsDecryptFailed(smsMessageId.get());
|
||||||
@ -1409,11 +1430,14 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||||
|
|
||||||
if (!smsMessageId.isPresent()) {
|
if (!smsMessageId.isPresent()) {
|
||||||
|
SmsMessageRecord lastMessage = getLastMessage(sender);
|
||||||
|
if (lastMessage == null || !SmsDatabase.Types.isNoRemoteSessionType(lastMessage.getType())) {
|
||||||
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
Optional<InsertResult> insertResult = insertPlaceholder(sender, senderDevice, timestamp);
|
||||||
|
|
||||||
if (insertResult.isPresent()) {
|
if (insertResult.isPresent()) {
|
||||||
smsDatabase.markAsNoSession(insertResult.get().getMessageId());
|
smsDatabase.markAsNoSession(insertResult.get().getMessageId());
|
||||||
// MessageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
MessageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
smsDatabase.markAsNoSession(smsMessageId.get());
|
smsDatabase.markAsNoSession(smsMessageId.get());
|
||||||
|
@ -14,6 +14,7 @@ import org.whispersystems.signalservice.loki.api.LokiPublicChat
|
|||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadDatabaseProtocol
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadDatabaseProtocol
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadSessionResetStatus
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadSessionResetStatus
|
||||||
|
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
||||||
|
|
||||||
class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiThreadDatabaseProtocol {
|
class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiThreadDatabaseProtocol {
|
||||||
var delegate: LokiThreadDatabaseDelegate? = null
|
var delegate: LokiThreadDatabaseDelegate? = null
|
||||||
@ -152,7 +153,10 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getSessionRestoreDevices(threadID: Long): Set<String> {
|
fun getSessionRestoreDevices(threadID: Long): Set<String> {
|
||||||
return TextSecurePreferences.getStringPreference(context, "session_restore_devices_$threadID", "").split(",").toSet()
|
return TextSecurePreferences.getStringPreference(context, "session_restore_devices_$threadID", "")
|
||||||
|
.split(",")
|
||||||
|
.filter { PublicKeyValidation.isValid(it) }
|
||||||
|
.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeAllSessionRestoreDevices(threadID: Long) {
|
fun removeAllSessionRestoreDevices(threadID: Long) {
|
||||||
|
@ -1,38 +1,27 @@
|
|||||||
package org.thoughtcrime.securesms.loki
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.components.reminder.Reminder
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build.VERSION_CODES
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
|
||||||
import kotlinx.android.synthetic.main.session_restore_banner.view.*
|
import kotlinx.android.synthetic.main.session_restore_banner.view.*
|
||||||
|
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View to display actionable reminders to the user
|
* View to display actionable reminders to the user
|
||||||
*/
|
*/
|
||||||
class SessionRestoreBannerView private constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
|
class SessionRestoreBannerView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) {
|
||||||
private var container: ViewGroup? = null
|
|
||||||
private var closeButton: ImageButton? = null
|
|
||||||
private var title: TextView? = null
|
|
||||||
private var text: TextView? = null
|
|
||||||
lateinit var recipient: Recipient
|
lateinit var recipient: Recipient
|
||||||
var onDismiss: (() -> Unit)? = null
|
var onDismiss: (() -> Unit)? = null
|
||||||
var onRestore: (() -> Unit)? = null
|
var onRestore: (() -> Unit)? = null
|
||||||
|
|
||||||
|
// region Initialization
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||||
constructor(context: Context) : this(context, null)
|
constructor(context: Context) : this(context, null)
|
||||||
private constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
// endregion
|
||||||
|
|
||||||
init {
|
init {
|
||||||
LayoutInflater.from(context).inflate(R.layout.session_restore_banner, this, true)
|
LayoutInflater.from(context).inflate(R.layout.session_restore_banner, this, true)
|
||||||
@ -46,10 +35,10 @@ class SessionRestoreBannerView private constructor(context: Context, attrs: Attr
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun show() {
|
fun show() {
|
||||||
container!!.visibility = View.VISIBLE;
|
sessionRestoreBanner.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hide() {
|
fun hide() {
|
||||||
container!!.visibility = View.GONE
|
sessionRestoreBanner.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user