mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 18:43:49 +00:00
parent
38d0b5caa8
commit
4ffb1ea95e
@ -20,6 +20,11 @@
|
|||||||
android:paddingTop="?attr/actionBarSize"
|
android:paddingTop="?attr/actionBarSize"
|
||||||
android:gravity="bottom">
|
android:gravity="bottom">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||||
|
android:id="@+id/reminder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<FrameLayout android:id="@+id/fragment_content"
|
<FrameLayout android:id="@+id/fragment_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ReminderView
|
<org.thoughtcrime.securesms.components.reminder.ReminderView
|
||||||
android:id="@+id/reminder"
|
android:id="@+id/reminder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
@ -1,59 +1,62 @@
|
|||||||
<?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 android:id="@+id/container"
|
||||||
android:orientation="vertical"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="wrap_content">
|
android:orientation="horizontal"
|
||||||
<LinearLayout android:id="@+id/container"
|
android:layout_width="match_parent"
|
||||||
android:orientation="horizontal"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:gravity="center_vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:background="?reminder_header_background">
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/reminder"
|
||||||
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:layout_weight="1"
|
||||||
android:background="?reminder_header_background">
|
android:layout_margin="10dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView android:id="@+id/icon"
|
<TextView android:id="@+id/reminder_title"
|
||||||
android:layout_width="50dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="50dp"
|
android:layout_height="wrap_content"
|
||||||
android:src="@drawable/sms_selection_icon"
|
android:textColor="@color/white"
|
||||||
android:padding="5dp"/>
|
android:textSize="16sp"
|
||||||
|
tools:text="@string/reminder_header_push_title" />
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/reminder"
|
<TextView android:id="@+id/reminder_text"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:fontFamily="sans-serif-light"
|
||||||
android:layout_margin="10dp"
|
android:textColor="@color/white"
|
||||||
android:orientation="vertical">
|
android:textSize="14sp"
|
||||||
|
tools:text="@string/reminder_header_push_text" />
|
||||||
<TextView android:id="@+id/reminder_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="18sp"/>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/reminder_text"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="sans-serif-light"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="16sp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="right|top"
|
|
||||||
android:layout_marginLeft="15dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ImageButton android:id="@+id/cancel"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:background="@drawable/touch_highlight_background"
|
|
||||||
android:src="@drawable/ic_cancel_white_24dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/cancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:paddingLeft="6dp"
|
||||||
|
android:paddingRight="6dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:textColor="#99ffffff"
|
||||||
|
android:clickable="true"
|
||||||
|
android:text="@string/reminder_header_close_button" />
|
||||||
|
|
||||||
|
<TextView android:id="@+id/accept"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:paddingLeft="6dp"
|
||||||
|
android:paddingRight="6dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
tools:text="ENABLE" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1037,12 +1037,20 @@
|
|||||||
<!-- reminder_header -->
|
<!-- reminder_header -->
|
||||||
<string name="reminder_header_expired_build">Your build of Signal has expired!</string>
|
<string name="reminder_header_expired_build">Your build of Signal has expired!</string>
|
||||||
<string name="reminder_header_expired_build_details">Messages will no longer send successfully, please update to the most recent version.</string>
|
<string name="reminder_header_expired_build_details">Messages will no longer send successfully, please update to the most recent version.</string>
|
||||||
|
<string name="reminder_header_expired_build_button">UPGRADE</string>
|
||||||
<string name="reminder_header_sms_default_title">Use as default SMS app?</string>
|
<string name="reminder_header_sms_default_title">Use as default SMS app?</string>
|
||||||
<string name="reminder_header_sms_default_text">Tap to make Signal your default SMS app.</string>
|
<string name="reminder_header_sms_default_text">Tap to make Signal your default SMS app.</string>
|
||||||
|
<string name="reminder_header_sms_default_button">SET</string>
|
||||||
<string name="reminder_header_sms_import_title">Import system SMS?</string>
|
<string name="reminder_header_sms_import_title">Import system SMS?</string>
|
||||||
<string name="reminder_header_sms_import_text">Tap to copy your phone\'s SMS messages into its encrypted database.</string>
|
<string name="reminder_header_sms_import_text">Tap to copy your phone\'s SMS messages into its encrypted database.</string>
|
||||||
<string name="reminder_header_push_title">Enable Signal messages?</string>
|
<string name="reminder_header_sms_import_button">IMPORT</string>
|
||||||
<string name="reminder_header_push_text">Tap for instant delivery, stronger privacy, and no SMS fees.</string>
|
<string name="reminder_header_push_title">Enable Signal?</string>
|
||||||
|
<string name="reminder_header_push_text">Upgrade your messaging experience.</string>
|
||||||
|
<string name="reminder_header_push_button">ENABLE</string>
|
||||||
|
<string name="reminder_header_invite_title">Invite to Signal?</string>
|
||||||
|
<string name="reminder_header_invite_text">Take your conversation with %1$s to the next level.</string>
|
||||||
|
<string name="reminder_header_invite_button">INVITE</string>
|
||||||
|
<string name="reminder_header_close_button">CLOSE</string>
|
||||||
|
|
||||||
<!-- MediaPreviewActivity -->
|
<!-- MediaPreviewActivity -->
|
||||||
<string name="MediaPreviewActivity_you">You</string>
|
<string name="MediaPreviewActivity_you">You</string>
|
||||||
|
@ -66,6 +66,8 @@ import org.thoughtcrime.securesms.components.AnimatingToggle;
|
|||||||
import org.thoughtcrime.securesms.components.ComposeText;
|
import org.thoughtcrime.securesms.components.ComposeText;
|
||||||
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||||
|
import org.thoughtcrime.securesms.components.reminder.InviteReminder;
|
||||||
|
import org.thoughtcrime.securesms.components.reminder.ReminderView;
|
||||||
import org.thoughtcrime.securesms.components.SendButton;
|
import org.thoughtcrime.securesms.components.SendButton;
|
||||||
import org.thoughtcrime.securesms.components.camera.HidingImageButton;
|
import org.thoughtcrime.securesms.components.camera.HidingImageButton;
|
||||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
||||||
@ -85,6 +87,7 @@ import org.thoughtcrime.securesms.database.DraftDatabase.Draft;
|
|||||||
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts;
|
import org.thoughtcrime.securesms.database.DraftDatabase.Drafts;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
import org.thoughtcrime.securesms.database.MmsSmsColumns.Types;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
import org.thoughtcrime.securesms.mms.AttachmentManager;
|
||||||
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
||||||
@ -106,6 +109,7 @@ import org.thoughtcrime.securesms.sms.MessageSender;
|
|||||||
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
|
||||||
import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState;
|
||||||
import org.thoughtcrime.securesms.util.Dialogs;
|
import org.thoughtcrime.securesms.util.Dialogs;
|
||||||
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
import org.thoughtcrime.securesms.util.DirectoryHelper;
|
||||||
@ -117,16 +121,17 @@ import org.thoughtcrime.securesms.util.GroupUtil;
|
|||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||||
import org.whispersystems.libaxolotl.InvalidMessageException;
|
import org.whispersystems.libaxolotl.InvalidMessageException;
|
||||||
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
import static org.thoughtcrime.securesms.TransportOption.Type;
|
import static org.thoughtcrime.securesms.TransportOption.Type;
|
||||||
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
@ -175,6 +180,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private InputAwareLayout container;
|
private InputAwareLayout container;
|
||||||
private View composePanel;
|
private View composePanel;
|
||||||
private View composeBubble;
|
private View composeBubble;
|
||||||
|
private ReminderView reminderView;
|
||||||
|
|
||||||
private AttachmentTypeSelectorAdapter attachmentAdapter;
|
private AttachmentTypeSelectorAdapter attachmentAdapter;
|
||||||
private AttachmentManager attachmentManager;
|
private AttachmentManager attachmentManager;
|
||||||
@ -216,16 +222,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
initializeActionBar();
|
initializeActionBar();
|
||||||
initializeViews();
|
initializeViews();
|
||||||
initializeResources();
|
initializeResources();
|
||||||
initializeSecurity(false, false).addListener(new ListenableFuture.Listener<Boolean>() {
|
initializeSecurity(false, false).addListener(new AssertedSuccessListener<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Boolean result) {
|
public void onSuccess(Boolean result) {
|
||||||
initializeDraft();
|
initializeDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(ExecutionException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,15 +242,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
|
|
||||||
setIntent(intent);
|
setIntent(intent);
|
||||||
initializeResources();
|
initializeResources();
|
||||||
initializeSecurity(false, false).addListener(new ListenableFuture.Listener<Boolean>() {
|
initializeSecurity(false, false).addListener(new AssertedSuccessListener<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Boolean result) {
|
public void onSuccess(Boolean result) {
|
||||||
initializeDraft();
|
initializeDraft();
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onFailure(ExecutionException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fragment != null) {
|
if (fragment != null) {
|
||||||
@ -804,14 +801,25 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
if (result.first != currentSecureText || result.second != currentSecureVoice) {
|
if (result.first != currentSecureText || result.second != currentSecureVoice) {
|
||||||
handleSecurityChange(result.first, result.second);
|
handleSecurityChange(result.first, result.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
future.set(true);
|
future.set(true);
|
||||||
|
onSecurityUpdated();
|
||||||
}
|
}
|
||||||
}.execute(recipients);
|
}.execute(recipients);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onSecurityUpdated() {
|
||||||
|
updateInviteReminder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateInviteReminder() {
|
||||||
|
if (TextSecurePreferences.isPushRegistered(this) && !isSecureText && recipients.isSingleRecipient()) {
|
||||||
|
new ShowInviteReminderTask().execute(recipients);
|
||||||
|
} else {
|
||||||
|
reminderView.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeMmsEnabledCheck() {
|
private void initializeMmsEnabledCheck() {
|
||||||
new AsyncTask<Void, Void, Boolean>() {
|
new AsyncTask<Void, Void, Boolean>() {
|
||||||
@ -828,21 +836,21 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeViews() {
|
private void initializeViews() {
|
||||||
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
||||||
buttonToggle = (AnimatingToggle) findViewById(R.id.button_toggle);
|
buttonToggle = ViewUtil.findById(this, R.id.button_toggle);
|
||||||
sendButton = (SendButton) findViewById(R.id.send_button);
|
sendButton = ViewUtil.findById(this, R.id.send_button);
|
||||||
attachButton = (ImageButton) findViewById(R.id.attach_button);
|
attachButton = ViewUtil.findById(this, R.id.attach_button);
|
||||||
composeText = (ComposeText) findViewById(R.id.embedded_text_editor);
|
composeText = ViewUtil.findById(this, R.id.embedded_text_editor);
|
||||||
charactersLeft = (TextView) findViewById(R.id.space_left);
|
charactersLeft = ViewUtil.findById(this, R.id.space_left);
|
||||||
emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);
|
emojiToggle = ViewUtil.findById(this, R.id.emoji_toggle);
|
||||||
emojiDrawer = (EmojiDrawer) findViewById(R.id.emoji_drawer);
|
emojiDrawer = ViewUtil.findById(this, R.id.emoji_drawer);
|
||||||
unblockButton = (Button) findViewById(R.id.unblock_button);
|
unblockButton = ViewUtil.findById(this, R.id.unblock_button);
|
||||||
composePanel = findViewById(R.id.bottom_panel);
|
composePanel = ViewUtil.findById(this, R.id.bottom_panel);
|
||||||
composeBubble = findViewById(R.id.compose_bubble);
|
composeBubble = ViewUtil.findById(this, R.id.compose_bubble);
|
||||||
container = (InputAwareLayout) findViewById(R.id.layout_container);
|
container = ViewUtil.findById(this, R.id.layout_container);
|
||||||
|
reminderView = ViewUtil.findById(this, R.id.reminder);
|
||||||
quickAttachmentDrawer = (QuickAttachmentDrawer) findViewById(R.id.quick_attachment_drawer);
|
quickAttachmentDrawer = ViewUtil.findById(this, R.id.quick_attachment_drawer);
|
||||||
quickAttachmentToggle = (HidingImageButton) findViewById(R.id.quick_attachment_toggle);
|
quickAttachmentToggle = ViewUtil.findById(this, R.id.quick_attachment_toggle);
|
||||||
|
|
||||||
container.addOnKeyboardShownListener(this);
|
container.addOnKeyboardShownListener(this);
|
||||||
|
|
||||||
@ -944,6 +952,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
titleView.setTitle(recipients);
|
titleView.setTitle(recipients);
|
||||||
setBlockedUserState(recipients);
|
setBlockedUserState(recipients);
|
||||||
setActionBarColor(recipients.getColor());
|
setActionBarColor(recipients.getColor());
|
||||||
|
updateInviteReminder();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1441,4 +1450,31 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
updateToggleButtonState();
|
updateToggleButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ShowInviteReminderTask extends AsyncTask<Recipients, Void, Pair<Recipients,Boolean>> {
|
||||||
|
@Override
|
||||||
|
protected Pair<Recipients, Boolean> doInBackground(Recipients... recipients) {
|
||||||
|
if (recipients.length != 1 || recipients[0] == null) throw new AssertionError("task needs exactly one Recipients object");
|
||||||
|
|
||||||
|
Optional<RecipientsPreferences> prefs = DatabaseFactory.getRecipientPreferenceDatabase(ConversationActivity.this)
|
||||||
|
.getRecipientsPreferences(recipients[0].getIds());
|
||||||
|
return new Pair<>(recipients[0], prefs.isPresent() && prefs.get().hasSeenInviteReminder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Pair<Recipients, Boolean> result) {
|
||||||
|
if (!result.second && result.first == recipients) {
|
||||||
|
InviteReminder reminder = new InviteReminder(ConversationActivity.this, result.first);
|
||||||
|
reminder.setOkListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
handleInviteLink();
|
||||||
|
reminderView.requestDismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
reminderView.showReminder(reminder);
|
||||||
|
} else {
|
||||||
|
reminderView.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,6 @@ import android.support.v7.app.AppCompatActivity;
|
|||||||
import android.support.v7.view.ActionMode;
|
import android.support.v7.view.ActionMode;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.support.v7.widget.RecyclerView.RecyclerListener;
|
|
||||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -48,12 +46,12 @@ import com.afollestad.materialdialogs.AlertDialogWrapper;
|
|||||||
import com.melnykov.fab.FloatingActionButton;
|
import com.melnykov.fab.FloatingActionButton;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ConversationListAdapter.ItemClickListener;
|
import org.thoughtcrime.securesms.ConversationListAdapter.ItemClickListener;
|
||||||
import org.thoughtcrime.securesms.components.DefaultSmsReminder;
|
import org.thoughtcrime.securesms.components.reminder.DefaultSmsReminder;
|
||||||
import org.thoughtcrime.securesms.components.ExpiredBuildReminder;
|
import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder;
|
||||||
import org.thoughtcrime.securesms.components.PushRegistrationReminder;
|
import org.thoughtcrime.securesms.components.reminder.PushRegistrationReminder;
|
||||||
import org.thoughtcrime.securesms.components.Reminder;
|
import org.thoughtcrime.securesms.components.reminder.Reminder;
|
||||||
import org.thoughtcrime.securesms.components.ReminderView;
|
import org.thoughtcrime.securesms.components.reminder.ReminderView;
|
||||||
import org.thoughtcrime.securesms.components.SystemSmsImportReminder;
|
import org.thoughtcrime.securesms.components.reminder.SystemSmsImportReminder;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.loaders.ConversationListLoader;
|
import org.thoughtcrime.securesms.database.loaders.ConversationListLoader;
|
||||||
@ -137,7 +135,7 @@ public class ConversationListFragment extends Fragment
|
|||||||
@Override protected Optional<? extends Reminder> doInBackground(Context... params) {
|
@Override protected Optional<? extends Reminder> doInBackground(Context... params) {
|
||||||
final Context context = params[0];
|
final Context context = params[0];
|
||||||
if (ExpiredBuildReminder.isEligible(context)) {
|
if (ExpiredBuildReminder.isEligible(context)) {
|
||||||
return Optional.of(new ExpiredBuildReminder());
|
return Optional.of(new ExpiredBuildReminder(context));
|
||||||
} else if (DefaultSmsReminder.isEligible(context)) {
|
} else if (DefaultSmsReminder.isEligible(context)) {
|
||||||
return Optional.of(new DefaultSmsReminder(context));
|
return Optional.of(new DefaultSmsReminder(context));
|
||||||
} else if (SystemSmsImportReminder.isEligible(context)) {
|
} else if (SystemSmsImportReminder.isEligible(context)) {
|
||||||
|
@ -57,6 +57,7 @@ public class ComposeText extends EmojiEditText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
append(invite);
|
append(invite);
|
||||||
|
setSelection(getText().length());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLandscape() {
|
private boolean isLandscape() {
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.provider.Telephony;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
|
||||||
import org.thoughtcrime.securesms.TextSecureExpiredException;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
|
||||||
|
|
||||||
public class ExpiredBuildReminder extends Reminder {
|
|
||||||
|
|
||||||
private static final String TAG = ExpiredBuildReminder.class.getSimpleName();
|
|
||||||
|
|
||||||
public ExpiredBuildReminder() {
|
|
||||||
super(R.drawable.ic_warning_dark,
|
|
||||||
R.string.reminder_header_expired_build,
|
|
||||||
R.string.reminder_header_expired_build_details);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDismissable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEligible(Context context) {
|
|
||||||
return !Util.isBuildFresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
|
||||||
|
|
||||||
public abstract class Reminder {
|
|
||||||
private int iconResId;
|
|
||||||
private int titleResId;
|
|
||||||
private int textResId;
|
|
||||||
private OnClickListener okListener;
|
|
||||||
private OnClickListener cancelListener;
|
|
||||||
|
|
||||||
public Reminder(int iconResId, int titleResId, int textResId) {
|
|
||||||
this.iconResId = iconResId;
|
|
||||||
this.titleResId = titleResId;
|
|
||||||
this.textResId = textResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIconResId() {
|
|
||||||
return iconResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTitleResId() {
|
|
||||||
return titleResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTextResId() {
|
|
||||||
return textResId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClickListener getOkListener() {
|
|
||||||
return okListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClickListener getCancelListener() {
|
|
||||||
return cancelListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOkListener(OnClickListener okListener) {
|
|
||||||
this.okListener = okListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCancelListener(OnClickListener cancelListener) {
|
|
||||||
this.cancelListener = cancelListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDismissable() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,8 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.provider.Telephony;
|
import android.provider.Telephony;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -17,9 +16,9 @@ public class DefaultSmsReminder extends Reminder {
|
|||||||
|
|
||||||
@TargetApi(VERSION_CODES.KITKAT)
|
@TargetApi(VERSION_CODES.KITKAT)
|
||||||
public DefaultSmsReminder(final Context context) {
|
public DefaultSmsReminder(final Context context) {
|
||||||
super(R.drawable.sms_selection_icon,
|
super(context.getString(R.string.reminder_header_sms_default_title),
|
||||||
R.string.reminder_header_sms_default_title,
|
context.getString(R.string.reminder_header_sms_default_text),
|
||||||
R.string.reminder_header_sms_default_text);
|
context.getString(R.string.reminder_header_sms_default_button));
|
||||||
|
|
||||||
final OnClickListener okListener = new OnClickListener() {
|
final OnClickListener okListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -30,14 +29,14 @@ public class DefaultSmsReminder extends Reminder {
|
|||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
final OnClickListener cancelListener = new OnClickListener() {
|
final OnClickListener dismissListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
TextSecurePreferences.setPromptedDefaultSmsProvider(context, true);
|
TextSecurePreferences.setPromptedDefaultSmsProvider(context, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setOkListener(okListener);
|
setOkListener(okListener);
|
||||||
setCancelListener(cancelListener);
|
setDismissListener(dismissListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEligible(Context context) {
|
public static boolean isEligible(Context context) {
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
|
public class ExpiredBuildReminder extends Reminder {
|
||||||
|
private static final String TAG = ExpiredBuildReminder.class.getSimpleName();
|
||||||
|
|
||||||
|
public ExpiredBuildReminder(final Context context) {
|
||||||
|
super(context.getString(R.string.reminder_header_expired_build),
|
||||||
|
context.getString(R.string.reminder_header_expired_build_details),
|
||||||
|
context.getString(R.string.reminder_header_expired_build_button));
|
||||||
|
setOkListener(new OnClickListener() {
|
||||||
|
@Override public void onClick(View v) {
|
||||||
|
try {
|
||||||
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
|
||||||
|
} catch (android.content.ActivityNotFoundException anfe) {
|
||||||
|
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDismissable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEligible(Context context) {
|
||||||
|
return !Util.isBuildFresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||||
|
|
||||||
|
public class InviteReminder extends Reminder {
|
||||||
|
|
||||||
|
public InviteReminder(final @NonNull Context context,
|
||||||
|
final @NonNull Recipients recipients)
|
||||||
|
{
|
||||||
|
super(context.getString(R.string.reminder_header_invite_title),
|
||||||
|
context.getString(R.string.reminder_header_invite_text, recipients.toShortString()),
|
||||||
|
context.getString(R.string.reminder_header_invite_button));
|
||||||
|
|
||||||
|
setDismissListener(new OnClickListener() {
|
||||||
|
@Override public void onClick(View v) {
|
||||||
|
new AsyncTask<Void,Void,Void>() {
|
||||||
|
|
||||||
|
@Override protected Void doInBackground(Void... params) {
|
||||||
|
DatabaseFactory.getRecipientPreferenceDatabase(context).setSeenInviteReminder(recipients, true);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -13,9 +13,9 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|||||||
public class PushRegistrationReminder extends Reminder {
|
public class PushRegistrationReminder extends Reminder {
|
||||||
|
|
||||||
public PushRegistrationReminder(final Context context, final MasterSecret masterSecret) {
|
public PushRegistrationReminder(final Context context, final MasterSecret masterSecret) {
|
||||||
super(R.drawable.ic_push_registration_reminder,
|
super(context.getString(R.string.reminder_header_push_title),
|
||||||
R.string.reminder_header_push_title,
|
context.getString(R.string.reminder_header_push_text),
|
||||||
R.string.reminder_header_push_text);
|
context.getString(R.string.reminder_header_push_button));
|
||||||
|
|
||||||
final OnClickListener okListener = new OnClickListener() {
|
final OnClickListener okListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
@ -0,0 +1,56 @@
|
|||||||
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
|
||||||
|
public abstract class Reminder {
|
||||||
|
private CharSequence buttonText;
|
||||||
|
private CharSequence title;
|
||||||
|
private CharSequence text;
|
||||||
|
|
||||||
|
private OnClickListener okListener;
|
||||||
|
private OnClickListener dismissListener;
|
||||||
|
|
||||||
|
public Reminder(@NonNull CharSequence title,
|
||||||
|
@NonNull CharSequence text,
|
||||||
|
@NonNull CharSequence buttonText)
|
||||||
|
{
|
||||||
|
this.title = title;
|
||||||
|
this.text = text;
|
||||||
|
this.buttonText = buttonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getButtonText() {
|
||||||
|
return buttonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnClickListener getOkListener() {
|
||||||
|
return okListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnClickListener getDismissListener() {
|
||||||
|
return dismissListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOkListener(OnClickListener okListener) {
|
||||||
|
this.okListener = okListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDismissListener(OnClickListener dismissListener) {
|
||||||
|
this.dismissListener = dismissListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDismissable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -7,23 +7,21 @@ 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.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View to display actionable reminders to the user
|
* View to display actionable reminders to the user
|
||||||
*/
|
*/
|
||||||
public class ReminderView extends LinearLayout {
|
public class ReminderView extends LinearLayout {
|
||||||
private ViewGroup container;
|
private ViewGroup container;
|
||||||
private ImageButton cancel;
|
private TextView acceptButton;
|
||||||
|
private TextView closeButton;
|
||||||
private TextView title;
|
private TextView title;
|
||||||
private TextView text;
|
private TextView text;
|
||||||
private ImageView icon;
|
|
||||||
|
|
||||||
public ReminderView(Context context) {
|
public ReminderView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -43,35 +41,39 @@ public class ReminderView extends LinearLayout {
|
|||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
LayoutInflater.from(getContext()).inflate(R.layout.reminder_header, this, true);
|
LayoutInflater.from(getContext()).inflate(R.layout.reminder_header, this, true);
|
||||||
container = (ViewGroup ) findViewById(R.id.container);
|
container = ViewUtil.findById(this, R.id.container);
|
||||||
cancel = (ImageButton) findViewById(R.id.cancel);
|
acceptButton = ViewUtil.findById(this, R.id.accept);
|
||||||
title = (TextView ) findViewById(R.id.reminder_title);
|
closeButton = ViewUtil.findById(this, R.id.cancel);
|
||||||
text = (TextView ) findViewById(R.id.reminder_text);
|
title = ViewUtil.findById(this, R.id.reminder_title);
|
||||||
icon = (ImageView ) findViewById(R.id.icon);
|
text = ViewUtil.findById(this, R.id.reminder_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showReminder(final Reminder reminder) {
|
public void showReminder(final Reminder reminder) {
|
||||||
icon.setImageResource(reminder.getIconResId());
|
title.setText(reminder.getTitle());
|
||||||
title.setText(reminder.getTitleResId());
|
text.setText(reminder.getText());
|
||||||
text.setText(reminder.getTextResId());
|
acceptButton.setText(reminder.getButtonText());
|
||||||
|
|
||||||
this.setOnClickListener(reminder.getOkListener());
|
acceptButton.setOnClickListener(reminder.getOkListener());
|
||||||
|
|
||||||
if (reminder.isDismissable()) {
|
if (reminder.isDismissable()) {
|
||||||
cancel.setOnClickListener(new OnClickListener() {
|
closeButton.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
hide();
|
hide();
|
||||||
if (reminder.getCancelListener() != null) reminder.getCancelListener().onClick(v);
|
if (reminder.getDismissListener() != null) reminder.getDismissListener().onClick(v);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cancel.setVisibility(View.GONE);
|
closeButton.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
container.setVisibility(View.VISIBLE);
|
container.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestDismiss() {
|
||||||
|
closeButton.performClick();
|
||||||
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
container.setVisibility(View.GONE);
|
container.setVisibility(View.GONE);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components.reminder;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -14,9 +14,9 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|||||||
public class SystemSmsImportReminder extends Reminder {
|
public class SystemSmsImportReminder extends Reminder {
|
||||||
|
|
||||||
public SystemSmsImportReminder(final Context context, final MasterSecret masterSecret) {
|
public SystemSmsImportReminder(final Context context, final MasterSecret masterSecret) {
|
||||||
super(R.drawable.sms_system_import_icon,
|
super(context.getString(R.string.reminder_header_sms_import_title),
|
||||||
R.string.reminder_header_sms_import_title,
|
context.getString(R.string.reminder_header_sms_import_text),
|
||||||
R.string.reminder_header_sms_import_text);
|
context.getString(R.string.reminder_header_sms_import_button));
|
||||||
|
|
||||||
final OnClickListener okListener = new OnClickListener() {
|
final OnClickListener okListener = new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -42,7 +42,7 @@ public class SystemSmsImportReminder extends Reminder {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
setOkListener(okListener);
|
setOkListener(okListener);
|
||||||
setCancelListener(cancelListener);
|
setDismissListener(cancelListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEligible(Context context) {
|
public static boolean isEligible(Context context) {
|
@ -66,7 +66,8 @@ public class DatabaseFactory {
|
|||||||
private static final int INTRODUCED_ENVELOPE_CONTENT_VERSION = 19;
|
private static final int INTRODUCED_ENVELOPE_CONTENT_VERSION = 19;
|
||||||
private static final int INTRODUCED_COLOR_PREFERENCE_VERSION = 20;
|
private static final int INTRODUCED_COLOR_PREFERENCE_VERSION = 20;
|
||||||
private static final int INTRODUCED_DB_OPTIMIZATIONS_VERSION = 21;
|
private static final int INTRODUCED_DB_OPTIMIZATIONS_VERSION = 21;
|
||||||
private static final int DATABASE_VERSION = 21;
|
private static final int INTRODUCED_INVITE_REMINDERS_VERSION = 22;
|
||||||
|
private static final int DATABASE_VERSION = 22;
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "messages.db";
|
private static final String DATABASE_NAME = "messages.db";
|
||||||
private static final Object lock = new Object();
|
private static final Object lock = new Object();
|
||||||
@ -768,6 +769,10 @@ public class DatabaseFactory {
|
|||||||
db.execSQL("CREATE INDEX IF NOT EXISTS mms_thread_date_index ON mms (thread_id, date_received);");
|
db.execSQL("CREATE INDEX IF NOT EXISTS mms_thread_date_index ON mms (thread_id, date_received);");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < INTRODUCED_INVITE_REMINDERS_VERSION) {
|
||||||
|
db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN seen_invite_reminder INTEGER DEFAULT 0");
|
||||||
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,15 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
private static final String TAG = RecipientPreferenceDatabase.class.getSimpleName();
|
private static final String TAG = RecipientPreferenceDatabase.class.getSimpleName();
|
||||||
private static final String RECIPIENT_PREFERENCES_URI = "content://textsecure/recipients/";
|
private static final String RECIPIENT_PREFERENCES_URI = "content://textsecure/recipients/";
|
||||||
|
|
||||||
private static final String TABLE_NAME = "recipient_preferences";
|
private static final String TABLE_NAME = "recipient_preferences";
|
||||||
private static final String ID = "_id";
|
private static final String ID = "_id";
|
||||||
private static final String RECIPIENT_IDS = "recipient_ids";
|
private static final String RECIPIENT_IDS = "recipient_ids";
|
||||||
private static final String BLOCK = "block";
|
private static final String BLOCK = "block";
|
||||||
private static final String NOTIFICATION = "notification";
|
private static final String NOTIFICATION = "notification";
|
||||||
private static final String VIBRATE = "vibrate";
|
private static final String VIBRATE = "vibrate";
|
||||||
private static final String MUTE_UNTIL = "mute_until";
|
private static final String MUTE_UNTIL = "mute_until";
|
||||||
private static final String COLOR = "color";
|
private static final String COLOR = "color";
|
||||||
|
private static final String SEEN_INVITE_REMINDER = "seen_invite_reminder";
|
||||||
|
|
||||||
public enum VibrateState {
|
public enum VibrateState {
|
||||||
DEFAULT(0), ENABLED(1), DISABLED(2);
|
DEFAULT(0), ENABLED(1), DISABLED(2);
|
||||||
@ -58,7 +59,8 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
NOTIFICATION + " TEXT DEFAULT NULL, " +
|
NOTIFICATION + " TEXT DEFAULT NULL, " +
|
||||||
VIBRATE + " INTEGER DEFAULT " + VibrateState.DEFAULT.getId() + ", " +
|
VIBRATE + " INTEGER DEFAULT " + VibrateState.DEFAULT.getId() + ", " +
|
||||||
MUTE_UNTIL + " INTEGER DEFAULT 0, " +
|
MUTE_UNTIL + " INTEGER DEFAULT 0, " +
|
||||||
COLOR + " TEXT DEFAULT NULL);";
|
COLOR + " TEXT DEFAULT NULL, " +
|
||||||
|
SEEN_INVITE_REMINDER + " INTEGER DEFAULT 0);";
|
||||||
|
|
||||||
public RecipientPreferenceDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public RecipientPreferenceDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
super(context, databaseHelper);
|
super(context, databaseHelper);
|
||||||
@ -86,12 +88,13 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
null, null, null);
|
null, null, null);
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
||||||
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
||||||
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
||||||
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
|
long muteUntil = cursor.getLong(cursor.getColumnIndexOrThrow(MUTE_UNTIL));
|
||||||
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
|
String serializedColor = cursor.getString(cursor.getColumnIndexOrThrow(COLOR));
|
||||||
Uri notificationUri = notification == null ? null : Uri.parse(notification);
|
Uri notificationUri = notification == null ? null : Uri.parse(notification);
|
||||||
|
boolean seenInviteReminder = cursor.getInt(cursor.getColumnIndexOrThrow(SEEN_INVITE_REMINDER)) == 1;
|
||||||
|
|
||||||
MaterialColor color;
|
MaterialColor color;
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
|
|
||||||
return Optional.of(new RecipientsPreferences(blocked, muteUntil,
|
return Optional.of(new RecipientsPreferences(blocked, muteUntil,
|
||||||
VibrateState.fromId(vibrateState),
|
VibrateState.fromId(vibrateState),
|
||||||
notificationUri, color));
|
notificationUri, color, seenInviteReminder));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
@ -146,6 +149,12 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
updateOrInsert(recipients, values);
|
updateOrInsert(recipients, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSeenInviteReminder(Recipients recipients, boolean seen) {
|
||||||
|
ContentValues values = new ContentValues(1);
|
||||||
|
values.put(SEEN_INVITE_REMINDER, seen ? 1 : 0);
|
||||||
|
updateOrInsert(recipients, values);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateOrInsert(Recipients recipients, ContentValues contentValues) {
|
private void updateOrInsert(Recipients recipients, ContentValues contentValues) {
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
|
|
||||||
@ -171,17 +180,20 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
private final VibrateState vibrateState;
|
private final VibrateState vibrateState;
|
||||||
private final Uri notification;
|
private final Uri notification;
|
||||||
private final MaterialColor color;
|
private final MaterialColor color;
|
||||||
|
private final boolean seenInviteReminder;
|
||||||
|
|
||||||
public RecipientsPreferences(boolean blocked, long muteUntil,
|
public RecipientsPreferences(boolean blocked, long muteUntil,
|
||||||
@NonNull VibrateState vibrateState,
|
@NonNull VibrateState vibrateState,
|
||||||
@Nullable Uri notification,
|
@Nullable Uri notification,
|
||||||
@Nullable MaterialColor color)
|
@Nullable MaterialColor color,
|
||||||
|
boolean seenInviteReminder)
|
||||||
{
|
{
|
||||||
this.blocked = blocked;
|
this.blocked = blocked;
|
||||||
this.muteUntil = muteUntil;
|
this.muteUntil = muteUntil;
|
||||||
this.vibrateState = vibrateState;
|
this.vibrateState = vibrateState;
|
||||||
this.notification = notification;
|
this.notification = notification;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
this.seenInviteReminder = seenInviteReminder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable MaterialColor getColor() {
|
public @Nullable MaterialColor getColor() {
|
||||||
@ -203,5 +215,9 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
public @Nullable Uri getRingtone() {
|
public @Nullable Uri getRingtone() {
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasSeenInviteReminder() {
|
||||||
|
return seenInviteReminder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.thoughtcrime.securesms.util.concurrent;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture.Listener;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public abstract class AssertedSuccessListener<T> implements Listener<T> {
|
||||||
|
@Override
|
||||||
|
public void onFailure(ExecutionException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
@ -23,10 +23,10 @@ import android.widget.TextView;
|
|||||||
import org.hamcrest.Description;
|
import org.hamcrest.Description;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hamcrest.TypeSafeMatcher;
|
import org.hamcrest.TypeSafeMatcher;
|
||||||
import org.thoughtcrime.securesms.components.DefaultSmsReminder;
|
import org.thoughtcrime.securesms.components.reminder.DefaultSmsReminder;
|
||||||
import org.thoughtcrime.securesms.components.ExpiredBuildReminder;
|
import org.thoughtcrime.securesms.components.reminder.ExpiredBuildReminder;
|
||||||
import org.thoughtcrime.securesms.components.PushRegistrationReminder;
|
import org.thoughtcrime.securesms.components.reminder.PushRegistrationReminder;
|
||||||
import org.thoughtcrime.securesms.components.SystemSmsImportReminder;
|
import org.thoughtcrime.securesms.components.reminder.SystemSmsImportReminder;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
|
||||||
import static android.support.test.espresso.Espresso.onView;
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user