2015-10-19 18:23:12 +00:00
|
|
|
package org.thoughtcrime.securesms;
|
|
|
|
|
|
|
|
import android.animation.Animator;
|
2018-02-02 03:22:48 +00:00
|
|
|
import android.annotation.SuppressLint;
|
2015-10-19 18:23:12 +00:00
|
|
|
import android.annotation.TargetApi;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
2017-10-23 20:03:32 +00:00
|
|
|
import android.os.AsyncTask;
|
2015-10-19 18:23:12 +00:00
|
|
|
import android.os.Build.VERSION;
|
|
|
|
import android.os.Build.VERSION_CODES;
|
|
|
|
import android.os.Bundle;
|
2020-08-19 00:06:26 +00:00
|
|
|
import androidx.annotation.AnimRes;
|
|
|
|
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
2015-10-19 18:23:12 +00:00
|
|
|
import android.view.View;
|
|
|
|
import android.view.View.OnClickListener;
|
|
|
|
import android.view.ViewAnimationUtils;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.ViewTreeObserver.OnPreDrawListener;
|
|
|
|
import android.view.animation.Animation;
|
|
|
|
import android.view.animation.AnimationUtils;
|
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.EditText;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
import org.thoughtcrime.securesms.components.ContactFilterToolbar;
|
|
|
|
import org.thoughtcrime.securesms.components.ContactFilterToolbar.OnFilterChangedListener;
|
2017-07-26 16:59:15 +00:00
|
|
|
import org.thoughtcrime.securesms.database.Address;
|
2015-10-19 18:23:12 +00:00
|
|
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
2020-05-11 06:19:26 +00:00
|
|
|
import org.thoughtcrime.securesms.loki.fragments.ContactSelectionListFragment;
|
|
|
|
import org.thoughtcrime.securesms.loki.fragments.ContactSelectionListLoader.DisplayMode;
|
2017-08-01 15:56:00 +00:00
|
|
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
2015-10-19 18:23:12 +00:00
|
|
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
|
|
|
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
|
|
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
2015-11-12 18:47:42 +00:00
|
|
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture.Listener;
|
2016-02-06 00:10:33 +00:00
|
|
|
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
2015-11-12 18:47:42 +00:00
|
|
|
|
|
|
|
import java.util.concurrent.ExecutionException;
|
2015-10-19 18:23:12 +00:00
|
|
|
|
2019-07-24 02:30:23 +00:00
|
|
|
import network.loki.messenger.R;
|
|
|
|
|
2020-04-15 02:52:23 +00:00
|
|
|
public class InviteActivity extends PassphraseRequiredActionBarActivity {
|
2015-10-19 18:23:12 +00:00
|
|
|
|
|
|
|
private ContactSelectionListFragment contactsFragment;
|
|
|
|
private EditText inviteText;
|
|
|
|
private ViewGroup smsSendFrame;
|
|
|
|
private Button smsSendButton;
|
|
|
|
private Animation slideInAnimation;
|
|
|
|
private Animation slideOutAnimation;
|
|
|
|
private ImageView heart;
|
|
|
|
|
|
|
|
@Override
|
2018-02-02 03:22:48 +00:00
|
|
|
protected void onCreate(Bundle savedInstanceState, boolean ready) {
|
2020-07-15 04:26:20 +00:00
|
|
|
getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, DisplayMode.FLAG_CONTACTS);
|
2015-10-19 18:23:12 +00:00
|
|
|
getIntent().putExtra(ContactSelectionListFragment.MULTI_SELECT, true);
|
|
|
|
getIntent().putExtra(ContactSelectionListFragment.REFRESHABLE, false);
|
|
|
|
|
|
|
|
setContentView(R.layout.invite_activity);
|
2018-02-02 03:22:48 +00:00
|
|
|
assert getSupportActionBar() != null;
|
2015-10-19 18:23:12 +00:00
|
|
|
getSupportActionBar().setTitle(R.string.AndroidManifest__invite_friends);
|
|
|
|
|
|
|
|
initializeResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initializeResources() {
|
|
|
|
slideInAnimation = loadAnimation(R.anim.slide_from_bottom);
|
|
|
|
slideOutAnimation = loadAnimation(R.anim.slide_to_bottom);
|
2018-02-02 03:22:48 +00:00
|
|
|
|
|
|
|
View shareButton = ViewUtil.findById(this, R.id.share_button);
|
|
|
|
View smsButton = ViewUtil.findById(this, R.id.sms_button);
|
|
|
|
Button smsCancelButton = ViewUtil.findById(this, R.id.cancel_sms_button);
|
|
|
|
ContactFilterToolbar contactFilter = ViewUtil.findById(this, R.id.contact_filter);
|
|
|
|
|
2015-10-19 18:23:12 +00:00
|
|
|
inviteText = ViewUtil.findById(this, R.id.invite_text);
|
|
|
|
smsSendFrame = ViewUtil.findById(this, R.id.sms_send_frame);
|
|
|
|
smsSendButton = ViewUtil.findById(this, R.id.send_sms_button);
|
|
|
|
heart = ViewUtil.findById(this, R.id.heart);
|
|
|
|
contactsFragment = (ContactSelectionListFragment)getSupportFragmentManager().findFragmentById(R.id.contact_selection_list_fragment);
|
|
|
|
|
2019-05-23 11:02:15 +00:00
|
|
|
inviteText.setText(getString(R.string.InviteActivity_lets_switch_to_signal, getString(R.string.install_url)));
|
2015-10-19 18:23:12 +00:00
|
|
|
updateSmsButtonText();
|
|
|
|
|
|
|
|
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
|
|
|
heart.getViewTreeObserver().addOnPreDrawListener(new HeartPreDrawListener());
|
|
|
|
}
|
|
|
|
shareButton.setOnClickListener(new ShareClickListener());
|
|
|
|
smsButton.setOnClickListener(new SmsClickListener());
|
|
|
|
smsCancelButton.setOnClickListener(new SmsCancelClickListener());
|
|
|
|
smsSendButton.setOnClickListener(new SmsSendClickListener());
|
|
|
|
contactFilter.setOnFilterChangedListener(new ContactFilterChangedListener());
|
2016-12-17 23:52:27 +00:00
|
|
|
contactFilter.setNavigationIcon(R.drawable.ic_search_white_24dp);
|
2015-10-19 18:23:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private Animation loadAnimation(@AnimRes int animResId) {
|
|
|
|
final Animation animation = AnimationUtils.loadAnimation(this, animResId);
|
|
|
|
animation.setInterpolator(new FastOutSlowInInterpolator());
|
|
|
|
return animation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onContactSelected(String number) {
|
|
|
|
updateSmsButtonText();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onContactDeselected(String number) {
|
|
|
|
updateSmsButtonText();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void sendSmsInvites() {
|
|
|
|
new SendSmsInvitesAsyncTask(this, inviteText.getText().toString())
|
2017-10-23 20:03:32 +00:00
|
|
|
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
|
|
|
contactsFragment.getSelectedContacts()
|
|
|
|
.toArray(new String[contactsFragment.getSelectedContacts().size()]));
|
2015-10-19 18:23:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void updateSmsButtonText() {
|
2016-03-29 08:35:50 +00:00
|
|
|
smsSendButton.setText(getResources().getQuantityString(R.plurals.InviteActivity_send_sms_to_friends,
|
2015-11-05 13:53:02 +00:00
|
|
|
contactsFragment.getSelectedContacts().size(),
|
|
|
|
contactsFragment.getSelectedContacts().size()));
|
2015-10-19 18:23:12 +00:00
|
|
|
smsSendButton.setEnabled(!contactsFragment.getSelectedContacts().isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override public void onBackPressed() {
|
|
|
|
if (smsSendFrame.getVisibility() == View.VISIBLE) {
|
|
|
|
cancelSmsSelection();
|
|
|
|
} else {
|
|
|
|
super.onBackPressed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void cancelSmsSelection() {
|
|
|
|
updateSmsButtonText();
|
2015-11-18 22:52:26 +00:00
|
|
|
ViewUtil.animateOut(smsSendFrame, slideOutAnimation, View.GONE);
|
2015-10-19 18:23:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private class ShareClickListener implements OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
Intent sendIntent = new Intent();
|
|
|
|
sendIntent.setAction(Intent.ACTION_SEND);
|
|
|
|
sendIntent.putExtra(Intent.EXTRA_TEXT, inviteText.getText().toString());
|
|
|
|
sendIntent.setType("text/plain");
|
|
|
|
if (sendIntent.resolveActivity(getPackageManager()) != null) {
|
|
|
|
startActivity(Intent.createChooser(sendIntent, getString(R.string.InviteActivity_invite_to_signal)));
|
|
|
|
} else {
|
|
|
|
Toast.makeText(InviteActivity.this, R.string.InviteActivity_no_app_to_share_to, Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class SmsClickListener implements OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
ViewUtil.animateIn(smsSendFrame, slideInAnimation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class SmsCancelClickListener implements OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
cancelSmsSelection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class SmsSendClickListener implements OnClickListener {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
new AlertDialog.Builder(InviteActivity.this)
|
2015-11-05 13:53:02 +00:00
|
|
|
.setTitle(getResources().getQuantityString(R.plurals.InviteActivity_send_sms_invites,
|
|
|
|
contactsFragment.getSelectedContacts().size(),
|
|
|
|
contactsFragment.getSelectedContacts().size()))
|
2015-10-19 18:23:12 +00:00
|
|
|
.setMessage(inviteText.getText().toString())
|
2018-02-02 03:22:48 +00:00
|
|
|
.setPositiveButton(R.string.yes, (dialog, which) -> sendSmsInvites())
|
|
|
|
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
|
2015-10-19 18:23:12 +00:00
|
|
|
.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class ContactFilterChangedListener implements OnFilterChangedListener {
|
|
|
|
@Override
|
|
|
|
public void onFilterChanged(String filter) {
|
|
|
|
contactsFragment.setQueryFilter(filter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class HeartPreDrawListener implements OnPreDrawListener {
|
|
|
|
@Override
|
|
|
|
@TargetApi(VERSION_CODES.LOLLIPOP)
|
|
|
|
public boolean onPreDraw() {
|
|
|
|
heart.getViewTreeObserver().removeOnPreDrawListener(this);
|
|
|
|
final int w = heart.getWidth();
|
|
|
|
final int h = heart.getHeight();
|
|
|
|
Animator reveal = ViewAnimationUtils.createCircularReveal(heart,
|
|
|
|
w / 2, h,
|
|
|
|
0, (float)Math.sqrt(h*h + (w*w/4)));
|
|
|
|
reveal.setInterpolator(new FastOutSlowInInterpolator());
|
|
|
|
reveal.setDuration(800);
|
|
|
|
reveal.start();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-02 03:22:48 +00:00
|
|
|
@SuppressLint("StaticFieldLeak")
|
2015-10-19 18:23:12 +00:00
|
|
|
private class SendSmsInvitesAsyncTask extends ProgressDialogAsyncTask<String,Void,Void> {
|
|
|
|
private final String message;
|
|
|
|
|
2018-02-02 03:22:48 +00:00
|
|
|
SendSmsInvitesAsyncTask(Context context, String message) {
|
2015-10-19 18:23:12 +00:00
|
|
|
super(context, R.string.InviteActivity_sending, R.string.InviteActivity_sending);
|
|
|
|
this.message = message;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Void doInBackground(String... numbers) {
|
|
|
|
final Context context = getContext();
|
|
|
|
if (context == null) return null;
|
|
|
|
|
|
|
|
for (String number : numbers) {
|
2017-08-22 17:44:04 +00:00
|
|
|
Recipient recipient = Recipient.from(context, Address.fromExternal(context, number), false);
|
|
|
|
int subscriptionId = recipient.getDefaultSubscriptionId().or(-1);
|
2016-02-06 00:10:33 +00:00
|
|
|
|
2018-01-25 03:17:44 +00:00
|
|
|
MessageSender.send(context, new OutgoingTextMessage(recipient, message, subscriptionId), -1L, true, null);
|
2016-02-06 00:10:33 +00:00
|
|
|
|
2017-08-01 15:56:00 +00:00
|
|
|
if (recipient.getContactUri() != null) {
|
2017-08-22 01:47:37 +00:00
|
|
|
DatabaseFactory.getRecipientDatabase(context).setSeenInviteReminder(recipient, true);
|
2015-10-19 18:23:12 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-01 15:56:00 +00:00
|
|
|
|
2015-10-19 18:23:12 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Void aVoid) {
|
|
|
|
super.onPostExecute(aVoid);
|
|
|
|
final Context context = getContext();
|
|
|
|
if (context == null) return;
|
|
|
|
|
2015-11-18 22:52:26 +00:00
|
|
|
ViewUtil.animateOut(smsSendFrame, slideOutAnimation, View.GONE).addListener(new Listener<Boolean>() {
|
2015-11-12 18:47:42 +00:00
|
|
|
@Override
|
|
|
|
public void onSuccess(Boolean result) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFailure(ExecutionException e) {}
|
|
|
|
});
|
2015-10-19 18:23:12 +00:00
|
|
|
Toast.makeText(context, R.string.InviteActivity_invitations_sent, Toast.LENGTH_LONG).show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|