diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index a43e671b8b..6d83f9b3b9 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -51,6 +51,7 @@ import android.widget.Toast; import com.google.protobuf.ByteString; +import org.thoughtcrime.securesms.TransportOptions.OnTransportChangedListener; import org.thoughtcrime.securesms.components.EmojiDrawer; import org.thoughtcrime.securesms.components.EmojiToggle; import org.thoughtcrime.securesms.components.SendButton; @@ -90,13 +91,12 @@ import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.util.BitmapDecodingException; -import org.thoughtcrime.securesms.util.CharacterCalculator; +import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState; import org.thoughtcrime.securesms.util.Dialogs; import org.thoughtcrime.securesms.util.DirectoryHelper; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.Emoji; -import org.thoughtcrime.securesms.util.EncryptedCharacterCalculator; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.MemoryCleaner; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -162,7 +162,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity private boolean isMmsEnabled = true; private boolean isCharactersLeftViewEnabled; - private CharacterCalculator characterCalculator = new CharacterCalculator(); private DynamicTheme dynamicTheme = new DynamicTheme(); private DynamicLanguage dynamicLanguage = new DynamicLanguage(); @@ -213,7 +212,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity initializeEnabledCheck(); initializeMmsEnabledCheck(); initializeIme(); - initializeCharactersLeftViewEnabledCheck(); calculateCharactersRemaining(); MessageNotifier.setVisibleThread(threadId); @@ -636,11 +634,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity sendButton.setEnabled(enabled); } - private void initializeCharactersLeftViewEnabledCheck() { - isCharactersLeftViewEnabled = !(isPushGroupConversation() || - (TextSecurePreferences.isPushRegistered(this) && !TextSecurePreferences.isFallbackSmsAllowed(this))); - } - private void initializeDraftFromDatabase() { new AsyncTask>() { @Override @@ -687,10 +680,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if (isPushDestination || isSecureDestination) { this.isEncryptedConversation = true; - this.characterCalculator = new EncryptedCharacterCalculator(); } else { this.isEncryptedConversation = false; - this.characterCalculator = new CharacterCalculator(); } sendButton.initializeAvailableTransports(!recipients.isSingleRecipient() || attachmentManager.isAttachmentPresent()); @@ -750,6 +741,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity sendButton.setOnClickListener(sendButtonListener); sendButton.setEnabled(true); sendButton.setComposeTextView(composeText); + sendButton.addOnTransportChangedListener(new OnTransportChangedListener() { + @Override + public void onChange(TransportOption newTransport) { + calculateCharactersRemaining(); + } + }); + composeText.setOnKeyListener(composeKeyPressedListener); composeText.addTextChangedListener(composeKeyPressedListener); composeText.setOnEditorActionListener(sendButtonListener); @@ -949,14 +947,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } private void calculateCharactersRemaining() { - int charactersSpent = composeText.getText().toString().length(); - CharacterCalculator.CharacterState characterState = characterCalculator.calculateCharacters(charactersSpent); - if (characterState.charactersRemaining <= 15 && charactersLeft.getVisibility() != View.VISIBLE && isCharactersLeftViewEnabled) { + int charactersSpent = composeText.getText().toString().length(); + CharacterState characterState = sendButton.getSelectedTransport().calculateCharacters(charactersSpent); + + if (characterState.charactersRemaining <= 15 || characterState.messagesSpent > 1) { + charactersLeft.setText(characterState.charactersRemaining + "/" + characterState.maxMessageSize + + " (" + characterState.messagesSpent + ")"); charactersLeft.setVisibility(View.VISIBLE); - } else if (characterState.charactersRemaining > 15 && charactersLeft.getVisibility() != View.GONE) { + } else { charactersLeft.setVisibility(View.GONE); } - charactersLeft.setText(characterState.charactersRemaining + "/" + characterState.maxMessageSize + " (" + characterState.messagesSpent + ")"); } private boolean isExistingConversation() { @@ -1052,9 +1052,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if ((!recipients.isSingleRecipient() || recipients.isEmailRecipient()) && !isMmsEnabled) { handleManualMmsRequired(); } else if (attachmentManager.isAttachmentPresent() || !recipients.isSingleRecipient() || recipients.isGroupRecipient() || recipients.isEmailRecipient()) { - sendMediaMessage(sendButton.getSelectedTransport().isForcedPlaintext(), sendButton.getSelectedTransport().isForcedSms()); + sendMediaMessage(sendButton.getSelectedTransport().isPlaintext(), sendButton.getSelectedTransport().isSms()); } else { - sendTextMessage(sendButton.getSelectedTransport().isForcedPlaintext(), sendButton.getSelectedTransport().isForcedSms()); + sendTextMessage(sendButton.getSelectedTransport().isPlaintext(), sendButton.getSelectedTransport().isSms()); } } catch (RecipientFormattingException ex) { Toast.makeText(ConversationActivity.this, diff --git a/src/org/thoughtcrime/securesms/TransportOption.java b/src/org/thoughtcrime/securesms/TransportOption.java index 98c75316f9..b3b943daa9 100644 --- a/src/org/thoughtcrime/securesms/TransportOption.java +++ b/src/org/thoughtcrime/securesms/TransportOption.java @@ -1,24 +1,42 @@ package org.thoughtcrime.securesms; +import org.thoughtcrime.securesms.util.CharacterCalculator; +import org.thoughtcrime.securesms.util.CharacterCalculator.CharacterState; +import org.thoughtcrime.securesms.util.EncryptedSmsCharacterCalculator; +import org.thoughtcrime.securesms.util.PushCharacterCalculator; +import org.thoughtcrime.securesms.util.SmsCharacterCalculator; + public class TransportOption { - public int drawable; - public String text; - public String key; - public String composeHint; + public int drawable; + public String text; + public String key; + public String composeHint; + public CharacterCalculator characterCalculator; public TransportOption(String key, int drawable, String text, String composeHint) { this.key = key; this.drawable = drawable; this.text = text; this.composeHint = composeHint; + + if (isPlaintext() && isSms()) { + this.characterCalculator = new SmsCharacterCalculator(); + } else if (isSms()) { + this.characterCalculator = new EncryptedSmsCharacterCalculator(); + } else { + this.characterCalculator = new PushCharacterCalculator(); + } } - public boolean isForcedPlaintext() { + public boolean isPlaintext() { return key.equals("insecure_sms"); } - public boolean isForcedSms() { + public boolean isSms() { return key.equals("insecure_sms") || key.equals("secure_sms"); } -} + public CharacterState calculateCharacters(int charactersSpent) { + return characterCalculator.calculateCharacters(charactersSpent); + } +} diff --git a/src/org/thoughtcrime/securesms/TransportOptions.java b/src/org/thoughtcrime/securesms/TransportOptions.java index 1056e63405..e7641bc7db 100644 --- a/src/org/thoughtcrime/securesms/TransportOptions.java +++ b/src/org/thoughtcrime/securesms/TransportOptions.java @@ -3,18 +3,12 @@ package org.thoughtcrime.securesms; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.BitmapDrawable; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.style.RelativeSizeSpan; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; -import android.widget.EditText; -import android.widget.ImageButton; import android.widget.ListView; import android.widget.PopupWindow; @@ -28,13 +22,13 @@ import java.util.Map; public class TransportOptions { private static final String TAG = TransportOptions.class.getSimpleName(); - private final Context context; - private PopupWindow transportPopup; - private final List enabledTransports = new ArrayList(); - private final Map transportMetadata = new HashMap(); - private String selectedTransport; - private boolean transportOverride = false; - private OnTransportChangedListener listener; + private final Context context; + private PopupWindow transportPopup; + private final List enabledTransports = new ArrayList<>(); + private final Map transportMetadata = new HashMap<>(); + private String selectedTransport; + private boolean transportOverride = false; + private final List listeners = new LinkedList<>(); public TransportOptions(Context context) { this.context = context; @@ -142,13 +136,13 @@ public class TransportOptions { private void updateViews() { if (selectedTransport == null) return; - if (listener != null) { + for (OnTransportChangedListener listener : listeners) { listener.onChange(getSelectedTransport()); } } - public void setOnTransportChangedListener(OnTransportChangedListener listener) { - this.listener = listener; + public void addOnTransportChangedListener(OnTransportChangedListener listener) { + this.listeners.add(listener); } public interface OnTransportChangedListener { diff --git a/src/org/thoughtcrime/securesms/components/SendButton.java b/src/org/thoughtcrime/securesms/components/SendButton.java index fc44e9cec8..234b14e2c5 100644 --- a/src/org/thoughtcrime/securesms/components/SendButton.java +++ b/src/org/thoughtcrime/securesms/components/SendButton.java @@ -37,7 +37,7 @@ public class SendButton extends ImageButton { private void initialize() { transportOptions = new TransportOptions(getContext()); - transportOptions.setOnTransportChangedListener(new OnTransportChangedListener() { + transportOptions.addOnTransportChangedListener(new OnTransportChangedListener() { @Override public void onChange(TransportOption newTransport) { setImageResource(newTransport.drawable); @@ -58,6 +58,10 @@ public class SendButton extends ImageButton { }); } + public void addOnTransportChangedListener(OnTransportChangedListener listener) { + transportOptions.addOnTransportChangedListener(listener); + } + public void setComposeTextView(EditText composeText) { this.composeText = composeText; } diff --git a/src/org/thoughtcrime/securesms/util/CharacterCalculator.java b/src/org/thoughtcrime/securesms/util/CharacterCalculator.java index 696dc63f73..01912c2540 100644 --- a/src/org/thoughtcrime/securesms/util/CharacterCalculator.java +++ b/src/org/thoughtcrime/securesms/util/CharacterCalculator.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2011 Whisper Systems + * Copyright (C) 2015 Whisper Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,29 +16,9 @@ */ package org.thoughtcrime.securesms.util; -import org.thoughtcrime.securesms.sms.SmsTransportDetails; - -public class CharacterCalculator { - - public CharacterState calculateCharacters(int charactersSpent) { - int maxMessageSize; - - if (charactersSpent <= SmsTransportDetails.SMS_SIZE) { - maxMessageSize = SmsTransportDetails.SMS_SIZE; - } else { - maxMessageSize = SmsTransportDetails.MULTIPART_SMS_SIZE; - } - - int messagesSpent = charactersSpent / maxMessageSize; - - if (((charactersSpent % maxMessageSize) > 0) || (messagesSpent == 0)) - messagesSpent++; - - int charactersRemaining = (maxMessageSize * messagesSpent) - charactersSpent; - - return new CharacterState(messagesSpent, charactersRemaining, maxMessageSize); - } +public abstract class CharacterCalculator { + public abstract CharacterState calculateCharacters(int charactersSpent); public class CharacterState { public int charactersRemaining; diff --git a/src/org/thoughtcrime/securesms/util/EncryptedCharacterCalculator.java b/src/org/thoughtcrime/securesms/util/EncryptedSmsCharacterCalculator.java similarity index 95% rename from src/org/thoughtcrime/securesms/util/EncryptedCharacterCalculator.java rename to src/org/thoughtcrime/securesms/util/EncryptedSmsCharacterCalculator.java index 9761d96f57..c7e60acd35 100644 --- a/src/org/thoughtcrime/securesms/util/EncryptedCharacterCalculator.java +++ b/src/org/thoughtcrime/securesms/util/EncryptedSmsCharacterCalculator.java @@ -18,7 +18,7 @@ package org.thoughtcrime.securesms.util; import org.thoughtcrime.securesms.sms.SmsTransportDetails; -public class EncryptedCharacterCalculator extends CharacterCalculator { +public class EncryptedSmsCharacterCalculator extends CharacterCalculator { private CharacterState calculateSingleRecordCharacters(int charactersSpent) { int charactersRemaining = SmsTransportDetails.ENCRYPTED_SINGLE_MESSAGE_BODY_MAX_SIZE - charactersSpent; @@ -41,7 +41,7 @@ public class EncryptedCharacterCalculator extends CharacterCalculator { @Override public CharacterState calculateCharacters(int charactersSpent) { - if (charactersSpent <= SmsTransportDetails.ENCRYPTED_SINGLE_MESSAGE_BODY_MAX_SIZE){ + if (charactersSpent <= SmsTransportDetails.ENCRYPTED_SINGLE_MESSAGE_BODY_MAX_SIZE) { return calculateSingleRecordCharacters(charactersSpent); } else { return calculateMultiRecordCharacters(charactersSpent); diff --git a/src/org/thoughtcrime/securesms/util/PushCharacterCalculator.java b/src/org/thoughtcrime/securesms/util/PushCharacterCalculator.java new file mode 100644 index 0000000000..c5096d2699 --- /dev/null +++ b/src/org/thoughtcrime/securesms/util/PushCharacterCalculator.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2015 Whisper Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.thoughtcrime.securesms.util; + +public class PushCharacterCalculator extends CharacterCalculator { + private static final int MAX_SIZE = 2000; + @Override + public CharacterState calculateCharacters(int charactersSpent) { + return new CharacterState(1, MAX_SIZE - charactersSpent, MAX_SIZE); + } +} + diff --git a/src/org/thoughtcrime/securesms/util/SmsCharacterCalculator.java b/src/org/thoughtcrime/securesms/util/SmsCharacterCalculator.java new file mode 100644 index 0000000000..eb72926bf0 --- /dev/null +++ b/src/org/thoughtcrime/securesms/util/SmsCharacterCalculator.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2011 Whisper Systems + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.thoughtcrime.securesms.util; + +import org.thoughtcrime.securesms.sms.SmsTransportDetails; + +public class SmsCharacterCalculator extends CharacterCalculator { + + @Override + public CharacterState calculateCharacters(int charactersSpent) { + int maxMessageSize; + + if (charactersSpent <= SmsTransportDetails.SMS_SIZE) { + maxMessageSize = SmsTransportDetails.SMS_SIZE; + } else { + maxMessageSize = SmsTransportDetails.MULTIPART_SMS_SIZE; + } + + int messagesSpent = charactersSpent / maxMessageSize; + + if (((charactersSpent % maxMessageSize) > 0) || (messagesSpent == 0)) + messagesSpent++; + + int charactersRemaining = (maxMessageSize * messagesSpent) - charactersSpent; + + return new CharacterState(messagesSpent, charactersRemaining, maxMessageSize); + } +} +