From 4435a790efaf55286d2f5c322e9f78322c251e55 Mon Sep 17 00:00:00 2001 From: kruks23 Date: Wed, 24 Sep 2014 11:14:47 +0200 Subject: [PATCH 01/57] Update Spanish Translations --- res/values-es/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index d6fbc7cb7..85d1d7842 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -254,5 +254,12 @@ Por favor, cuidado con estas opciones Incrementar tamaño de fuente Usar fuentes grandes en toda la aplicación + Botón enviar indica estado + Solicitar entrega de mensaje + Cuando el contacto reciba el mensaje será indicado con una marca verde. Cuidado, esto podría no funcionar en todos los casos. + El color del botón enviar indica el estado del contacto + Otros + Nombre de conferencia + Usar el asunto de la conferencia en lugar del identificador jabber como nombre de conferencia \ No newline at end of file From 92197a47968abddce3290ee53597d3e9d4abede6 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 24 Sep 2014 15:00:12 +0200 Subject: [PATCH 02/57] added Aizaz AZ as translator to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ec510c150..99f5f429f 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ These XEPs are - as of now: * [Ilia Rostovtsev](https://github.com/qooob) (Russian) * [Jelmer Vernooij](https://github.com/jelmer) (Dutch) * [Anders Sandblad](https://github.com/andersruneson) (Swedish) +* [Aizaz AZ](http://www.linkedin.com/in/aizazhaider) (Chinese) ##FAQ ###General From 642a70765ce028419a0577d730a009bfbbf6ffb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20Wei=C3=9F?= Date: Wed, 24 Sep 2014 22:52:02 +0200 Subject: [PATCH 03/57] Add missing German translations --- res/values-de/arrays.xml | 7 +++++++ res/values-de/strings.xml | 2 ++ 2 files changed, 9 insertions(+) diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml index e468f478b..9b429c5a7 100644 --- a/res/values-de/arrays.xml +++ b/res/values-de/arrays.xml @@ -20,5 +20,12 @@ 524288 1048576 + + 30 Minuten + eine Stunde + 2 Stunden + 8 Stunden + bis auf Widerruf + \ No newline at end of file diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 14397e163..0c230ec64 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -259,5 +259,7 @@ Absende-Knopf zeigt Online-Status an Absende-Knopf einfärben, um den Online-Status des Kontakts zu signalisieren Sonstiges + Konferenz-Name + Konferenz-Thema statt Raum-JID als Name verwenden From 9fef0d1a997f9b70403f11560814f260e354bf1a Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 26 Sep 2014 21:06:36 +0200 Subject: [PATCH 04/57] fix lint-warning: Wrong locale name The Hebrew ("he") language code is rewritten as "iw" --- res/{values-he => values-iw}/arrays.xml | 0 res/{values-he => values-iw}/strings.xml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename res/{values-he => values-iw}/arrays.xml (100%) rename res/{values-he => values-iw}/strings.xml (100%) diff --git a/res/values-he/arrays.xml b/res/values-iw/arrays.xml similarity index 100% rename from res/values-he/arrays.xml rename to res/values-iw/arrays.xml diff --git a/res/values-he/strings.xml b/res/values-iw/strings.xml similarity index 100% rename from res/values-he/strings.xml rename to res/values-iw/strings.xml From 1d42385e0e1e3da85f22125a11e39d32d09bebf4 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 26 Sep 2014 21:21:58 +0200 Subject: [PATCH 05/57] fix lint-warning: Hardcoded text --- res/layout/dialog_verify_otr.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/layout/dialog_verify_otr.xml b/res/layout/dialog_verify_otr.xml index 831f06edc..499ef6cde 100644 --- a/res/layout/dialog_verify_otr.xml +++ b/res/layout/dialog_verify_otr.xml @@ -11,7 +11,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="8dp" - android:text="Jabber ID" + android:text="@string/account_settings_jabber_id" android:textColor="@color/primarytext" android:textSize="?attr/TextSizeHeadline" /> From 6e7734340797c0e929a3669056d0c1361cac7384 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 10:51:46 +0200 Subject: [PATCH 06/57] revised send button in landscape mode --- res/layout/fragment_conversation.xml | 2 +- src/eu/siacs/conversations/ui/ConversationFragment.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/res/layout/fragment_conversation.xml b/res/layout/fragment_conversation.xml index 0f5f692e4..f9aae10a0 100644 --- a/res/layout/fragment_conversation.xml +++ b/res/layout/fragment_conversation.xml @@ -37,7 +37,7 @@ android:layout_toLeftOf="@+id/textSendButton" android:background="@color/primarybackground" android:ems="10" - android:imeOptions="flagNoExtractUi" + android:imeOptions="flagNoExtractUi|actionSend" android:inputType="textShortMessage|textMultiLine|textCapSentences" android:minHeight="48dp" android:minLines="1" diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index feed9df5a..9e2d39e59 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -76,10 +76,11 @@ public class ConversationFragment extends Fragment { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) { + if (actionId == EditorInfo.IME_ACTION_SEND) { InputMethodManager imm = (InputMethodManager) v.getContext() .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); + sendMessage(); return true; } else { return false; From 8fb0fb0c0d7a760d1bea33701a794f3ab2ba6664 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 11:37:02 +0200 Subject: [PATCH 07/57] anwser to xmpp: style uris. fixed open conversations from android address book --- AndroidManifest.xml | 10 ++- .../siacs/conversations/entities/Roster.java | 13 ++- .../services/XmppConnectionService.java | 21 ++++- .../ui/StartConversationActivity.java | 82 ++++++++++++++++--- .../siacs/conversations/ui/XmppActivity.java | 1 + 5 files changed, 107 insertions(+), 20 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 33dcdfa4b..d86d5bb15 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -63,6 +63,14 @@ + + + + + + + + - + \ No newline at end of file diff --git a/src/eu/siacs/conversations/entities/Roster.java b/src/eu/siacs/conversations/entities/Roster.java index f11f0250d..b69087934 100644 --- a/src/eu/siacs/conversations/entities/Roster.java +++ b/src/eu/siacs/conversations/entities/Roster.java @@ -14,13 +14,18 @@ public class Roster { this.account = account; } - public boolean hasContact(String jid) { - String cleanJid = jid.split("/",2)[0]; - return contacts.containsKey(cleanJid); + public Contact getContactAsShownInRoster(String jid) { + String cleanJid = jid.split("/", 2)[0]; + Contact contact = contacts.get(cleanJid); + if (contact != null && contact.showInRoster()) { + return contact; + } else { + return null; + } } public Contact getContact(String jid) { - String cleanJid = jid.split("/",2)[0].toLowerCase(Locale.getDefault()); + String cleanJid = jid.split("/", 2)[0].toLowerCase(Locale.getDefault()); if (contacts.containsKey(cleanJid)) { return contacts.get(cleanJid); } else { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index db3ee2b91..524a3bd78 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -824,7 +824,7 @@ public class XmppConnectionService extends Service { } }); } - + public int loadMoreMessages(Conversation conversation, long timestamp) { List messages = databaseBackend.getMessages(conversation, 50, timestamp); @@ -851,8 +851,9 @@ public class XmppConnectionService extends Service { public Conversation find(List haystack, Account account, String jid) { for (Conversation conversation : haystack) { - if ((conversation.getAccount().equals(account)) - && (conversation.getContactJid().split("/",2)[0].equals(jid))) { + if ((account == null || conversation.getAccount().equals(account)) + && (conversation.getContactJid().split("/", 2)[0] + .equals(jid))) { return conversation; } } @@ -1742,4 +1743,18 @@ public class XmppConnectionService extends Service { public interface OnRosterUpdate { public void onRosterUpdate(); } + + public List findContacts(String jid) { + ArrayList contacts = new ArrayList(); + for (Account account : getAccounts()) { + if (!account.isOptionSet(Account.OPTION_DISABLED)) { + Contact contact = account.getRoster() + .getContactAsShownInRoster(jid); + if (contact != null) { + contacts.add(contact); + } + } + } + return contacts; + } } diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index db6c15096..612dd5853 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.ui; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -14,6 +16,8 @@ import android.app.ListFragment; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.v13.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; @@ -157,6 +161,8 @@ public class StartConversationActivity extends XmppActivity { }); } }; + private MenuItem mMenuSearchView; + private String mInitialJid; @Override public void onCreate(Bundle savedInstanceState) { @@ -308,7 +314,7 @@ public class StartConversationActivity extends XmppActivity { } - protected void showCreateContactDialog() { + protected void showCreateContactDialog(String prefilledJid) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.create_contact); View dialogView = getLayoutInflater().inflate( @@ -317,7 +323,10 @@ public class StartConversationActivity extends XmppActivity { final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView .findViewById(R.id.jid); jid.setAdapter(new KnownHostsAdapter(this, - android.R.layout.simple_list_item_1, mKnownHosts)); + android.R.layout.simple_list_item_1, mKnownHosts)); + if (prefilledJid!=null) { + jid.append(prefilledJid); + } populateAccountSpinner(spinner); builder.setView(dialogView); builder.setNegativeButton(R.string.cancel, null); @@ -449,9 +458,9 @@ public class StartConversationActivity extends XmppActivity { .findItem(R.id.action_create_contact); MenuItem menuCreateConference = (MenuItem) menu .findItem(R.id.action_join_conference); - MenuItem menuSearchView = (MenuItem) menu.findItem(R.id.action_search); - menuSearchView.setOnActionExpandListener(mOnActionExpandListener); - View mSearchView = menuSearchView.getActionView(); + mMenuSearchView = (MenuItem) menu.findItem(R.id.action_search); + mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener); + View mSearchView = mMenuSearchView.getActionView(); mSearchEditText = (EditText) mSearchView .findViewById(R.id.search_field); mSearchEditText.addTextChangedListener(mSearchTextWatcher); @@ -460,6 +469,11 @@ public class StartConversationActivity extends XmppActivity { } else { menuCreateContact.setVisible(false); } + if (mInitialJid != null) { + mMenuSearchView.expandActionView(); + mSearchEditText.append(mInitialJid); + filter(mInitialJid); + } return true; } @@ -467,7 +481,7 @@ public class StartConversationActivity extends XmppActivity { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_create_contact: - showCreateContactDialog(); + showCreateContactDialog(null); break; case R.id.action_join_conference: showJoinConferenceDialog(); @@ -486,13 +500,8 @@ public class StartConversationActivity extends XmppActivity { } @Override - void onBackendConnected() { + protected void onBackendConnected() { xmppConnectionService.setOnRosterUpdateListener(this.onRosterUpdate); - if (mSearchEditText != null) { - filter(mSearchEditText.getText().toString()); - } else { - filter(null); - } this.mActivatedAccounts.clear(); for (Account account : xmppConnectionService.getAccounts()) { if (account.getStatus() != Account.STATUS_DISABLED) { @@ -502,6 +511,55 @@ public class StartConversationActivity extends XmppActivity { this.mKnownHosts = xmppConnectionService.getKnownHosts(); this.mKnownConferenceHosts = xmppConnectionService .getKnownConferenceHosts(); + if (!startByIntent()) { + if (mSearchEditText != null) { + filter(mSearchEditText.getText().toString()); + } else { + filter(null); + } + } + } + + protected boolean startByIntent() { + if (getIntent() != null + && Intent.ACTION_SENDTO.equals(getIntent().getAction())) { + try { + String jid = URLDecoder.decode( + getIntent().getData().getEncodedPath(), "UTF-8").split( + "/")[1]; + setIntent(null); + return handleJid(jid); + } catch (UnsupportedEncodingException e) { + setIntent(null); + return false; + } + } else if (getIntent() != null && Intent.ACTION_VIEW.equals(getIntent().getAction())) { + Uri uri = getIntent().getData(); + String jid = uri.getSchemeSpecificPart().split("\\?")[0]; + return handleJid(jid); + } + return false; + } + + private boolean handleJid(String jid) { + List contacts = xmppConnectionService + .findContacts(jid); + if (contacts.size() == 0) { + showCreateContactDialog(jid); + return false; + } else if (contacts.size() == 1) { + switchToConversation(contacts.get(0)); + return true; + } else { + if (mMenuSearchView != null) { + mMenuSearchView.expandActionView(); + mSearchEditText.setText(jid); + filter(jid); + } else { + mInitialJid = jid; + } + return true; + } } protected void filter(String needle) { diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 26a33d1a8..63dbdd111 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -245,6 +245,7 @@ public abstract class XmppActivity extends Activity { | Intent.FLAG_ACTIVITY_CLEAR_TOP); } startActivity(viewConversationIntent); + finish(); } public void switchToContactDetails(Contact contact) { From 2415781ebf6fdf8846baf8294c4b0c49310b5c79 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 11:46:56 +0200 Subject: [PATCH 08/57] fixed some lint warnings. thanks @betheg --- src/eu/siacs/conversations/ui/ConversationActivity.java | 2 ++ src/eu/siacs/conversations/ui/StartConversationActivity.java | 3 +++ src/eu/siacs/conversations/ui/XmppActivity.java | 2 ++ src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java | 2 +- src/eu/siacs/conversations/utils/UIHelper.java | 2 ++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 89d823a13..6fc5d36d6 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -17,6 +17,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.provider.MediaStore; +import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.AlertDialog; import android.app.FragmentTransaction; @@ -376,6 +377,7 @@ public class ConversationActivity extends XmppActivity implements } } + @SuppressLint("InflateParams") protected void clearHistoryDialog(final Conversation conversation) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.clear_conversation_history)); diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index 612dd5853..e4b49d082 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import android.annotation.SuppressLint; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.ActionBar.TabListener; @@ -314,6 +315,7 @@ public class StartConversationActivity extends XmppActivity { } + @SuppressLint("InflateParams") protected void showCreateContactDialog(String prefilledJid) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.create_contact); @@ -368,6 +370,7 @@ public class StartConversationActivity extends XmppActivity { } + @SuppressLint("InflateParams") protected void showJoinConferenceDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.join_conference); diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 63dbdd111..1a94c7666 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -15,6 +15,7 @@ import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; import eu.siacs.conversations.utils.ExceptionHelper; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.PendingIntent; @@ -390,6 +391,7 @@ public abstract class XmppActivity extends Activity { quickEdit(previousValue, callback, true); } + @SuppressLint("InflateParams") private void quickEdit(final String previousValue, final OnValueEdited callback, boolean password) { AlertDialog.Builder builder = new AlertDialog.Builder(this); diff --git a/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java index 9ef427fc5..789e4c340 100644 --- a/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java @@ -24,7 +24,7 @@ public class ListItemAdapter extends ArrayAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); ListItem item = getItem(position); if (view == null) { - view = (View) inflater.inflate(R.layout.contact, null); + view = (View) inflater.inflate(R.layout.contact, parent); } TextView name = (TextView) view.findViewById(R.id.contact_display_name); TextView jid = (TextView) view.findViewById(R.id.contact_jid); diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index f6e66cdb7..d18263155 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -17,6 +17,7 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions.User; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Notification; @@ -511,6 +512,7 @@ public class UIHelper { badge.setImageBitmap(contact.getImage(72, context)); } + @SuppressLint("InflateParams") public static AlertDialog getVerifyFingerprintDialog( final ConversationActivity activity, final Conversation conversation, final View msg) { From b9183bb31751704dd21f08ef784c6e8fab986a4f Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 14:31:16 +0200 Subject: [PATCH 09/57] added flattr button --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 99f5f429f..5d411cdca 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ The more convenient way - which not only gives you automatic updates but also supports the further development of Conversations - is to buy the App in the Google [Play Store](https://play.google.com/store/apps/details?id=eu.siacs.conversations). ####I don't have a Google Account but I would still like to make a contribution -I accept donations over PayPal and BitCoin. For donations via PayPal you can use the email address donate@siacs.eu or the button below. +I accept donations over PayPal, BitCoin and Flattr. For donations via PayPal you can use the email address donate@siacs.eu or the button below. [![Donate with PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CW3SYT3KG5PDL) @@ -92,6 +92,9 @@ transfer (SEPA). My Bitcoin Address is: 1NxSU1YxYzJVDpX1rcESAA3NJki7kRgeeu + +[![Flattr this!](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=inputmice&url=https%3A%2F%2Fgithub.com%2Fsiacs%2FConversation) + ####How do I create an account? XMPP like email for example is a federated protocol which means that there is not one company you can create your 'official xmpp account' with but there are From 0746d8750602a038f5899848a8ba6fd12024a7cc Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 14:32:35 +0200 Subject: [PATCH 10/57] fixed link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d411cdca..da376cf66 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ transfer (SEPA). My Bitcoin Address is: 1NxSU1YxYzJVDpX1rcESAA3NJki7kRgeeu -[![Flattr this!](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=inputmice&url=https%3A%2F%2Fgithub.com%2Fsiacs%2FConversation) +[![Flattr this!](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=inputmice&url=https%3A%2F%2Fgithub.com%2Fsiacs%2FConversations) ####How do I create an account? XMPP like email for example is a federated protocol which means that there is From 1d3a6125d2c2ee06ed1229be13dd1cfa4e178e51 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 27 Sep 2014 16:45:37 +0200 Subject: [PATCH 11/57] add false argument to inflate. --- src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java index 789e4c340..df67e5663 100644 --- a/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ListItemAdapter.java @@ -24,7 +24,7 @@ public class ListItemAdapter extends ArrayAdapter { .getSystemService(Context.LAYOUT_INFLATER_SERVICE); ListItem item = getItem(position); if (view == null) { - view = (View) inflater.inflate(R.layout.contact, parent); + view = (View) inflater.inflate(R.layout.contact, parent, false); } TextView name = (TextView) view.findViewById(R.id.contact_display_name); TextView jid = (TextView) view.findViewById(R.id.contact_jid); @@ -36,4 +36,4 @@ public class ListItemAdapter extends ArrayAdapter { return view; } -} \ No newline at end of file +} From 1ae9338fc9d5f8e1f6505445f07f4476efd8f139 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 27 Sep 2014 18:16:31 +0200 Subject: [PATCH 12/57] made muc passwords and prefereced encryption method persistant across restarts --- .../conversations/entities/Conversation.java | 65 ++++++++++++++++--- .../conversations/entities/MucOptions.java | 4 +- .../conversations/parser/MessageParser.java | 2 + .../persistance/DatabaseBackend.java | 10 ++- .../services/XmppConnectionService.java | 1 + .../ui/ConversationActivity.java | 2 + .../ui/ConversationFragment.java | 2 + .../siacs/conversations/ui/XmppActivity.java | 1 + 8 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 8395449db..b8d375860 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -4,6 +4,9 @@ import java.security.interfaces.DSAPublicKey; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import org.json.JSONException; +import org.json.JSONObject; + import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.UIHelper; @@ -36,6 +39,10 @@ public class Conversation extends AbstractEntity { public static final String STATUS = "status"; public static final String CREATED = "created"; public static final String MODE = "mode"; + public static final String ATTRIBUTES = "attributes"; + + public static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; + public static final String ATTRIBUTE_MUC_PASSWORD = "muc_password"; private String name; private String contactUuid; @@ -44,6 +51,8 @@ public class Conversation extends AbstractEntity { private int status; private long created; private int mode; + + private JSONObject attributes = new JSONObject(); private long mutedTill = 0; @@ -56,7 +65,6 @@ public class Conversation extends AbstractEntity { private transient String otrFingerprint = null; - private int nextMessageEncryption = -1; private String nextMessage; private transient MucOptions mucOptions = null; @@ -73,13 +81,13 @@ public class Conversation extends AbstractEntity { int mode) { this(java.util.UUID.randomUUID().toString(), name, null, account .getUuid(), contactJid, System.currentTimeMillis(), - STATUS_AVAILABLE, mode); + STATUS_AVAILABLE, mode,""); this.account = account; } public Conversation(String uuid, String name, String contactUuid, String accountUuid, String contactJid, long created, int status, - int mode) { + int mode, String attributes) { this.uuid = uuid; this.name = name; this.contactUuid = contactUuid; @@ -88,6 +96,14 @@ public class Conversation extends AbstractEntity { this.created = created; this.status = status; this.mode = mode; + try { + if (attributes==null) { + attributes = new String(); + } + this.attributes = new JSONObject(attributes); + } catch (JSONException e) { + this.attributes = new JSONObject(); + } } public List getMessages() { @@ -198,6 +214,7 @@ public class Conversation extends AbstractEntity { values.put(CREATED, created); values.put(STATUS, status); values.put(MODE, mode); + values.put(ATTRIBUTES,attributes.toString()); return values; } @@ -209,7 +226,8 @@ public class Conversation extends AbstractEntity { cursor.getString(cursor.getColumnIndex(CONTACTJID)), cursor.getLong(cursor.getColumnIndex(CREATED)), cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(MODE))); + cursor.getInt(cursor.getColumnIndex(MODE)), + cursor.getString(cursor.getColumnIndex(ATTRIBUTES))); } public void setStatus(int status) { @@ -345,7 +363,8 @@ public class Conversation extends AbstractEntity { } public int getNextEncryption(boolean force) { - if (this.nextMessageEncryption == -1) { + int next = this.getIntAttribute(ATTRIBUTE_NEXT_ENCRYPTION, -1); + if (next == -1) { int latest = this.getLatestEncryption(); if (latest == Message.ENCRYPTION_NONE) { if (force && getMode() == MODE_SINGLE) { @@ -363,16 +382,16 @@ public class Conversation extends AbstractEntity { return latest; } } - if (this.nextMessageEncryption == Message.ENCRYPTION_NONE && force + if (next == Message.ENCRYPTION_NONE && force && getMode() == MODE_SINGLE) { return Message.ENCRYPTION_OTR; } else { - return this.nextMessageEncryption; + return next; } } public void setNextEncryption(int encryption) { - this.nextMessageEncryption = encryption; + this.setAttribute(ATTRIBUTE_NEXT_ENCRYPTION, String.valueOf(encryption)); } public String getNextMessage() { @@ -440,4 +459,34 @@ public class Conversation extends AbstractEntity { public boolean isMuted() { return SystemClock.elapsedRealtime() < this.mutedTill; } + + public boolean setAttribute(String key, String value) { + try { + this.attributes.put(key, value); + return true; + } catch (JSONException e) { + return false; + } + } + + public String getAttribute(String key) { + try { + return this.attributes.getString(key); + } catch (JSONException e) { + return null; + } + } + + public int getIntAttribute(String key, int defaultValue) { + String value = this.getAttribute(key); + if (value==null) { + return defaultValue; + } else { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + } } diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java index 676fb4f40..91a3d260a 100644 --- a/src/eu/siacs/conversations/entities/MucOptions.java +++ b/src/eu/siacs/conversations/entities/MucOptions.java @@ -323,7 +323,8 @@ public class MucOptions { } public String getPassword() { - if (conversation.getBookmark() != null + this.password = conversation.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); + if (this.password == null && conversation.getBookmark() != null && conversation.getBookmark().getPassword() != null) { return conversation.getBookmark().getPassword(); } else { @@ -338,6 +339,7 @@ public class MucOptions { } else { this.password = password; } + conversation.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); } public boolean isPasswordChanged() { diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 1c77d10d5..9e2ccd921 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -298,6 +298,7 @@ public class MessageParser extends AbstractParser implements Element password = x.findChild("password"); conversation.getMucOptions().setPassword( password.getContent()); + mXmppConnectionService.databaseBackend.updateConversation(conversation); } mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); @@ -313,6 +314,7 @@ public class MessageParser extends AbstractParser implements if (!conversation.getMucOptions().online()) { if (password != null) { conversation.getMucOptions().setPassword(password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); } mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java index 51fd79e50..7afe387e4 100644 --- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -19,7 +19,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 7; + private static final int DATABASE_VERSION = 8; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -50,8 +50,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { + " TEXT, " + Conversation.CONTACT + " TEXT, " + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACTJID + " TEXT, " + Conversation.CREATED + " NUMBER, " - + Conversation.STATUS + " NUMBER," + Conversation.MODE - + " NUMBER," + "FOREIGN KEY(" + Conversation.ACCOUNT + + Conversation.STATUS + " NUMBER, " + Conversation.MODE + + " NUMBER, "+Conversation.ATTRIBUTES + " TEXT, FOREIGN KEY(" + Conversation.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE);"); db.execSQL("create table " + Message.TABLENAME + "( " + Message.UUID @@ -96,6 +96,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.AVATAR + " TEXT"); } + if (oldVersion < 8 && newVersion >= 8) { + db.execSQL("ALTER TABLE " + Conversation.TABLENAME + " ADD COLUMN " + + Conversation.ATTRIBUTES + " TEXT"); + } } public static synchronized DatabaseBackend getInstance(Context context) { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 524a3bd78..badf1df52 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1119,6 +1119,7 @@ public class XmppConnectionService extends Service { } pushBookmarks(conversation.getAccount()); } + databaseBackend.updateConversation(conversation); joinMuc(conversation); } } diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 6fc5d36d6..b6b6aa722 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -297,6 +297,7 @@ public class ConversationActivity extends XmppActivity implements int which) { conversation .setNextEncryption(Message.ENCRYPTION_NONE); + xmppConnectionService.databaseBackend.updateConversation(conversation); selectPresenceToAttachFile(attachmentChoice); } }); @@ -472,6 +473,7 @@ public class ConversationActivity extends XmppActivity implements conversation.setNextEncryption(Message.ENCRYPTION_NONE); break; } + xmppConnectionService.databaseBackend.updateConversation(conversation); fragment.updateChatMsgHint(); return true; } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 9e2d39e59..a8dee4f76 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -668,6 +668,7 @@ public class ConversationFragment extends Fragment { int which) { conversation .setNextEncryption(Message.ENCRYPTION_NONE); + xmppService.databaseBackend.updateConversation(conversation); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.sendMessage(message); messageSent(); @@ -696,6 +697,7 @@ public class ConversationFragment extends Fragment { conversation .setNextEncryption(Message.ENCRYPTION_NONE); message.setEncryption(Message.ENCRYPTION_NONE); + xmppService.databaseBackend.updateConversation(conversation); xmppService.sendMessage(message); messageSent(); } diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 1a94c7666..b54bc1524 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -294,6 +294,7 @@ public abstract class XmppActivity extends Activity { if (conversation != null) { conversation .setNextEncryption(Message.ENCRYPTION_PGP); + xmppConnectionService.databaseBackend.updateConversation(conversation); } } From bff23c2e232e8f9a4e64553215130079b7fc5a4f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Sep 2014 15:21:56 +0200 Subject: [PATCH 13/57] new notification service. first draft --- .../conversations/entities/Conversation.java | 22 +-- .../conversations/entities/MucOptions.java | 14 +- .../generator/AbstractGenerator.java | 4 +- .../generator/MessageGenerator.java | 8 +- .../conversations/parser/AbstractParser.java | 2 +- .../conversations/parser/MessageParser.java | 11 +- .../conversations/parser/PresenceParser.java | 4 +- .../persistance/DatabaseBackend.java | 13 +- .../conversations/services/EventReceiver.java | 3 +- .../conversations/services/ImageProvider.java | 2 +- .../services/NotificationService.java | 165 ++++++++++++++++++ .../services/XmppConnectionService.java | 19 +- .../ui/ConferenceDetailsActivity.java | 2 +- .../ui/ConversationActivity.java | 10 +- .../ui/ConversationFragment.java | 14 +- .../conversations/ui/SettingsActivity.java | 18 +- .../ui/StartConversationActivity.java | 10 +- .../siacs/conversations/ui/XmppActivity.java | 9 +- .../ui/adapter/ConversationAdapter.java | 3 +- .../siacs/conversations/utils/UIHelper.java | 2 +- .../conversations/xmpp/XmppConnection.java | 2 +- .../xmpp/jingle/JingleConnection.java | 11 +- 22 files changed, 264 insertions(+), 84 deletions(-) create mode 100644 src/eu/siacs/conversations/services/NotificationService.java diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index b8d375860..fedb0893a 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -40,7 +40,7 @@ public class Conversation extends AbstractEntity { public static final String CREATED = "created"; public static final String MODE = "mode"; public static final String ATTRIBUTES = "attributes"; - + public static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; public static final String ATTRIBUTE_MUC_PASSWORD = "muc_password"; @@ -51,7 +51,7 @@ public class Conversation extends AbstractEntity { private int status; private long created; private int mode; - + private JSONObject attributes = new JSONObject(); private long mutedTill = 0; @@ -81,7 +81,7 @@ public class Conversation extends AbstractEntity { int mode) { this(java.util.UUID.randomUUID().toString(), name, null, account .getUuid(), contactJid, System.currentTimeMillis(), - STATUS_AVAILABLE, mode,""); + STATUS_AVAILABLE, mode, ""); this.account = account; } @@ -97,7 +97,7 @@ public class Conversation extends AbstractEntity { this.status = status; this.mode = mode; try { - if (attributes==null) { + if (attributes == null) { attributes = new String(); } this.attributes = new JSONObject(attributes); @@ -214,7 +214,7 @@ public class Conversation extends AbstractEntity { values.put(CREATED, created); values.put(STATUS, status); values.put(MODE, mode); - values.put(ATTRIBUTES,attributes.toString()); + values.put(ATTRIBUTES, attributes.toString()); return values; } @@ -247,8 +247,8 @@ public class Conversation extends AbstractEntity { if (this.otrSession != null) { return this.otrSession; } else { - SessionID sessionId = new SessionID( - this.getContactJid().split("/",2)[0], presence, "xmpp"); + SessionID sessionId = new SessionID(this.getContactJid().split("/", + 2)[0], presence, "xmpp"); this.otrSession = new SessionImpl(sessionId, getAccount() .getOtrEngine(service)); try { @@ -459,7 +459,7 @@ public class Conversation extends AbstractEntity { public boolean isMuted() { return SystemClock.elapsedRealtime() < this.mutedTill; } - + public boolean setAttribute(String key, String value) { try { this.attributes.put(key, value); @@ -468,7 +468,7 @@ public class Conversation extends AbstractEntity { return false; } } - + public String getAttribute(String key) { try { return this.attributes.getString(key); @@ -476,10 +476,10 @@ public class Conversation extends AbstractEntity { return null; } } - + public int getIntAttribute(String key, int defaultValue) { String value = this.getAttribute(key); - if (value==null) { + if (value == null) { return defaultValue; } else { try { diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java index 91a3d260a..0294c8aae 100644 --- a/src/eu/siacs/conversations/entities/MucOptions.java +++ b/src/eu/siacs/conversations/entities/MucOptions.java @@ -134,7 +134,7 @@ public class MucOptions { } public void processPacket(PresencePacket packet, PgpEngine pgp) { - String[] fromParts = packet.getFrom().split("/",2); + String[] fromParts = packet.getFrom().split("/", 2); if (fromParts.length >= 2) { String name = fromParts[1]; String type = packet.getAttribute("type"); @@ -180,7 +180,7 @@ public class MucOptions { } } } else if (type.equals("unavailable")) { - deleteUser(packet.getAttribute("from").split("/",2)[1]); + deleteUser(packet.getAttribute("from").split("/", 2)[1]); } else if (type.equals("error")) { Element error = packet.findChild("error"); if (error.hasChild("conflict")) { @@ -209,7 +209,7 @@ public class MucOptions { } public String getProposedNick() { - String[] mucParts = conversation.getContactJid().split("/",2); + String[] mucParts = conversation.getContactJid().split("/", 2); if (conversation.getBookmark() != null && conversation.getBookmark().getNick() != null) { return conversation.getBookmark().getNick(); @@ -309,7 +309,7 @@ public class MucOptions { } public String getJoinJid() { - return this.conversation.getContactJid().split("/",2)[0] + "/" + return this.conversation.getContactJid().split("/", 2)[0] + "/" + this.joinnick; } @@ -323,7 +323,8 @@ public class MucOptions { } public String getPassword() { - this.password = conversation.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); + this.password = conversation + .getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); if (this.password == null && conversation.getBookmark() != null && conversation.getBookmark().getPassword() != null) { return conversation.getBookmark().getPassword(); @@ -339,7 +340,8 @@ public class MucOptions { } else { this.password = password; } - conversation.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); + conversation + .setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); } public boolean isPasswordChanged() { diff --git a/src/eu/siacs/conversations/generator/AbstractGenerator.java b/src/eu/siacs/conversations/generator/AbstractGenerator.java index 61f290e4a..c96d116d0 100644 --- a/src/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/eu/siacs/conversations/generator/AbstractGenerator.java @@ -21,9 +21,9 @@ public abstract class AbstractGenerator { "urn:xmpp:avatar:metadata+notify" }; public final String IDENTITY_NAME = "Conversations 0.7"; public final String IDENTITY_TYPE = "phone"; - + protected XmppConnectionService mXmppConnectionService; - + protected AbstractGenerator(XmppConnectionService service) { this.mXmppConnectionService = service; } diff --git a/src/eu/siacs/conversations/generator/MessageGenerator.java b/src/eu/siacs/conversations/generator/MessageGenerator.java index d4cab3edd..dd833e56c 100644 --- a/src/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/eu/siacs/conversations/generator/MessageGenerator.java @@ -34,7 +34,7 @@ public class MessageGenerator extends AbstractGenerator { packet.setTo(message.getCounterpart()); packet.setType(MessagePacket.TYPE_CHAT); } else { - packet.setTo(message.getCounterpart().split("/",2)[0]); + packet.setTo(message.getCounterpart().split("/", 2)[0]); packet.setType(MessagePacket.TYPE_GROUPCHAT); } packet.setFrom(account.getFullJid()); @@ -134,7 +134,7 @@ public class MessageGenerator extends AbstractGenerator { String subject) { MessagePacket packet = new MessagePacket(); packet.setType(MessagePacket.TYPE_GROUPCHAT); - packet.setTo(conversation.getContactJid().split("/",2)[0]); + packet.setTo(conversation.getContactJid().split("/", 2)[0]); Element subjectChild = new Element("subject"); subjectChild.setContent(subject); packet.addChild(subjectChild); @@ -148,13 +148,13 @@ public class MessageGenerator extends AbstractGenerator { packet.setTo(contact); packet.setFrom(conversation.getAccount().getFullJid()); Element x = packet.addChild("x", "jabber:x:conference"); - x.setAttribute("jid", conversation.getContactJid().split("/",2)[0]); + x.setAttribute("jid", conversation.getContactJid().split("/", 2)[0]); return packet; } public MessagePacket invite(Conversation conversation, String contact) { MessagePacket packet = new MessagePacket(); - packet.setTo(conversation.getContactJid().split("/",2)[0]); + packet.setTo(conversation.getContactJid().split("/", 2)[0]); packet.setFrom(conversation.getAccount().getFullJid()); Element x = new Element("x"); x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user"); diff --git a/src/eu/siacs/conversations/parser/AbstractParser.java b/src/eu/siacs/conversations/parser/AbstractParser.java index efbf5aef1..5541c1c61 100644 --- a/src/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/eu/siacs/conversations/parser/AbstractParser.java @@ -60,7 +60,7 @@ public abstract class AbstractParser { protected void updateLastseen(Element packet, Account account, boolean presenceOverwrite) { - String[] fromParts = packet.getAttribute("from").split("/",2); + String[] fromParts = packet.getAttribute("from").split("/", 2); String from = fromParts[0]; String presence = null; if (fromParts.length >= 2) { diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 9e2ccd921..3891ebf7c 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -298,7 +298,8 @@ public class MessageParser extends AbstractParser implements Element password = x.findChild("password"); conversation.getMucOptions().setPassword( password.getContent()); - mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.databaseBackend + .updateConversation(conversation); } mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); @@ -314,7 +315,8 @@ public class MessageParser extends AbstractParser implements if (!conversation.getMucOptions().online()) { if (password != null) { conversation.getMucOptions().setPassword(password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.databaseBackend + .updateConversation(conversation); } mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); @@ -465,7 +467,10 @@ public class MessageParser extends AbstractParser implements } } notify = notify && !conversation.isMuted(); - mXmppConnectionService.notifyUi(conversation, notify); + if (notify) { + mXmppConnectionService.pushNotification(message); + } + mXmppConnectionService.updateConversationUi(); } private void parseHeadline(MessagePacket packet, Account account) { diff --git a/src/eu/siacs/conversations/parser/PresenceParser.java b/src/eu/siacs/conversations/parser/PresenceParser.java index e240a8581..507ebbd2b 100644 --- a/src/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/eu/siacs/conversations/parser/PresenceParser.java @@ -22,7 +22,7 @@ public class PresenceParser extends AbstractParser implements PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine(); if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) { Conversation muc = mXmppConnectionService.find(account, packet - .getAttribute("from").split("/",2)[0]); + .getAttribute("from").split("/", 2)[0]); if (muc != null) { boolean before = muc.getMucOptions().online(); muc.getMucOptions().processPacket(packet, mPgpEngine); @@ -32,7 +32,7 @@ public class PresenceParser extends AbstractParser implements } } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) { Conversation muc = mXmppConnectionService.find(account, packet - .getAttribute("from").split("/",2)[0]); + .getAttribute("from").split("/", 2)[0]); if (muc != null) { boolean before = muc.getMucOptions().online(); muc.getMucOptions().processPacket(packet, mPgpEngine); diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java index 7afe387e4..0231c0e7e 100644 --- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -51,9 +51,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACTJID + " TEXT, " + Conversation.CREATED + " NUMBER, " + Conversation.STATUS + " NUMBER, " + Conversation.MODE - + " NUMBER, "+Conversation.ATTRIBUTES + " TEXT, FOREIGN KEY(" + Conversation.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID - + ") ON DELETE CASCADE);"); + + " NUMBER, " + Conversation.ATTRIBUTES + " TEXT, FOREIGN KEY(" + + Conversation.ACCOUNT + ") REFERENCES " + Account.TABLENAME + + "(" + Account.UUID + ") ON DELETE CASCADE);"); db.execSQL("create table " + Message.TABLENAME + "( " + Message.UUID + " TEXT PRIMARY KEY, " + Message.CONVERSATION + " TEXT, " + Message.TIME_SENT + " NUMBER, " + Message.COUNTERPART @@ -225,13 +225,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid() }; db.delete(Account.TABLENAME, Account.UUID + "=?", args); } - + public boolean hasEnabledAccounts() { SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor= db.rawQuery("select count("+Account.UUID+") from "+Account.TABLENAME+" where not options & (1 <<1)", null); + Cursor cursor = db.rawQuery("select count(" + Account.UUID + ") from " + + Account.TABLENAME + " where not options & (1 <<1)", null); cursor.moveToFirst(); int count = cursor.getInt(0); - return (count>0); + return (count > 0); } @Override diff --git a/src/eu/siacs/conversations/services/EventReceiver.java b/src/eu/siacs/conversations/services/EventReceiver.java index e2445b2a9..dfbe9db76 100644 --- a/src/eu/siacs/conversations/services/EventReceiver.java +++ b/src/eu/siacs/conversations/services/EventReceiver.java @@ -15,7 +15,8 @@ public class EventReceiver extends BroadcastReceiver { } else { mIntentForService.setAction("other"); } - if (intent.getAction().equals("ui") || DatabaseBackend.getInstance(context).hasEnabledAccounts()) { + if (intent.getAction().equals("ui") + || DatabaseBackend.getInstance(context).hasEnabledAccounts()) { context.startService(mIntentForService); } } diff --git a/src/eu/siacs/conversations/services/ImageProvider.java b/src/eu/siacs/conversations/services/ImageProvider.java index af8ab4b2c..ac78a4540 100644 --- a/src/eu/siacs/conversations/services/ImageProvider.java +++ b/src/eu/siacs/conversations/services/ImageProvider.java @@ -31,7 +31,7 @@ public class ImageProvider extends ContentProvider { if (uuids == null) { throw new FileNotFoundException(); } - String[] uuidsSplited = uuids.split("/",2); + String[] uuidsSplited = uuids.split("/", 2); if (uuidsSplited.length != 3) { throw new FileNotFoundException(); } diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java new file mode 100644 index 000000000..b004d1c58 --- /dev/null +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -0,0 +1,165 @@ +package eu.siacs.conversations.services; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.TaskStackBuilder; +import android.text.Html; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.ui.ConversationActivity; + +public class NotificationService { + + private XmppConnectionService mXmppConnectionService; + private NotificationManager mNotificationManager; + + private LinkedHashMap> notifications = new LinkedHashMap>(); + + public int NOTIFICATION_ID = 0x2342; + + public NotificationService(XmppConnectionService service) { + this.mXmppConnectionService = service; + this.mNotificationManager = (NotificationManager) service + .getSystemService(Context.NOTIFICATION_SERVICE); + } + + public synchronized void push(Message message) { + String conversationUuid = message.getConversationUuid(); + if (notifications.containsKey(conversationUuid)) { + notifications.get(conversationUuid).add(message); + } else { + ArrayList mList = new ArrayList(); + mList.add(message); + notifications.put(conversationUuid, mList); + } + updateNotification(true); + } + + public void clear() { + notifications.clear(); + updateNotification(false); + } + + public void clear(Conversation conversation) { + notifications.remove(conversation.getUuid()); + updateNotification(false); + } + + private void updateNotification(boolean notify) { + SharedPreferences preferences = mXmppConnectionService.getPreferences(); + + String ringtone = preferences.getString("notification_ringtone", null); + boolean vibrate = preferences.getBoolean("vibrate_on_notification", + true); + + if (notifications.size() == 0) { + mNotificationManager.cancel(NOTIFICATION_ID); + } else { + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( + mXmppConnectionService); + mBuilder.setSmallIcon(R.drawable.ic_notification); + if (notifications.size() == 1) { + ArrayList messages = notifications.values().iterator() + .next(); + if (messages.size() >= 1) { + Conversation conversation = messages.get(0) + .getConversation(); + mBuilder.setLargeIcon(conversation.getImage( + mXmppConnectionService, 64)); + mBuilder.setContentTitle(conversation.getName()); + StringBuilder text = new StringBuilder(); + for (int i = 0; i < messages.size(); ++i) { + text.append(messages.get(i).getReadableBody( + mXmppConnectionService)); + if (i != messages.size() - 1) { + text.append("\n"); + } + } + mBuilder.setStyle(new NotificationCompat.BigTextStyle() + .bigText(text.toString())); + mBuilder.setContentText(messages.get(0).getReadableBody( + mXmppConnectionService)); + mBuilder.setTicker(messages.get(messages.size() - 1) + .getReadableBody(mXmppConnectionService)); + mBuilder.setContentIntent(createContentIntent(conversation + .getUuid())); + } else { + mNotificationManager.cancel(NOTIFICATION_ID); + return; + } + } else { + NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); + style.setBigContentTitle(notifications.size() + + " " + + mXmppConnectionService + .getString(R.string.unread_conversations)); + StringBuilder names = new StringBuilder(); + for (ArrayList messages : notifications.values()) { + if (messages.size() > 0) { + String name = messages.get(0).getConversation() + .getName(); + style.addLine(Html.fromHtml("" + + name + + " " + + messages.get(0).getReadableBody( + mXmppConnectionService))); + names.append(name); + names.append(", "); + } + } + if (names.length() >= 2) { + names.delete(names.length() - 2, names.length()); + } + mBuilder.setContentTitle(notifications.size() + + " " + + mXmppConnectionService + .getString(R.string.unread_conversations)); + mBuilder.setContentText(names.toString()); + mBuilder.setStyle(style); + } + if (notify) { + if (vibrate) { + int dat = 70; + long[] pattern = { 0, 3 * dat, dat, dat }; + mBuilder.setVibrate(pattern); + } + mBuilder.setLights(0xffffffff, 2000, 4000); + if (ringtone != null) { + mBuilder.setSound(Uri.parse(ringtone)); + } + } + Notification notification = mBuilder.build(); + mNotificationManager.notify(NOTIFICATION_ID, notification); + } + } + + private PendingIntent createContentIntent(String conversationUuid) { + TaskStackBuilder stackBuilder = TaskStackBuilder + .create(mXmppConnectionService); + stackBuilder.addParentStack(ConversationActivity.class); + + Intent viewConversationIntent = new Intent(mXmppConnectionService, + ConversationActivity.class); + viewConversationIntent.setAction(Intent.ACTION_VIEW); + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, + conversationUuid); + viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); + + stackBuilder.addNextIntent(viewConversationIntent); + + PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, + PendingIntent.FLAG_UPDATE_CURRENT); + return resultPendingIntent; + } +} diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index badf1df52..2ca11286f 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -93,6 +93,8 @@ public class XmppConnectionService extends Service { private MemorizingTrustManager mMemorizingTrustManager; + private NotificationService mNotificationService; + private MessageParser mMessageParser = new MessageParser(this); private PresenceParser mPresenceParser = new PresenceParser(this); private IqParser mIqParser = new IqParser(this); @@ -401,6 +403,7 @@ public class XmppConnectionService extends Service { this.mRandom = new SecureRandom(); this.mMemorizingTrustManager = new MemorizingTrustManager( getApplicationContext()); + this.mNotificationService = new NotificationService(this); this.databaseBackend = DatabaseBackend .getInstance(getApplicationContext()); this.fileBackend = new FileBackend(getApplicationContext()); @@ -1268,7 +1271,7 @@ public class XmppConnectionService extends Service { } } } - notifyUi(conversation, false); + updateConversationUi(); } public boolean renewSymmetricKey(Conversation conversation) { @@ -1577,15 +1580,6 @@ public class XmppConnectionService extends Service { return getPreferences().getBoolean("indicate_received", false); } - public void notifyUi(Conversation conversation, boolean notify) { - if (mOnConversationUpdate != null) { - mOnConversationUpdate.onConversationUpdate(); - } else { - UIHelper.updateNotification(getApplicationContext(), - getConversations(), conversation, notify); - } - } - public void updateConversationUi() { if (mOnConversationUpdate != null) { mOnConversationUpdate.onConversationUpdate(); @@ -1624,6 +1618,7 @@ public class XmppConnectionService extends Service { public void markRead(Conversation conversation) { conversation.markRead(); + mNotificationService.clear(conversation); String id = conversation.popLatestMarkableMessageId(); if (confirmMessages() && id != null) { Account account = conversation.getAccount(); @@ -1758,4 +1753,8 @@ public class XmppConnectionService extends Service { } return contacts; } + + public void pushNotification(Message message) { + this.mNotificationService.push(message); + } } diff --git a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 76c12a474..04059d528 100644 --- a/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -201,7 +201,7 @@ public class ConferenceDetailsActivity extends XmppActivity { private void populateView() { mYourPhoto.setImageBitmap(conversation.getAccount().getImage(this, 48)); setTitle(conversation.getName()); - mFullJid.setText(conversation.getContactJid().split("/",2)[0]); + mFullJid.setText(conversation.getContactJid().split("/", 2)[0]); mYourNick.setText(conversation.getMucOptions().getActualNick()); mRoleAffiliaton = (TextView) findViewById(R.id.muc_role); if (conversation.getMucOptions().online()) { diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index b6b6aa722..3accafe84 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -167,8 +167,6 @@ public class ConversationActivity extends XmppActivity implements if (!getSelectedConversation().isRead()) { xmppConnectionService .markRead(getSelectedConversation()); - UIHelper.updateNotification(getApplicationContext(), - getConversationList(), null, false); listView.invalidateViews(); } } @@ -297,7 +295,8 @@ public class ConversationActivity extends XmppActivity implements int which) { conversation .setNextEncryption(Message.ENCRYPTION_NONE); - xmppConnectionService.databaseBackend.updateConversation(conversation); + xmppConnectionService.databaseBackend + .updateConversation(conversation); selectPresenceToAttachFile(attachmentChoice); } }); @@ -402,7 +401,7 @@ public class ConversationActivity extends XmppActivity implements }); builder.create().show(); } - + protected void attachFileDialog() { View menuAttachFile = findViewById(R.id.action_attach_file); if (menuAttachFile == null) { @@ -473,7 +472,8 @@ public class ConversationActivity extends XmppActivity implements conversation.setNextEncryption(Message.ENCRYPTION_NONE); break; } - xmppConnectionService.databaseBackend.updateConversation(conversation); + xmppConnectionService.databaseBackend + .updateConversation(conversation); fragment.updateChatMsgHint(); return true; } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index a8dee4f76..7916560d5 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -381,10 +381,12 @@ public class ConversationFragment extends Fragment { activity.getSlidingPaneLayout().closePane(); activity.getActionBar().setDisplayHomeAsUpEnabled(true); activity.getActionBar().setHomeButtonEnabled(true); - if (conversation.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) { + if (conversation.getMode() == Conversation.MODE_SINGLE + || activity.useSubjectToIdentifyConference()) { activity.getActionBar().setTitle(conversation.getName()); } else { - activity.getActionBar().setTitle(conversation.getContactJid().split("/")[0]); + activity.getActionBar().setTitle( + conversation.getContactJid().split("/")[0]); } activity.invalidateOptionsMenu(); } @@ -502,8 +504,6 @@ public class ConversationFragment extends Fragment { updateChatMsgHint(); if (!activity.shouldPaneBeOpen()) { activity.xmppConnectionService.markRead(conversation); - UIHelper.updateNotification(getActivity(), - activity.getConversationList(), null, false); activity.updateConversationList(); } this.updateSendButton(); @@ -668,7 +668,8 @@ public class ConversationFragment extends Fragment { int which) { conversation .setNextEncryption(Message.ENCRYPTION_NONE); - xmppService.databaseBackend.updateConversation(conversation); + xmppService.databaseBackend + .updateConversation(conversation); message.setEncryption(Message.ENCRYPTION_NONE); xmppService.sendMessage(message); messageSent(); @@ -697,7 +698,8 @@ public class ConversationFragment extends Fragment { conversation .setNextEncryption(Message.ENCRYPTION_NONE); message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.databaseBackend.updateConversation(conversation); + xmppService.databaseBackend + .updateConversation(conversation); xmppService.sendMessage(message); messageSent(); } diff --git a/src/eu/siacs/conversations/ui/SettingsActivity.java b/src/eu/siacs/conversations/ui/SettingsActivity.java index fc361fb82..fc6308fce 100644 --- a/src/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/eu/siacs/conversations/ui/SettingsActivity.java @@ -21,7 +21,7 @@ public class SettingsActivity extends XmppActivity implements super.onCreate(savedInstanceState); mSettingsFragment = new SettingsFragment(); getFragmentManager().beginTransaction() - .replace(android.R.id.content,mSettingsFragment).commit(); + .replace(android.R.id.content, mSettingsFragment).commit(); } @Override @@ -34,12 +34,16 @@ public class SettingsActivity extends XmppActivity implements super.onStart(); PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(this); - ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource"); - if (resources!=null) { - ArrayList entries = new ArrayList(Arrays.asList(resources.getEntries())); - entries.add(0,Build.MODEL); - resources.setEntries(entries.toArray(new CharSequence[entries.size()])); - resources.setEntryValues(entries.toArray(new CharSequence[entries.size()])); + ListPreference resources = (ListPreference) mSettingsFragment + .findPreference("resource"); + if (resources != null) { + ArrayList entries = new ArrayList( + Arrays.asList(resources.getEntries())); + entries.add(0, Build.MODEL); + resources.setEntries(entries.toArray(new CharSequence[entries + .size()])); + resources.setEntryValues(entries.toArray(new CharSequence[entries + .size()])); } } diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index e4b49d082..1a5fba959 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -325,8 +325,8 @@ public class StartConversationActivity extends XmppActivity { final AutoCompleteTextView jid = (AutoCompleteTextView) dialogView .findViewById(R.id.jid); jid.setAdapter(new KnownHostsAdapter(this, - android.R.layout.simple_list_item_1, mKnownHosts)); - if (prefilledJid!=null) { + android.R.layout.simple_list_item_1, mKnownHosts)); + if (prefilledJid != null) { jid.append(prefilledJid); } populateAccountSpinner(spinner); @@ -536,7 +536,8 @@ public class StartConversationActivity extends XmppActivity { setIntent(null); return false; } - } else if (getIntent() != null && Intent.ACTION_VIEW.equals(getIntent().getAction())) { + } else if (getIntent() != null + && Intent.ACTION_VIEW.equals(getIntent().getAction())) { Uri uri = getIntent().getData(); String jid = uri.getSchemeSpecificPart().split("\\?")[0]; return handleJid(jid); @@ -545,8 +546,7 @@ public class StartConversationActivity extends XmppActivity { } private boolean handleJid(String jid) { - List contacts = xmppConnectionService - .findContacts(jid); + List contacts = xmppConnectionService.findContacts(jid); if (contacts.size() == 0) { showCreateContactDialog(jid); return false; diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index b54bc1524..518f7b0be 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -63,7 +63,7 @@ public abstract class XmppActivity extends Activity { protected int mColorOrange; protected int mColorGreen; protected int mPrimaryColor; - + protected boolean mUseSubject = true; private DisplayMetrics metrics; @@ -217,7 +217,7 @@ public abstract class XmppActivity extends Activity { return PreferenceManager .getDefaultSharedPreferences(getApplicationContext()); } - + public boolean useSubjectToIdentifyConference() { return mUseSubject; } @@ -256,7 +256,7 @@ public abstract class XmppActivity extends Activity { intent.putExtra("contact", contact.getJid()); startActivity(intent); } - + public void switchToAccount(Account account) { Intent intent = new Intent(this, EditAccountActivity.class); intent.putExtra("jid", account.getJid()); @@ -294,7 +294,8 @@ public abstract class XmppActivity extends Activity { if (conversation != null) { conversation .setNextEncryption(Message.ENCRYPTION_PGP); - xmppConnectionService.databaseBackend.updateConversation(conversation); + xmppConnectionService.databaseBackend + .updateConversation(conversation); } } diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index e40723f41..7b470faa4 100644 --- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -52,7 +52,8 @@ public class ConversationAdapter extends ArrayAdapter { } TextView convName = (TextView) view .findViewById(R.id.conversation_name); - if (conv.getMode() == Conversation.MODE_SINGLE || activity.useSubjectToIdentifyConference()) { + if (conv.getMode() == Conversation.MODE_SINGLE + || activity.useSubjectToIdentifyConference()) { convName.setText(conv.getName()); } else { convName.setText(conv.getContactJid().split("/")[0]); diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index d18263155..ed11a6359 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -341,7 +341,7 @@ public class UIHelper { Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } - public static void updateNotification(Context context, + private static void updateNotification(Context context, List conversations, Conversation currentCon, boolean notify) { NotificationManager mNotificationManager = (NotificationManager) context diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 8694e68c4..b055e35a3 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -657,7 +657,7 @@ public class XmppConnection implements Runnable { if (bind != null) { Element jid = bind.findChild("jid"); if (jid != null && jid.getContent() != null) { - account.setResource(jid.getContent().split("/",2)[1]); + account.setResource(jid.getContent().split("/", 2)[1]); if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) { smVersion = 3; EnablePacket enable = new EnablePacket(smVersion); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 4eac99e68..3a3d3582c 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -88,8 +88,8 @@ public class JingleConnection implements Downloadable { sendSuccess(); if (acceptedAutomatically) { message.markUnread(); - JingleConnection.this.mXmppConnectionService.notifyUi( - message.getConversation(), true); + JingleConnection.this.mXmppConnectionService + .pushNotification(message); } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; @@ -256,12 +256,12 @@ public class JingleConnection implements Downloadable { this.status = STATUS_INITIATED; Conversation conversation = this.mXmppConnectionService .findOrCreateConversation(account, - packet.getFrom().split("/",2)[0], false); + packet.getFrom().split("/", 2)[0], false); this.message = new Message(conversation, "", Message.ENCRYPTION_NONE); this.message.setType(Message.TYPE_IMAGE); this.message.setStatus(Message.STATUS_RECEIVED_OFFER); this.message.setDownloadable(this); - String[] fromParts = packet.getFrom().split("/",2); + String[] fromParts = packet.getFrom().split("/", 2); this.message.setPresence(fromParts[1]); this.account = account; this.initiator = packet.getFrom(); @@ -319,8 +319,7 @@ public class JingleConnection implements Downloadable { + " allowed size:" + this.mJingleConnectionManager .getAutoAcceptFileSize()); - this.mXmppConnectionService - .notifyUi(conversation, true); + this.mXmppConnectionService.pushNotification(message); } this.file = this.mXmppConnectionService.getFileBackend() .getJingleFile(message, false); From 87010e6094cc35ece98d3beadbbfbc59ea0a25b3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Sep 2014 16:33:25 +0200 Subject: [PATCH 14/57] more improvments for new notification service --- res/layout/message_received.xml | 10 +- res/layout/message_sent.xml | 20 +- res/values-eu/arrays.xml | 7 +- res/values-eu/strings.xml | 4 +- res/xml/preferences.xml | 8 +- .../conversations/parser/MessageParser.java | 18 +- .../services/NotificationService.java | 21 +++ .../siacs/conversations/utils/UIHelper.java | 176 ------------------ 8 files changed, 53 insertions(+), 211 deletions(-) diff --git a/res/layout/message_received.xml b/res/layout/message_received.xml index 28c04a707..730d00d53 100644 --- a/res/layout/message_received.xml +++ b/res/layout/message_received.xml @@ -54,7 +54,7 @@ android:text="@string/download_image" android:visibility="gone" /> - - - + android:alpha="0.54" + android:gravity="center_vertical" + android:src="@drawable/ic_secure_indicator" /> - - + android:alpha="0.54" + android:gravity="center_vertical" + android:src="@drawable/ic_secure_indicator" /> + - - + android:alpha="0.54" + android:gravity="center_vertical" + android:src="@drawable/ic_received_indicator" /> @@ -99,4 +97,4 @@ android:scaleType="fitXY" android:src="@drawable/ic_profile" /> - + \ No newline at end of file diff --git a/res/values-eu/arrays.xml b/res/values-eu/arrays.xml index cb1c20fd7..a34d3c6a9 100644 --- a/res/values-eu/arrays.xml +++ b/res/values-eu/arrays.xml @@ -26,8 +26,9 @@ 2 ordu 8 ordu abisatu arte - - + + + 1800 3600 7200 @@ -35,4 +36,4 @@ -1 - + \ No newline at end of file diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 727372849..4d3522fd4 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -256,5 +256,5 @@ Letra tamaina handiagoa erabili aplikazio osoan zehar Bidaltze botoiak egoera adierazten du Bidaltze botoia koloreztatu kontaktu baten egoera adierazteko - - + + \ No newline at end of file diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 024335f15..5af789c0d 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -52,15 +52,9 @@ - (Config.CARBON_GRACE_PERIOD * 1000); - } + boolean notify = mXmppConnectionService.getPreferences().getBoolean( + "show_notification", true); + notify = notify + && (SystemClock.elapsedRealtime() - lastCarbonMessageReceived) > (Config.CARBON_GRACE_PERIOD * 1000); + boolean alwaysNotifyInConference = notify + && mXmppConnectionService.getPreferences().getBoolean( + "always_notify_in_conference", false); this.parseNick(packet, account); @@ -427,8 +430,11 @@ public class MessageParser extends AbstractParser implements if (message != null) { if (message.getStatus() == Message.STATUS_RECEIVED) { message.markUnread(); + notify = alwaysNotifyInConference + || NotificationService + .wasHighlightedOrPrivate(message); } else { - message.getConversation().markRead(); + mXmppConnectionService.markRead(message.getConversation()); lastCarbonMessageReceived = SystemClock.elapsedRealtime(); notify = false; } diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index b004d1c58..656e16f36 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -2,6 +2,9 @@ package eu.siacs.conversations.services; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import android.app.Notification; import android.app.NotificationManager; @@ -162,4 +165,22 @@ public class NotificationService { PendingIntent.FLAG_UPDATE_CURRENT); return resultPendingIntent; } + + public static boolean wasHighlightedOrPrivate(Message message) { + String nick = message.getConversation().getMucOptions().getActualNick(); + Pattern highlight = generateNickHighlightPattern(nick); + Matcher m = highlight.matcher(message.getBody()); + return (m.find() || message.getType() == Message.TYPE_PRIVATE); + } + + private static Pattern generateNickHighlightPattern(String nick) { + // We expect a word boundary, i.e. space or start of string, followed by + // the + // nick (matched in case-insensitive manner), followed by optional + // punctuation (for example "bob: i disagree" or "how are you alice?"), + // followed by another word boundary. + return Pattern.compile("\\b" + nick + "\\p{Punct}?\\b", + Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); + } + } diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index ed11a6359..671e66d5b 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -7,13 +7,11 @@ import java.util.Date; import java.util.List; import java.util.Locale; import java.util.regex.Pattern; -import java.util.regex.Matcher; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions.User; import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.ui.ManageAccountActivity; @@ -27,7 +25,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -35,13 +32,11 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.net.Uri; -import android.preference.PreferenceManager; import android.provider.ContactsContract.Contacts; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.format.DateFormat; import android.text.format.DateUtils; -import android.text.Html; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; @@ -331,177 +326,6 @@ public class UIHelper { mNotificationManager.notify(1111, notification); } - private static Pattern generateNickHighlightPattern(String nick) { - // We expect a word boundary, i.e. space or start of string, followed by - // the - // nick (matched in case-insensitive manner), followed by optional - // punctuation (for example "bob: i disagree" or "how are you alice?"), - // followed by another word boundary. - return Pattern.compile("\\b" + nick + "\\p{Punct}?\\b", - Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); - } - - private static void updateNotification(Context context, - List conversations, Conversation currentCon, - boolean notify) { - NotificationManager mNotificationManager = (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - - SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(context); - boolean showNofifications = preferences.getBoolean("show_notification", - true); - boolean vibrate = preferences.getBoolean("vibrate_on_notification", - true); - boolean alwaysNotify = preferences.getBoolean( - "notify_in_conversation_when_highlighted", false); - - if (!showNofifications) { - mNotificationManager.cancel(2342); - return; - } - - String targetUuid = ""; - - if ((currentCon != null) - && (currentCon.getMode() == Conversation.MODE_MULTI) - && (!alwaysNotify) && notify) { - String nick = currentCon.getMucOptions().getActualNick(); - Pattern highlight = generateNickHighlightPattern(nick); - Matcher m = highlight.matcher(currentCon.getLatestMessage() - .getBody()); - notify = m.find() - || (currentCon.getLatestMessage().getType() == Message.TYPE_PRIVATE); - } - - List unread = new ArrayList(); - for (Conversation conversation : conversations) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - if ((!conversation.isRead()) - && ((wasHighlightedOrPrivate(conversation) || (alwaysNotify)))) { - unread.add(conversation); - } - } else { - if (!conversation.isRead()) { - unread.add(conversation); - } - } - } - String ringtone = preferences.getString("notification_ringtone", null); - - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( - context); - if (unread.size() == 0) { - mNotificationManager.cancel(2342); - return; - } else if (unread.size() == 1) { - Conversation conversation = unread.get(0); - targetUuid = conversation.getUuid(); - mBuilder.setLargeIcon(conversation.getImage(context, 64)); - mBuilder.setContentTitle(conversation.getName()); - if (notify) { - mBuilder.setTicker(conversation.getLatestMessage() - .getReadableBody(context)); - } - StringBuilder bigText = new StringBuilder(); - List messages = conversation.getMessages(); - String firstLine = ""; - for (int i = messages.size() - 1; i >= 0; --i) { - if (!messages.get(i).isRead()) { - if (i == messages.size() - 1) { - firstLine = messages.get(i).getReadableBody(context); - bigText.append(firstLine); - } else { - firstLine = messages.get(i).getReadableBody(context); - bigText.insert(0, firstLine + "\n"); - } - } else { - break; - } - } - mBuilder.setContentText(firstLine); - mBuilder.setStyle(new NotificationCompat.BigTextStyle() - .bigText(bigText.toString())); - } else { - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(unread.size() + " " - + context.getString(R.string.unread_conversations)); - StringBuilder names = new StringBuilder(); - for (int i = 0; i < unread.size(); ++i) { - targetUuid = unread.get(i).getUuid(); - if (i < unread.size() - 1) { - names.append(unread.get(i).getName() + ", "); - } else { - names.append(unread.get(i).getName()); - } - style.addLine(Html.fromHtml("" - + unread.get(i).getName() - + " " - + unread.get(i).getLatestMessage() - .getReadableBody(context))); - } - mBuilder.setContentTitle(unread.size() + " " - + context.getString(R.string.unread_conversations)); - mBuilder.setContentText(names.toString()); - mBuilder.setStyle(style); - } - if ((currentCon != null) && (notify)) { - targetUuid = currentCon.getUuid(); - } - if (unread.size() != 0) { - mBuilder.setSmallIcon(R.drawable.ic_notification); - if (notify) { - if (vibrate) { - int dat = 70; - long[] pattern = { 0, 3 * dat, dat, dat }; - mBuilder.setVibrate(pattern); - } - mBuilder.setLights(0xffffffff, 2000, 4000); - if (ringtone != null) { - mBuilder.setSound(Uri.parse(ringtone)); - } - } - - TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); - stackBuilder.addParentStack(ConversationActivity.class); - - Intent viewConversationIntent = new Intent(context, - ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - targetUuid); - viewConversationIntent - .setType(ConversationActivity.VIEW_CONVERSATION); - - stackBuilder.addNextIntent(viewConversationIntent); - - PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( - 0, PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.setContentIntent(resultPendingIntent); - Notification notification = mBuilder.build(); - mNotificationManager.notify(2342, notification); - } - } - - private static boolean wasHighlightedOrPrivate(Conversation conversation) { - List messages = conversation.getMessages(); - String nick = conversation.getMucOptions().getActualNick(); - Pattern highlight = generateNickHighlightPattern(nick); - for (int i = messages.size() - 1; i >= 0; --i) { - if (messages.get(i).isRead()) { - break; - } else { - Matcher m = highlight.matcher(messages.get(i).getBody()); - if (m.find() - || messages.get(i).getType() == Message.TYPE_PRIVATE) { - return true; - } - } - } - return false; - } - public static void prepareContactBadge(final Activity activity, QuickContactBadge badge, final Contact contact, Context context) { if (contact.getSystemAccount() != null) { From c8160b010d70aea41d4b6e00ed58563d6c195b1d Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 29 Sep 2014 17:59:53 +0200 Subject: [PATCH 15/57] fixed muc invite with . --- src/eu/siacs/conversations/parser/MessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 9e2ccd921..27627e525 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -399,7 +399,9 @@ public class MessageParser extends AbstractParser implements if (message != null) { message.markUnread(); } - } else if (packet.hasChild("body")) { + } else if (packet.hasChild("body") + && !(packet.hasChild("x", + "http://jabber.org/protocol/muc#user"))) { message = this.parseChat(packet, account); if (message != null) { message.markUnread(); From 511b7a53f41f8254449e6c2c6eff795f728e7a33 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 29 Sep 2014 18:28:13 +0200 Subject: [PATCH 16/57] notifiy only when necessary --- res/xml/preferences.xml | 16 ++++---- .../conversations/parser/MessageParser.java | 4 +- .../services/NotificationService.java | 30 ++++++++++++--- .../services/XmppConnectionService.java | 8 ++-- .../ui/ConversationActivity.java | 38 ++++++++++++------- .../ui/ConversationFragment.java | 11 +----- .../xmpp/jingle/JingleConnection.java | 5 ++- 7 files changed, 68 insertions(+), 44 deletions(-) diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 5af789c0d..eccc8baea 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -89,13 +89,13 @@ android:summary="@string/pref_dont_save_encrypted_summary" android:title="@string/pref_dont_save_encrypted" /> - - - + + + - + \ No newline at end of file diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index d1964b8c9..af0c96e9a 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -417,7 +417,7 @@ public class MessageParser extends AbstractParser implements lastCarbonMessageReceived = SystemClock .elapsedRealtime(); notify = false; - message.getConversation().markRead(); + mXmppConnectionService.markRead(message.getConversation()); } else { message.markUnread(); } @@ -474,7 +474,7 @@ public class MessageParser extends AbstractParser implements } notify = notify && !conversation.isMuted(); if (notify) { - mXmppConnectionService.pushNotification(message); + mXmppConnectionService.getNotificationService().push(message); } mXmppConnectionService.updateConversationUi(); } diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 656e16f36..831ce51ff 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -2,7 +2,6 @@ package eu.siacs.conversations.services; import java.util.ArrayList; import java.util.LinkedHashMap; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -16,7 +15,9 @@ import android.net.Uri; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.Html; +import android.util.Log; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -30,6 +31,8 @@ public class NotificationService { private LinkedHashMap> notifications = new LinkedHashMap>(); public int NOTIFICATION_ID = 0x2342; + private Conversation mOpenConversation; + private boolean mIsInForeground; public NotificationService(XmppConnectionService service) { this.mXmppConnectionService = service; @@ -38,6 +41,13 @@ public class NotificationService { } public synchronized void push(Message message) { + if (this.mIsInForeground + && this.mOpenConversation == message.getConversation()) { + Log.d(Config.LOGTAG,"ignoring notification because foreground and conv matches"); + return; // simply ignore + } else { + Log.d(Config.LOGTAG,"pushed new notification"); + } String conversationUuid = message.getConversationUuid(); if (notifications.containsKey(conversationUuid)) { notifications.get(conversationUuid).add(message); @@ -46,7 +56,7 @@ public class NotificationService { mList.add(message); notifications.put(conversationUuid, mList); } - updateNotification(true); + updateNotification(!(this.mIsInForeground && this.mOpenConversation == null)); } public void clear() { @@ -93,8 +103,10 @@ public class NotificationService { .bigText(text.toString())); mBuilder.setContentText(messages.get(0).getReadableBody( mXmppConnectionService)); - mBuilder.setTicker(messages.get(messages.size() - 1) - .getReadableBody(mXmppConnectionService)); + if (notify) { + mBuilder.setTicker(messages.get(messages.size() - 1) + .getReadableBody(mXmppConnectionService)); + } mBuilder.setContentIntent(createContentIntent(conversation .getUuid())); } else { @@ -137,11 +149,11 @@ public class NotificationService { long[] pattern = { 0, 3 * dat, dat, dat }; mBuilder.setVibrate(pattern); } - mBuilder.setLights(0xffffffff, 2000, 4000); if (ringtone != null) { mBuilder.setSound(Uri.parse(ringtone)); } } + mBuilder.setLights(0xffffffff, 2000, 4000); Notification notification = mBuilder.build(); mNotificationManager.notify(NOTIFICATION_ID, notification); } @@ -183,4 +195,12 @@ public class NotificationService { Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } + public void setOpenConversation(Conversation conversation) { + this.mOpenConversation = conversation; + } + + public void setIsInForeground(boolean foreground) { + this.mIsInForeground = foreground; + } + } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 2ca11286f..b83be7fbd 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -971,6 +971,7 @@ public class XmppConnectionService extends Service { switchToForeground(); } this.mOnConversationUpdate = listener; + this.mNotificationService.setIsInForeground(true); this.convChangedListenerCount++; } @@ -978,6 +979,7 @@ public class XmppConnectionService extends Service { this.convChangedListenerCount--; if (this.convChangedListenerCount == 0) { this.mOnConversationUpdate = null; + this.mNotificationService.setIsInForeground(false); if (checkListeners()) { switchToBackground(); } @@ -1753,8 +1755,8 @@ public class XmppConnectionService extends Service { } return contacts; } - - public void pushNotification(Message message) { - this.mNotificationService.push(message); + + public NotificationService getNotificationService() { + return this.mNotificationService; } } diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 3accafe84..03cf753d3 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -12,7 +12,6 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.ConversationAdapter; import eu.siacs.conversations.utils.ExceptionHelper; -import eu.siacs.conversations.utils.UIHelper; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; @@ -144,6 +143,9 @@ public class ConversationActivity extends XmppActivity implements } invalidateOptionsMenu(); hideKeyboard(); + if (xmppConnectionServiceBound) { + xmppConnectionService.getNotificationService().setOpenConversation(null); + } } @Override @@ -151,19 +153,7 @@ public class ConversationActivity extends XmppActivity implements paneShouldBeOpen = false; if ((conversationList.size() > 0) && (getSelectedConversation() != null)) { - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(true); - ab.setHomeButtonEnabled(true); - if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE - || activity.useSubjectToIdentifyConference()) { - ab.setTitle(getSelectedConversation().getName()); - } else { - ab.setTitle(getSelectedConversation() - .getContactJid().split("/")[0]); - } - } - invalidateOptionsMenu(); + openConversation(getSelectedConversation()); if (!getSelectedConversation().isRead()) { xmppConnectionService .markRead(getSelectedConversation()); @@ -179,6 +169,25 @@ public class ConversationActivity extends XmppActivity implements } }); } + + public void openConversation(Conversation conversation) { + ActionBar ab = getActionBar(); + if (ab != null) { + ab.setDisplayHomeAsUpEnabled(true); + ab.setHomeButtonEnabled(true); + if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE + || activity.useSubjectToIdentifyConference()) { + ab.setTitle(getSelectedConversation().getName()); + } else { + ab.setTitle(getSelectedConversation() + .getContactJid().split("/")[0]); + } + } + invalidateOptionsMenu(); + if (xmppConnectionServiceBound) { + xmppConnectionService.getNotificationService().setOpenConversation(conversation); + } + } @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -603,6 +612,7 @@ public class ConversationActivity extends XmppActivity implements xmppConnectionService.removeOnConversationListChangedListener(); xmppConnectionService.removeOnAccountListChangedListener(); xmppConnectionService.removeOnRosterUpdateListener(); + xmppConnectionService.getNotificationService().setOpenConversation(null); } super.onStop(); } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 7916560d5..064b00be4 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -379,16 +379,7 @@ public class ConversationFragment extends Fragment { if (activity.getSlidingPaneLayout().isSlideable()) { if (!activity.shouldPaneBeOpen()) { activity.getSlidingPaneLayout().closePane(); - activity.getActionBar().setDisplayHomeAsUpEnabled(true); - activity.getActionBar().setHomeButtonEnabled(true); - if (conversation.getMode() == Conversation.MODE_SINGLE - || activity.useSubjectToIdentifyConference()) { - activity.getActionBar().setTitle(conversation.getName()); - } else { - activity.getActionBar().setTitle( - conversation.getContactJid().split("/")[0]); - } - activity.invalidateOptionsMenu(); + activity.openConversation(conversation); } } if (this.conversation.getMode() == Conversation.MODE_MULTI) { diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 3a3d3582c..92fdbe0b6 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -89,7 +89,7 @@ public class JingleConnection implements Downloadable { if (acceptedAutomatically) { message.markUnread(); JingleConnection.this.mXmppConnectionService - .pushNotification(message); + .getNotificationService().push(message); } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; @@ -319,7 +319,8 @@ public class JingleConnection implements Downloadable { + " allowed size:" + this.mJingleConnectionManager .getAutoAcceptFileSize()); - this.mXmppConnectionService.pushNotification(message); + this.mXmppConnectionService.getNotificationService() + .push(message); } this.file = this.mXmppConnectionService.getFileBackend() .getJingleFile(message, false); From fd6f5b0e84763e98be6299d63d48786c602211a3 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 30 Sep 2014 16:22:02 +0200 Subject: [PATCH 17/57] calculate sample size for thumbnails as well --- .../conversations/persistance/FileBackend.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java index 2b2aa86e3..d86c0ee13 100644 --- a/src/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/eu/siacs/conversations/persistance/FileBackend.java @@ -250,7 +250,10 @@ public class FileBackend { if (!file.exists()) { file = getJingleFileLegacy(message); } - Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath()); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = calcSampleSize(file, size); + Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(), + options); if (fullsize == null) { throw new FileNotFoundException(); } @@ -414,6 +417,17 @@ public class FileBackend { options.inJustDecodeBounds = true; BitmapFactory.decodeStream(context.getContentResolver() .openInputStream(image), null, options); + return calcSampleSize(options, size); + } + + private int calcSampleSize(File image, int size) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(image.getAbsolutePath(), options); + return calcSampleSize(options, size); + } + + private int calcSampleSize(BitmapFactory.Options options, int size) { int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; @@ -428,7 +442,6 @@ public class FileBackend { } } return inSampleSize; - } public Uri getJingleFileUri(Message message) { From 4b09f0e9d3296b4b71d3b31c9102610cc8037d20 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 2 Oct 2014 17:36:02 +0200 Subject: [PATCH 18/57] properly dismiss notifications --- .../services/NotificationService.java | 16 ++++++++++++++-- .../services/XmppConnectionService.java | 19 +++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 831ce51ff..1bc494b74 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -120,10 +120,11 @@ public class NotificationService { + mXmppConnectionService .getString(R.string.unread_conversations)); StringBuilder names = new StringBuilder(); + Conversation conversation = null; for (ArrayList messages : notifications.values()) { if (messages.size() > 0) { - String name = messages.get(0).getConversation() - .getName(); + conversation = messages.get(0).getConversation(); + String name = conversation.getName(); style.addLine(Html.fromHtml("" + name + " " @@ -142,6 +143,10 @@ public class NotificationService { .getString(R.string.unread_conversations)); mBuilder.setContentText(names.toString()); mBuilder.setStyle(style); + if (conversation!=null) { + mBuilder.setContentIntent(createContentIntent(conversation + .getUuid())); + } } if (notify) { if (vibrate) { @@ -153,6 +158,7 @@ public class NotificationService { mBuilder.setSound(Uri.parse(ringtone)); } } + mBuilder.setDeleteIntent(createDeleteIntent()); mBuilder.setLights(0xffffffff, 2000, 4000); Notification notification = mBuilder.build(); mNotificationManager.notify(NOTIFICATION_ID, notification); @@ -177,6 +183,12 @@ public class NotificationService { PendingIntent.FLAG_UPDATE_CURRENT); return resultPendingIntent; } + + private PendingIntent createDeleteIntent() { + Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); + intent.setAction("clear_notification"); + return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); + } public static boolean wasHighlightedOrPrivate(Message message) { String nick = message.getConversation().getMucOptions().getActualNick(); diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index b83be7fbd..0676c6030 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -90,6 +90,7 @@ public class XmppConnectionService extends Service { public long startDate; private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; + public static String ACTION_CLEAR_NOTIFICATION = "clear_notification"; private MemorizingTrustManager mMemorizingTrustManager; @@ -318,14 +319,16 @@ public class XmppConnectionService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - if ((intent != null) - && (ACTION_MERGE_PHONE_CONTACTS.equals(intent.getAction()))) { - mergePhoneContactsWithRoster(); - return START_STICKY; - } else if ((intent != null) - && (Intent.ACTION_SHUTDOWN.equals(intent.getAction()))) { - logoutAndSave(); - return START_NOT_STICKY; + if (intent != null && intent.getAction() != null) { + if (intent.getAction().equals(ACTION_MERGE_PHONE_CONTACTS)) { + mergePhoneContactsWithRoster(); + return START_STICKY; + } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { + logoutAndSave(); + return START_NOT_STICKY; + } else if (intent.getAction().equals(ACTION_CLEAR_NOTIFICATION)) { + mNotificationService.clear(); + } } this.wakeLock.acquire(); ConnectivityManager cm = (ConnectivityManager) getApplicationContext() From f8be57d43f83925d7f298ee1d34ef8cee32acec3 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 2 Oct 2014 18:31:19 +0200 Subject: [PATCH 19/57] show displayed by contact on all devices --- .../services/NotificationService.java | 14 +++++--------- .../services/XmppConnectionService.java | 6 ++++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 1bc494b74..012bac302 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -15,9 +15,7 @@ import android.net.Uri; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.Html; -import android.util.Log; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -43,10 +41,7 @@ public class NotificationService { public synchronized void push(Message message) { if (this.mIsInForeground && this.mOpenConversation == message.getConversation()) { - Log.d(Config.LOGTAG,"ignoring notification because foreground and conv matches"); return; // simply ignore - } else { - Log.d(Config.LOGTAG,"pushed new notification"); } String conversationUuid = message.getConversationUuid(); if (notifications.containsKey(conversationUuid)) { @@ -143,9 +138,9 @@ public class NotificationService { .getString(R.string.unread_conversations)); mBuilder.setContentText(names.toString()); mBuilder.setStyle(style); - if (conversation!=null) { + if (conversation != null) { mBuilder.setContentIntent(createContentIntent(conversation - .getUuid())); + .getUuid())); } } if (notify) { @@ -183,9 +178,10 @@ public class NotificationService { PendingIntent.FLAG_UPDATE_CURRENT); return resultPendingIntent; } - + private PendingIntent createDeleteIntent() { - Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); + Intent intent = new Intent(mXmppConnectionService, + XmppConnectionService.class); intent.setAction("clear_notification"); return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 0676c6030..ffef19ed1 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1545,7 +1545,9 @@ public class XmppConnectionService extends Service { public boolean markMessage(Conversation conversation, String uuid, int status) { for (Message message : conversation.getMessages()) { - if (message.getUuid().equals(uuid)) { + if (message.getUuid().equals(uuid) + || (message.getStatus() >= Message.STATUS_SEND && uuid + .equals(message.getRemoteMsgId()))) { markMessage(message, status); return true; } @@ -1758,7 +1760,7 @@ public class XmppConnectionService extends Service { } return contacts; } - + public NotificationService getNotificationService() { return this.mNotificationService; } From cc76e15b95af16a2030b02b9a5035126d3ba18da Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 2 Oct 2014 18:54:21 +0200 Subject: [PATCH 20/57] avoided unecessary message searchs --- .../services/XmppConnectionService.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index ffef19ed1..ea2b59038 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1533,26 +1533,34 @@ public class XmppConnectionService extends Service { public boolean markMessage(Account account, String recipient, String uuid, int status) { - for (Conversation conversation : getConversations()) { - if (conversation.getContactJid().equals(recipient) - && conversation.getAccount().equals(account)) { - return markMessage(conversation, uuid, status); + if (uuid == null) { + return false; + } else { + for (Conversation conversation : getConversations()) { + if (conversation.getContactJid().equals(recipient) + && conversation.getAccount().equals(account)) { + return markMessage(conversation, uuid, status); + } } + return false; } - return false; } public boolean markMessage(Conversation conversation, String uuid, int status) { - for (Message message : conversation.getMessages()) { - if (message.getUuid().equals(uuid) - || (message.getStatus() >= Message.STATUS_SEND && uuid - .equals(message.getRemoteMsgId()))) { - markMessage(message, status); - return true; + if (uuid == null) { + return false; + } else { + for (Message message : conversation.getMessages()) { + if (uuid.equals(message.getUuid()) + || (message.getStatus() >= Message.STATUS_SEND && uuid + .equals(message.getRemoteMsgId()))) { + markMessage(message, status); + return true; + } } + return false; } - return false; } public void markMessage(Message message, int status) { From f671938e842ece605f600860107ec9d2b8bfd019 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 2 Oct 2014 21:07:11 +0200 Subject: [PATCH 21/57] mark conversation as read when displayed marker from another client is received --- .../conversations/parser/MessageParser.java | 23 ++++++++++++++++--- .../services/XmppConnectionService.java | 7 ++++-- .../ui/ConversationActivity.java | 2 +- .../ui/ConversationFragment.java | 2 +- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index c8718edb0..e09dd0c5b 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.parser; import android.os.SystemClock; +import android.util.Log; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; import eu.siacs.conversations.Config; @@ -202,10 +203,24 @@ public class MessageParser extends AbstractParser implements return null; } Element message = forwarded.findChild("message"); - if ((message == null) || (!message.hasChild("body"))) { + if (message == null) { + return null; + } + if (!message.hasChild("body")) { if (status == Message.STATUS_RECEIVED && message.getAttribute("from") != null) { parseNonMessage(message, account); + } else if (status == Message.STATUS_SEND + && message.hasChild("displayed", "urn:xmpp:chat-markers:0")) { + String to = message.getAttribute("to"); + if (to != null) { + Conversation conversation = mXmppConnectionService.find( + mXmppConnectionService.getConversations(), account, + to.split("/")[0]); + if (conversation != null) { + mXmppConnectionService.markRead(conversation, false); + } + } } return null; } @@ -419,7 +434,8 @@ public class MessageParser extends AbstractParser implements lastCarbonMessageReceived = SystemClock .elapsedRealtime(); notify = false; - mXmppConnectionService.markRead(message.getConversation()); + mXmppConnectionService.markRead( + message.getConversation(), false); } else { message.markUnread(); } @@ -436,7 +452,8 @@ public class MessageParser extends AbstractParser implements || NotificationService .wasHighlightedOrPrivate(message); } else { - mXmppConnectionService.markRead(message.getConversation()); + mXmppConnectionService.markRead(message.getConversation(), + false); lastCarbonMessageReceived = SystemClock.elapsedRealtime(); notify = false; } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index ea2b59038..557a625b0 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1631,16 +1631,19 @@ public class XmppConnectionService extends Service { return null; } - public void markRead(Conversation conversation) { + public void markRead(Conversation conversation, boolean calledByUi) { conversation.markRead(); mNotificationService.clear(conversation); String id = conversation.popLatestMarkableMessageId(); - if (confirmMessages() && id != null) { + if (confirmMessages() && id != null && calledByUi) { Account account = conversation.getAccount(); String to = conversation.getContactJid(); this.sendMessagePacket(conversation.getAccount(), mMessageGenerator.confirm(account, to, id)); } + if (!calledByUi) { + updateConversationUi(); + } } public void failWaitingOtrMessages(Conversation conversation) { diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 03cf753d3..0c67beff9 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -156,7 +156,7 @@ public class ConversationActivity extends XmppActivity implements openConversation(getSelectedConversation()); if (!getSelectedConversation().isRead()) { xmppConnectionService - .markRead(getSelectedConversation()); + .markRead(getSelectedConversation(),true); listView.invalidateViews(); } } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 064b00be4..34c68e00b 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -494,7 +494,7 @@ public class ConversationFragment extends Fragment { getActivity().invalidateOptionsMenu(); updateChatMsgHint(); if (!activity.shouldPaneBeOpen()) { - activity.xmppConnectionService.markRead(conversation); + activity.xmppConnectionService.markRead(conversation,true); activity.updateConversationList(); } this.updateSendButton(); From facd15f0373913eaafe8aa3a9a65cd02d8269aba Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 2 Oct 2014 22:17:25 +0200 Subject: [PATCH 22/57] check if display is off for notifications --- .../conversations/services/NotificationService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 012bac302..eb2039091 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -12,6 +12,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; +import android.os.PowerManager; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.Html; @@ -39,7 +40,12 @@ public class NotificationService { } public synchronized void push(Message message) { - if (this.mIsInForeground + + PowerManager pm = (PowerManager) mXmppConnectionService + .getSystemService(Context.POWER_SERVICE); + boolean isScreenOn = pm.isScreenOn(); + + if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { return; // simply ignore } @@ -51,7 +57,7 @@ public class NotificationService { mList.add(message); notifications.put(conversationUuid, mList); } - updateNotification(!(this.mIsInForeground && this.mOpenConversation == null)); + updateNotification(!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn); } public void clear() { From 0e56ff93e9df5ef80e1f2841fb5b9dca3161cd43 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 11:55:38 +0200 Subject: [PATCH 23/57] fixed possible npe --- .../siacs/conversations/services/NotificationService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index eb2039091..9428aa15a 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -57,7 +57,8 @@ public class NotificationService { mList.add(message); notifications.put(conversationUuid, mList); } - updateNotification(!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn); + updateNotification(!(this.mIsInForeground && this.mOpenConversation == null) + || !isScreenOn); } public void clear() { @@ -195,6 +196,9 @@ public class NotificationService { public static boolean wasHighlightedOrPrivate(Message message) { String nick = message.getConversation().getMucOptions().getActualNick(); Pattern highlight = generateNickHighlightPattern(nick); + if (message.getBody() == null || nick == null) { + return false; + } Matcher m = highlight.matcher(message.getBody()); return (m.find() || message.getType() == Message.TYPE_PRIVATE); } From 730f46c7b2db7d8c6849d36609643d6c02bf4221 Mon Sep 17 00:00:00 2001 From: Isaac Kwan Date: Fri, 3 Oct 2014 19:34:51 +0800 Subject: [PATCH 24/57] 1) Renamed values-zh values-zh_rCN in accordance with #329 and Android conventions 2) Added arrays.xml translations for Simplified Chinese (zh_rCN) 3) Added translations (arrays.xml and strings.xml) for Traditional Chinese (zh_rTW) --- res/values-zh_rCN/arrays.xml | 39 +++ res/{values-zh => values-zh_rCN}/strings.xml | 0 res/values-zh_rTW/arrays.xml | 39 +++ res/values-zh_rTW/strings.xml | 265 +++++++++++++++++++ 4 files changed, 343 insertions(+) create mode 100644 res/values-zh_rCN/arrays.xml rename res/{values-zh => values-zh_rCN}/strings.xml (100%) create mode 100644 res/values-zh_rTW/arrays.xml create mode 100644 res/values-zh_rTW/strings.xml diff --git a/res/values-zh_rCN/arrays.xml b/res/values-zh_rCN/arrays.xml new file mode 100644 index 000000000..1a2430791 --- /dev/null +++ b/res/values-zh_rCN/arrays.xml @@ -0,0 +1,39 @@ + + + + + 手机 + 电话 + 平板电脑 + Conversations + Android + + + 永不 + 256 KB + 512 KB + 1 MB + + + 0 + 262144 + 524288 + 1048576 + + + 30 分钟 + 1 小时 + 2 小时 + 8 小时 + 直至另行取消 + + + + 1800 + 3600 + 7200 + 28800 + -1 + + + \ No newline at end of file diff --git a/res/values-zh/strings.xml b/res/values-zh_rCN/strings.xml similarity index 100% rename from res/values-zh/strings.xml rename to res/values-zh_rCN/strings.xml diff --git a/res/values-zh_rTW/arrays.xml b/res/values-zh_rTW/arrays.xml new file mode 100644 index 000000000..b9c261adc --- /dev/null +++ b/res/values-zh_rTW/arrays.xml @@ -0,0 +1,39 @@ + + + + + 手機 + 電話 + 平板電腦 + Conversations + Android + + + 永不 + 256 KB + 512 KB + 1 MB + + + 0 + 262144 + 524288 + 1048576 + + + 30 分鐘 + 1 小時 + 2 小時 + 8 小時 + 直至另行取消 + + + + 1800 + 3600 + 7200 + 28800 + -1 + + + \ No newline at end of file diff --git a/res/values-zh_rTW/strings.xml b/res/values-zh_rTW/strings.xml new file mode 100644 index 000000000..77389ffe5 --- /dev/null +++ b/res/values-zh_rTW/strings.xml @@ -0,0 +1,265 @@ + + + +    Conversations +    設定 +    新對話 +    管理帳戶 +    結束對話 +    聯絡人詳情 +    群組詳情 +    安全對話 +    新增帳戶 +    編輯姓名 +    新增到手機通訊錄 +    從列表中刪除 +    管理帳戶 +    設定 +    群組詳情 +    聯絡人詳情 +    對話 +    分享對話 +    開始對話 +    選擇聯絡人 +    剛剛 +    1 分鐘前 +    %d 分鐘前 +    未讀對話 +    正在發送… +    正在解密訊息中,請稍候… +    該用戶名稱已被使用 +    管理員 +    擁有人 +    版主 +    成員 +    訪客 +    你確定要將 %s 從聯絡人清單中移除嗎?與該聯絡人的對話將不會被清除。 +    你確定要將 %s 從書籤清單中移除嗎?與該聯絡人的對話將不會被清除。 +    在伺服器上註冊新帳戶 +    分享 +    開始對話 +    邀請聯絡人 +    聯絡人 +    取消 +    新增 +    編輯 +    刪除 +    儲存 +    好的 +    Conversations 停止運行 +    發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式。\n警告: 你的 XMPP 帳戶將被用作發送有關訊息之用。 +    現在發送 +    不再詢問 +    無法連接至帳戶 +    無法連接至多個帳戶 +    點擊此處管理帳戶。 +    附件 +    該聯絡人不在你的聯絡人清單上,需要加為聯絡人嗎? +    新增聯絡人 +    傳遞失敗 +    拒絕 +    接收圖片文件中,請稍候… +    準備傳輸圖片 +    清除歷史記錄 +    清除對話記錄 +    你確定要刪除該對話中所有訊息嗎?\n\n警告: 這將不會影響其他設備或伺服器儲存的訊息。 +    刪除訊息 +    之後結束這對話 +    選擇狀態訊息 +    發送純文字訊息 +    發送 OTR 加密訊息 +    發送 OpenPGP 加密訊息 +    用戶名稱修改成功 +    下載圖片 +    可供下載的圖像文件 +    不加密發送 +    解密失敗,可能是私鑰不正確。 +    OpenKeychain +    Conversations 使用一個名為 OpenKeychain 的第三方程式來加密、解碼訊息以及管理您的公鑰。\n\nOpenKeychain 以 GPLv3 釋出,並可在 F-Droid 和 Google Play 上下載。\n\n(之後請重新啟動 Conversations。) +    重新啟動 +    安裝 +    提供中… +    等待中… +    找不到 OpenPGP 鑰匙 +    Conversations 不能將你的訊息加密,因為聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 +    找不到多條 OpenPGP 鑰匙 +    Conversations 不能將你的訊息加密,因為多位聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 +    已收到加密訊息,點擊進行解密和查看。 +    已收到加密圖片,點擊進行解密和查看。 +    已收到圖片,點擊查看 +    一般 +    XMPP 資源 +    客戶端標示名稱 +    接收文件 +    自動接收小於 … 的文件 +    通知設定 +    通知 +    收到新訊息時通知 +    震動 +    收到新訊息時震動 +    聲音 +    收到新訊息時播放鈴聲 +    群組通知 +    當有新訊息時總是通知,而不是被標記時才通知 +    通知限期 +    收到副本後,關閉通知一小段時間 +    進階選項 +    總是不發送故障報告 +    發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式 +    確認訊息 +    讓你的聯絡人知道你已收到及閱讀訊息 +    介面選項 +    OpenKeychain 回報了一個錯誤 +    解密文件時出現 I/O 錯誤 +    接受 +    發生了一個錯誤 +    同意更新狀態訊息 +    預先更新狀態訊息並關注聯絡人的狀態訊息 +    關注 +    你的帳戶 +    鑰匙 +    發送狀態訊息 +    接收狀態訊息 +    關注狀態訊息 +    選擇圖片 +    拍照 +    預先同意關注請求 +    您選擇的文件不是圖片 +    轉換圖片時發生錯誤 +    找不到文件 +    一般的 I/O 錯誤。是存儲空間不足嗎? +    你用來選擇圖片的 app 沒有給予足夠權限我們去讀取文件。\n\n請使用另一文件管理器來選擇圖片 +    未知 +    暫時停用 +    在線 +    連接中\u2026 +    離線 +    未授權 +    未找到伺服器 +    未連接網絡 +    註冊失敗 +    該用戶名稱已被使用 +    註冊完成 +    伺服器不支持註冊 +    純文字內容 +    OTR +    OpenPGP +    編輯帳戶 +    刪除帳戶 +    暫時停用 +    發佈頭像 +    發布 OpenPGP 公共鑰匙 +    啟用帳戶 +    你確定嗎? +    如果刪除帳戶,則所有對話訊息將會被刪除 +    錄音 +    Jabber ID +    密碼 +    username@example.com +    確認密碼 +    密碼 +    確認密碼 +    密碼不一致 +    該 Jabber ID 無效 +    空間不足,圖片過大 +    你確定要新增 %s 為聯絡人嗎? +    線上 +    目前有空 +    離開 +    長時間離開 +    請勿打擾 +    離線 +    群組 +    其他成員 +    XEP-0280: Message Carbons +    XEP-0198: Stream Management +    XEP-0163: PEP (Avatars) +    支援 +    不支援 +    沒有公佈公鑰訊息。 +    剛剛曾在線上 +    一分鐘前曾在線上 +    %d 分鐘前曾在線上 +    一小時前曾在線上 +    %d 小時前曾在線上 +    一天前曾在線上 +    %d 天前曾在線上 +    未曾上線 +    加密的訊息。請安裝 OpenKeychain 以解密。 +    未知的 OTR 指紋 +    發現以 OpenPGP 加密的訊息 +    接收失敗 +    你的指紋 +    OTR 指紋 +    驗證 +    解密 +    群組 +    查找 +    新增聯絡人 +    加入群組 +    刪除聯絡人 +    查看聯絡人詳細訊息 +    新增 +    聯絡人已存在 +    加入 +    群組地址 +    room@conference.example.com +    儲存為書籤 +    刪除書籤 +    該書籤已存在 +     +    編輯群組主題 +    群組未找到 +    離開 +    聯絡人已新增你到聯絡人列表 +    新增為聯絡人 +    %s 讀到此處 +    發佈 +    點擊頭像可選擇頭像 +    請注意: 所有關注你狀態訊息的人將看到該圖像。 +    發佈中… +    伺服器拒絕了你的發佈請求 +    發佈頭像時發生錯誤 +    將頭像儲存至硬碟時發生錯誤 +    (或長按以回復預設頭像) +    你的伺服器不支持發佈頭像 +    私密聊天 +    給 %s +    發送私密消息給 %s +    連接 +    該帳戶已存在 +    下一步 +    已建立連接 +    其他訊息 +    略過 +    關閉通知 +    關閉該對話消息 +    通知已關閉 +    打開通知 +    群組設有密碼 +    輸入密碼 +    缺少聯絡人狀態訊息 +    請先發送關注狀態訊息請求。\n\n這將用來判斷您的聯絡人所用的客戶端類型。 +    現在發送請求 +    刪除指紋 +    你確定刪除該指紋嗎? +    忽略 +    警告: 在沒有互相關注狀態訊息的情況下發送或會引起不能預計的問題。\n\n請檢視聯絡人詳情頁面以確認你們的關注狀態。 +    加密設定 +    強制要求端到端加密 +    總是發送加密訊息 (群組訊息除外) +    不儲存加密訊息 +    警告: 此操作或會導致訊息丟失 +    專家選項 +    請小心設定 +    增加字體大小 +    讓整個 app 界面使用更大號的字體 +    用「發送」按鈕顯示狀態訊息 +    要求讀取收據 +    已被讀取的訊息會以綠色勾號表示。請注意,這個功能未必每次有效。 +    將「發送」按鈕設成不同顏色,以表示不同的狀態訊息。 +    其他 +    群組名稱 +    使用群組的名稱而不是 JID 來識別之。 + + \ No newline at end of file From 9ae52a235f39f86813220eae0bd084251242470e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 15:00:29 +0200 Subject: [PATCH 25/57] revised tablet ui. fixed #423 --- .../fragment_conversations_overview.xml | 8 +- .../fragment_conversations_overview.xml | 2 +- .../fragment_conversations_overview.xml | 4 +- .../fragment_conversations_overview.xml | 13 +- .../fragment_conversations_overview.xml | 2 +- .../ui/ConversationActivity.java | 249 +++++++++++------- .../ui/ConversationFragment.java | 8 +- .../siacs/conversations/ui/XmppActivity.java | 6 + .../ui/adapter/ConversationAdapter.java | 4 +- 9 files changed, 177 insertions(+), 119 deletions(-) rename res/{layout-sw600dp => layout-w360dp}/fragment_conversations_overview.xml (83%) rename res/{layout-sw384dp => layout-w384dp}/fragment_conversations_overview.xml (96%) rename res/{layout-sw360dp => layout-w600dp}/fragment_conversations_overview.xml (93%) rename res/{layout-sw720dp => layout-w960dp}/fragment_conversations_overview.xml (66%) diff --git a/res/layout-sw600dp/fragment_conversations_overview.xml b/res/layout-w360dp/fragment_conversations_overview.xml similarity index 83% rename from res/layout-sw600dp/fragment_conversations_overview.xml rename to res/layout-w360dp/fragment_conversations_overview.xml index 5dfdceff5..a639ed56b 100644 --- a/res/layout-sw600dp/fragment_conversations_overview.xml +++ b/res/layout-w360dp/fragment_conversations_overview.xml @@ -1,11 +1,11 @@ - @@ -27,4 +27,4 @@ android:orientation="vertical" > - \ No newline at end of file + \ No newline at end of file diff --git a/res/layout-sw384dp/fragment_conversations_overview.xml b/res/layout-w384dp/fragment_conversations_overview.xml similarity index 96% rename from res/layout-sw384dp/fragment_conversations_overview.xml rename to res/layout-w384dp/fragment_conversations_overview.xml index 2a4220523..c3aa67ae6 100644 --- a/res/layout-sw384dp/fragment_conversations_overview.xml +++ b/res/layout-w384dp/fragment_conversations_overview.xml @@ -1,5 +1,5 @@ diff --git a/res/layout-sw360dp/fragment_conversations_overview.xml b/res/layout-w600dp/fragment_conversations_overview.xml similarity index 93% rename from res/layout-sw360dp/fragment_conversations_overview.xml rename to res/layout-w600dp/fragment_conversations_overview.xml index ef8a1b6e2..331fb1f06 100644 --- a/res/layout-sw360dp/fragment_conversations_overview.xml +++ b/res/layout-w600dp/fragment_conversations_overview.xml @@ -1,11 +1,11 @@ diff --git a/res/layout-sw720dp/fragment_conversations_overview.xml b/res/layout-w960dp/fragment_conversations_overview.xml similarity index 66% rename from res/layout-sw720dp/fragment_conversations_overview.xml rename to res/layout-w960dp/fragment_conversations_overview.xml index bc52ec461..5309674be 100644 --- a/res/layout-sw720dp/fragment_conversations_overview.xml +++ b/res/layout-w960dp/fragment_conversations_overview.xml @@ -1,11 +1,11 @@ - + android:layout_height="match_parent" + android:orientation="horizontal"> @@ -23,8 +23,7 @@ android:id="@+id/selected_conversation" android:layout_width="fill_parent" android:layout_height="match_parent" - android:layout_weight="1" android:orientation="vertical" > - \ No newline at end of file + \ No newline at end of file diff --git a/res/layout/fragment_conversations_overview.xml b/res/layout/fragment_conversations_overview.xml index bc52ec461..d4145761d 100644 --- a/res/layout/fragment_conversations_overview.xml +++ b/res/layout/fragment_conversations_overview.xml @@ -1,5 +1,5 @@ diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 0c67beff9..04af0e845 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -59,8 +59,13 @@ public class ConversationActivity extends XmppActivity implements private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301; private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302; private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303; + private static final String STATE_OPEN_CONVERSATION = "state_open_conversation"; + private static final String STATE_PANEL_OPEN = "state_panel_open"; - protected SlidingPaneLayout spl; + private String mOpenConverstaion = null; + private boolean mPanelOpen = true; + + private View mContentView; private List conversationList = new ArrayList(); private Conversation selectedConversation = null; @@ -83,25 +88,59 @@ public class ConversationActivity extends XmppActivity implements } public void setSelectedConversation(Conversation conversation) { - this.selectedConversation = conversation; + this.selectedConversation = conversation; } public ListView getConversationListView() { return this.listView; } - public SlidingPaneLayout getSlidingPaneLayout() { - return this.spl; - } - public boolean shouldPaneBeOpen() { return paneShouldBeOpen; } + + public void showConversationsOverview() { + if (mContentView instanceof SlidingPaneLayout) { + SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; + mSlidingPaneLayout.openPane(); + } + } + + public void hideConversationsOverview() { + if (mContentView instanceof SlidingPaneLayout) { + SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; + mSlidingPaneLayout.closePane(); + } + } + + public boolean isConversationsOverviewHideable() { + if (mContentView instanceof SlidingPaneLayout) { + SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; + return mSlidingPaneLayout.isSlideable(); + } else { + return false; + } + } + + public boolean isConversationsOverviewVisable() { + if (mContentView instanceof SlidingPaneLayout) { + SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; + return mSlidingPaneLayout.isOpen(); + } else { + return true; + } + } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (savedInstanceState != null) { + mOpenConverstaion = savedInstanceState.getString( + STATE_OPEN_CONVERSATION, null); + mPanelOpen = savedInstanceState.getBoolean(STATE_PANEL_OPEN, true); + } + setContentView(R.layout.fragment_conversations_overview); listView = (ListView) findViewById(R.id.list); @@ -122,54 +161,61 @@ public class ConversationActivity extends XmppActivity implements setSelectedConversation(conversationList.get(position)); swapConversationFragment(); } else { - spl.closePane(); + hideConversationsOverview(); } } }); - spl = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout); - spl.setParallaxDistance(150); - spl.setShadowResource(R.drawable.es_slidingpane_shadow); - spl.setSliderFadeColor(0); - spl.setPanelSlideListener(new PanelSlideListener() { + mContentView = findViewById(R.id.content_view_spl); + if (mContentView==null) { + mContentView = findViewById(R.id.content_view_ll); + } + if (mContentView instanceof SlidingPaneLayout) { + SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; + mSlidingPaneLayout.setParallaxDistance(150); + mSlidingPaneLayout.setShadowResource(R.drawable.es_slidingpane_shadow); + mSlidingPaneLayout.setSliderFadeColor(0); + mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() { - @Override - public void onPanelOpened(View arg0) { - paneShouldBeOpen = true; - ActionBar ab = getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(false); - ab.setHomeButtonEnabled(false); - ab.setTitle(R.string.app_name); - } - invalidateOptionsMenu(); - hideKeyboard(); - if (xmppConnectionServiceBound) { - xmppConnectionService.getNotificationService().setOpenConversation(null); - } - } - - @Override - public void onPanelClosed(View arg0) { - paneShouldBeOpen = false; - if ((conversationList.size() > 0) - && (getSelectedConversation() != null)) { - openConversation(getSelectedConversation()); - if (!getSelectedConversation().isRead()) { - xmppConnectionService - .markRead(getSelectedConversation(),true); - listView.invalidateViews(); + @Override + public void onPanelOpened(View arg0) { + paneShouldBeOpen = true; + ActionBar ab = getActionBar(); + if (ab != null) { + ab.setDisplayHomeAsUpEnabled(false); + ab.setHomeButtonEnabled(false); + ab.setTitle(R.string.app_name); + } + invalidateOptionsMenu(); + hideKeyboard(); + if (xmppConnectionServiceBound) { + xmppConnectionService.getNotificationService() + .setOpenConversation(null); } } - } - @Override - public void onPanelSlide(View arg0, float arg1) { - // TODO Auto-generated method stub + @Override + public void onPanelClosed(View arg0) { + paneShouldBeOpen = false; + if ((conversationList.size() > 0) + && (getSelectedConversation() != null)) { + openConversation(getSelectedConversation()); + if (!getSelectedConversation().isRead()) { + xmppConnectionService.markRead( + getSelectedConversation(), true); + listView.invalidateViews(); + } + } + } - } - }); + @Override + public void onPanelSlide(View arg0, float arg1) { + // TODO Auto-generated method stub + + } + }); + } } - + public void openConversation(Conversation conversation) { ActionBar ab = getActionBar(); if (ab != null) { @@ -179,13 +225,14 @@ public class ConversationActivity extends XmppActivity implements || activity.useSubjectToIdentifyConference()) { ab.setTitle(getSelectedConversation().getName()); } else { - ab.setTitle(getSelectedConversation() - .getContactJid().split("/")[0]); + ab.setTitle(getSelectedConversation().getContactJid() + .split("/")[0]); } } invalidateOptionsMenu(); if (xmppConnectionServiceBound) { - xmppConnectionService.getNotificationService().setOpenConversation(conversation); + xmppConnectionService.getNotificationService().setOpenConversation( + conversation); } } @@ -206,7 +253,7 @@ public class ConversationActivity extends XmppActivity implements .findItem(R.id.action_invite); MenuItem menuMute = (MenuItem) menu.findItem(R.id.action_mute); - if ((spl.isOpen() && (spl.isSlideable()))) { + if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) { menuArchive.setVisible(false); menuMucDetails.setVisible(false); menuContactDetails.setVisible(false); @@ -216,7 +263,7 @@ public class ConversationActivity extends XmppActivity implements menuClearHistory.setVisible(false); menuMute.setVisible(false); } else { - menuAdd.setVisible(!spl.isSlideable()); + menuAdd.setVisible(!isConversationsOverviewHideable()); if (this.getSelectedConversation() != null) { if (this.getSelectedConversation().getLatestMessage() .getEncryption() != Message.ENCRYPTION_NONE) { @@ -325,7 +372,7 @@ public class ConversationActivity extends XmppActivity implements @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { - spl.openPane(); + showConversationsOverview(); return true; } else if (item.getItemId() == R.id.action_add) { startActivity(new Intent(this, StartConversationActivity.class)); @@ -377,7 +424,7 @@ public class ConversationActivity extends XmppActivity implements public void endConversation(Conversation conversation) { conversation.setStatus(Conversation.STATUS_ARCHIVED); paneShouldBeOpen = true; - spl.openPane(); + showConversationsOverview(); xmppConnectionService.archiveConversation(conversation); if (conversationList.size() > 0) { setSelectedConversation(conversationList.get(0)); @@ -563,8 +610,8 @@ public class ConversationActivity extends XmppActivity implements @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - if (!spl.isOpen()) { - spl.openPane(); + if (!isConversationsOverviewVisable()) { + showConversationsOverview(); return false; } } @@ -612,63 +659,71 @@ public class ConversationActivity extends XmppActivity implements xmppConnectionService.removeOnConversationListChangedListener(); xmppConnectionService.removeOnAccountListChangedListener(); xmppConnectionService.removeOnRosterUpdateListener(); - xmppConnectionService.getNotificationService().setOpenConversation(null); + xmppConnectionService.getNotificationService().setOpenConversation( + null); } super.onStop(); } + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + savedInstanceState.putString(STATE_OPEN_CONVERSATION, + getSelectedConversation().getUuid()); + savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable()); + super.onSaveInstanceState(savedInstanceState); + } + @Override void onBackendConnected() { this.registerListener(); - if (conversationList.size() == 0) { - updateConversationList(); + updateConversationList(); + + if (xmppConnectionService.getAccounts().size() == 0) { + startActivity(new Intent(this, EditAccountActivity.class)); + } else if (conversationList.size() <= 0) { + startActivity(new Intent(this, StartConversationActivity.class)); + finish(); + } else if (mOpenConverstaion != null) { + selectConversationByUuid(mOpenConverstaion); + paneShouldBeOpen = mPanelOpen; + if (paneShouldBeOpen) { + showConversationsOverview(); + } + swapConversationFragment(); + mOpenConverstaion = null; + } else if (getIntent() != null + && VIEW_CONVERSATION.equals(getIntent().getType())) { + String uuid = (String) getIntent().getExtras().get(CONVERSATION); + String text = getIntent().getExtras().getString(TEXT, null); + selectConversationByUuid(uuid); + paneShouldBeOpen = false; + swapConversationFragment().setText(text); + setIntent(null); + } else { + showConversationsOverview(); + ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() + .findFragmentByTag("conversation"); + if (selectedFragment != null) { + selectedFragment.onBackendConnected(); + } else { + pendingImageUri = null; + setSelectedConversation(conversationList.get(0)); + swapConversationFragment(); + } } - if (getSelectedConversation() != null && pendingImageUri != null) { + if (pendingImageUri != null) { attachImageToConversation(getSelectedConversation(), pendingImageUri); pendingImageUri = null; - } else { - pendingImageUri = null; } + ExceptionHelper.checkForCrash(this, this.xmppConnectionService); + } - if ((getIntent().getAction() != null) - && (getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) { - if (getIntent().getType().equals( - ConversationActivity.VIEW_CONVERSATION)) { - handledViewIntent = true; - - String convToView = (String) getIntent().getExtras().get( - CONVERSATION); - - for (int i = 0; i < conversationList.size(); ++i) { - if (conversationList.get(i).getUuid().equals(convToView)) { - setSelectedConversation(conversationList.get(i)); - } - } - paneShouldBeOpen = false; - String text = getIntent().getExtras().getString(TEXT, null); - swapConversationFragment().setText(text); - } - } else { - if (xmppConnectionService.getAccounts().size() == 0) { - startActivity(new Intent(this, EditAccountActivity.class)); - } else if (conversationList.size() <= 0) { - // add no history - startActivity(new Intent(this, StartConversationActivity.class)); - finish(); - } else { - spl.openPane(); - // find currently loaded fragment - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() - .findFragmentByTag("conversation"); - if (selectedFragment != null) { - selectedFragment.onBackendConnected(); - } else { - setSelectedConversation(conversationList.get(0)); - swapConversationFragment(); - } - ExceptionHelper.checkForCrash(this, this.xmppConnectionService); + private void selectConversationByUuid(String uuid) { + for (int i = 0; i < conversationList.size(); ++i) { + if (conversationList.get(i).getUuid().equals(uuid)) { + setSelectedConversation(conversationList.get(i)); } } } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 34c68e00b..86e5257ac 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -245,9 +245,7 @@ public class ConversationFragment extends Fragment { @Override public void onClick(View v) { - if (activity.getSlidingPaneLayout().isSlideable()) { - activity.getSlidingPaneLayout().closePane(); - } + activity.hideConversationsOverview(); } }); mEditMessage.setOnEditorActionListener(mEditorActionListener); @@ -376,9 +374,9 @@ public class ConversationFragment extends Fragment { int position = mEditMessage.length(); Editable etext = mEditMessage.getText(); Selection.setSelection(etext, position); - if (activity.getSlidingPaneLayout().isSlideable()) { + if (activity.isConversationsOverviewHideable()) { if (!activity.shouldPaneBeOpen()) { - activity.getSlidingPaneLayout().closePane(); + activity.hideConversationsOverview(); activity.openConversation(conversation); } } diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 518f7b0be..39ca623bb 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -59,6 +59,7 @@ public abstract class XmppActivity extends Activity { protected int mPrimaryTextColor; protected int mSecondaryTextColor; + protected int mSecondaryBackgroundColor; protected int mColorRed; protected int mColorOrange; protected int mColorGreen; @@ -207,6 +208,7 @@ public abstract class XmppActivity extends Activity { mColorOrange = getResources().getColor(R.color.orange); mColorGreen = getResources().getColor(R.color.green); mPrimaryColor = getResources().getColor(R.color.primary); + mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); if (getPreferences().getBoolean("use_larger_font", false)) { setTheme(R.style.ConversationsTheme_LargerText); } @@ -518,6 +520,10 @@ public abstract class XmppActivity extends Activity { public int getPrimaryColor() { return this.mPrimaryColor; } + + public int getSecondaryBackgroundColor() { + return this.mSecondaryBackgroundColor; + } class BitmapWorkerTask extends AsyncTask { private final WeakReference imageViewReference; diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 7b470faa4..583772baf 100644 --- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -40,9 +40,9 @@ public class ConversationAdapter extends ArrayAdapter { Conversation conv = getItem(position); if (this.activity instanceof ConversationActivity) { ConversationActivity activity = (ConversationActivity) this.activity; - if (!activity.getSlidingPaneLayout().isSlideable()) { + if (!activity.isConversationsOverviewHideable()) { if (conv == activity.getSelectedConversation()) { - view.setBackgroundColor(0xffdddddd); + view.setBackgroundColor(activity.getSecondaryBackgroundColor()); } else { view.setBackgroundColor(Color.TRANSPARENT); } From 0e12272c5bb7a40b200824bfe2b3f209795c4b98 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 15:01:36 +0200 Subject: [PATCH 26/57] bug fixes --- AndroidManifest.xml | 1 - res/layout-w360dp/fragment_conversations_overview.xml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d86d5bb15..85cf2dc65 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -40,7 +40,6 @@ diff --git a/res/layout-w360dp/fragment_conversations_overview.xml b/res/layout-w360dp/fragment_conversations_overview.xml index a639ed56b..a600118db 100644 --- a/res/layout-w360dp/fragment_conversations_overview.xml +++ b/res/layout-w360dp/fragment_conversations_overview.xml @@ -1,4 +1,4 @@ - @@ -27,4 +27,4 @@ android:orientation="vertical" > - \ No newline at end of file + \ No newline at end of file From d51b41590c6d6871632a9cf88de532c4038b8bcd Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 16:16:51 +0200 Subject: [PATCH 27/57] fixed chinese translations --- .../arrays.xml | 0 .../strings.xml | 0 .../arrays.xml | 0 res/values-zh-rTW/strings.xml | 263 +++++++++++++++++ res/values-zh_rTW/strings.xml | 265 ------------------ 5 files changed, 263 insertions(+), 265 deletions(-) rename res/{values-zh_rCN => values-zh-rCN}/arrays.xml (100%) rename res/{values-zh_rCN => values-zh-rCN}/strings.xml (100%) rename res/{values-zh_rTW => values-zh-rTW}/arrays.xml (100%) create mode 100644 res/values-zh-rTW/strings.xml delete mode 100644 res/values-zh_rTW/strings.xml diff --git a/res/values-zh_rCN/arrays.xml b/res/values-zh-rCN/arrays.xml similarity index 100% rename from res/values-zh_rCN/arrays.xml rename to res/values-zh-rCN/arrays.xml diff --git a/res/values-zh_rCN/strings.xml b/res/values-zh-rCN/strings.xml similarity index 100% rename from res/values-zh_rCN/strings.xml rename to res/values-zh-rCN/strings.xml diff --git a/res/values-zh_rTW/arrays.xml b/res/values-zh-rTW/arrays.xml similarity index 100% rename from res/values-zh_rTW/arrays.xml rename to res/values-zh-rTW/arrays.xml diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..2c3ea225c --- /dev/null +++ b/res/values-zh-rTW/strings.xml @@ -0,0 +1,263 @@ + + + + Conversations + 設定 + 新對話 + 管理帳戶 + 結束對話 + 聯絡人詳情 + 安全對話 + 新增帳戶 + 編輯姓名 + 新增到手機通訊錄 + 從列表中刪除 + 管理帳戶 + 群組詳情 + 聯絡人詳情 + 對話 + 分享對話 + 開始對話 + 選擇聯絡人 + 剛剛 + 1 分鐘前 + %d 分鐘前 + 未讀對話 + 正在發送… + 正在解密訊息中,請稍候… + 該用戶名稱已被使用 + 管理員 + 擁有人 + 版主 + 成員 + 訪客 + 你確定要將 %s 從聯絡人清單中移除嗎?與該聯絡人的對話將不會被清除。 + 你確定要將 %s 從書籤清單中移除嗎?與該聯絡人的對話將不會被清除。 + 在伺服器上註冊新帳戶 + 分享 + 開始對話 + 邀請聯絡人 + 聯絡人 + 取消 + 新增 + 編輯 + 刪除 + 儲存 + 好的 + Conversations 停止運行 + 發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式。\n警告: 你的 XMPP 帳戶將被用作發送有關訊息之用。 + 現在發送 + 不再詢問 + 無法連接至帳戶 + 無法連接至多個帳戶 + 點擊此處管理帳戶。 + 附件 + 該聯絡人不在你的聯絡人清單上,需要加為聯絡人嗎? + 新增聯絡人 + 傳遞失敗 + 拒絕 + 接收圖片文件中,請稍候… + 準備傳輸圖片 + 清除歷史記錄 + 清除對話記錄 + 你確定要刪除該對話中所有訊息嗎?\n\n警告: 這將不會影響其他設備或伺服器儲存的訊息。 + 刪除訊息 + 之後結束這對話 + 選擇狀態訊息 + 發送純文字訊息 + 發送 OTR 加密訊息 + 發送 OpenPGP 加密訊息 + 用戶名稱修改成功 + 下載圖片 + 可供下載的圖像文件 + 不加密發送 + 解密失敗,可能是私鑰不正確。 + OpenKeychain + Conversations 使用一個名為 OpenKeychain 的第三方程式來加密、解碼訊息以及管理您的公鑰。\n\nOpenKeychain 以 GPLv3 釋出,並可在 F-Droid 和 Google Play 上下載。\n\n(之後請重新啟動 Conversations。) + 重新啟動 + 安裝 + 提供中… + 等待中… + 找不到 OpenPGP 鑰匙 + Conversations 不能將你的訊息加密,因為聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 + 找不到多條 OpenPGP 鑰匙 + Conversations 不能將你的訊息加密,因為多位聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 + 已收到加密訊息,點擊進行解密和查看。 + 已收到加密圖片,點擊進行解密和查看。 + 已收到圖片,點擊查看 + 一般 + XMPP 資源 + 客戶端標示名稱 + 接收文件 + 自動接收小於 … 的文件 + 通知設定 + 通知 + 收到新訊息時通知 + 震動 + 收到新訊息時震動 + 聲音 + 收到新訊息時播放鈴聲 + 群組通知 + 當有新訊息時總是通知,而不是被標記時才通知 + 通知限期 + 收到副本後,關閉通知一小段時間 + 進階選項 + 總是不發送故障報告 + 發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式 + 確認訊息 + 讓你的聯絡人知道你已收到及閱讀訊息 + 介面選項 + OpenKeychain 回報了一個錯誤 + 解密文件時出現 I/O 錯誤 + 接受 + 發生了一個錯誤 + 同意更新狀態訊息 + 預先更新狀態訊息並關注聯絡人的狀態訊息 + 關注 + 你的帳戶 + 鑰匙 + 發送狀態訊息 + 接收狀態訊息 + 關注狀態訊息 + 選擇圖片 + 拍照 + 預先同意關注請求 + 您選擇的文件不是圖片 + 轉換圖片時發生錯誤 + 找不到文件 + 一般的 I/O 錯誤。是存儲空間不足嗎? + 你用來選擇圖片的 app 沒有給予足夠權限我們去讀取文件。\n\n請使用另一文件管理器來選擇圖片 + 未知 + 暫時停用 + 在線 + 連接中\u2026 + 離線 + 未授權 + 未找到伺服器 + 未連接網絡 + 註冊失敗 + 該用戶名稱已被使用 + 註冊完成 + 伺服器不支持註冊 + 純文字內容 + OTR + OpenPGP + 編輯帳戶 + 刪除帳戶 + 暫時停用 + 發佈頭像 + 發布 OpenPGP 公共鑰匙 + 啟用帳戶 + 你確定嗎? + 如果刪除帳戶,則所有對話訊息將會被刪除 + 錄音 + Jabber ID + 密碼 + username@example.com + 確認密碼 + 密碼 + 確認密碼 + 密碼不一致 + 該 Jabber ID 無效 + 空間不足,圖片過大 + 你確定要新增 %s 為聯絡人嗎? + 線上 + 目前有空 + 離開 + 長時間離開 + 請勿打擾 + 離線 + 群組 + 其他成員 + XEP-0280: Message Carbons + XEP-0198: Stream Management + XEP-0163: PEP (Avatars) + 支援 + 不支援 + 沒有公佈公鑰訊息。 + 剛剛曾在線上 + 一分鐘前曾在線上 + %d 分鐘前曾在線上 + 一小時前曾在線上 + %d 小時前曾在線上 + 一天前曾在線上 + %d 天前曾在線上 + 未曾上線 + 加密的訊息。請安裝 OpenKeychain 以解密。 + 未知的 OTR 指紋 + 發現以 OpenPGP 加密的訊息 + 接收失敗 + 你的指紋 + OTR 指紋 + 驗證 + 解密 + 群組 + 查找 + 新增聯絡人 + 加入群組 + 刪除聯絡人 + 查看聯絡人詳細訊息 + 新增 + 聯絡人已存在 + 加入 + 群組地址 + room@conference.example.com + 儲存為書籤 + 刪除書籤 + 該書籤已存在 + + 編輯群組主題 + 群組未找到 + 離開 + 聯絡人已新增你到聯絡人列表 + 新增為聯絡人 + %s 讀到此處 + 發佈 + 點擊頭像可選擇頭像 + 請注意: 所有關注你狀態訊息的人將看到該圖像。 + 發佈中… + 伺服器拒絕了你的發佈請求 + 發佈頭像時發生錯誤 + 將頭像儲存至硬碟時發生錯誤 + (或長按以回復預設頭像) + 你的伺服器不支持發佈頭像 + 私密聊天 + 給 %s + 發送私密消息給 %s + 連接 + 該帳戶已存在 + 下一步 + 已建立連接 + 其他訊息 + 略過 + 關閉通知 + 關閉該對話消息 + 通知已關閉 + 打開通知 + 群組設有密碼 + 輸入密碼 + 缺少聯絡人狀態訊息 + 請先發送關注狀態訊息請求。\n\n這將用來判斷您的聯絡人所用的客戶端類型。 + 現在發送請求 + 刪除指紋 + 你確定刪除該指紋嗎? + 忽略 + 警告: 在沒有互相關注狀態訊息的情況下發送或會引起不能預計的問題。\n\n請檢視聯絡人詳情頁面以確認你們的關注狀態。 + 加密設定 + 強制要求端到端加密 + 總是發送加密訊息 (群組訊息除外) + 不儲存加密訊息 + 警告: 此操作或會導致訊息丟失 + 專家選項 + 請小心設定 + 增加字體大小 + 讓整個 app 界面使用更大號的字體 + 用「發送」按鈕顯示狀態訊息 + 要求讀取收據 + 已被讀取的訊息會以綠色勾號表示。請注意,這個功能未必每次有效。 + 將「發送」按鈕設成不同顏色,以表示不同的狀態訊息。 + 其他 + 群組名稱 + 使用群組的名稱而不是 JID 來識別之。 + + \ No newline at end of file diff --git a/res/values-zh_rTW/strings.xml b/res/values-zh_rTW/strings.xml deleted file mode 100644 index 77389ffe5..000000000 --- a/res/values-zh_rTW/strings.xml +++ /dev/null @@ -1,265 +0,0 @@ - - - -    Conversations -    設定 -    新對話 -    管理帳戶 -    結束對話 -    聯絡人詳情 -    群組詳情 -    安全對話 -    新增帳戶 -    編輯姓名 -    新增到手機通訊錄 -    從列表中刪除 -    管理帳戶 -    設定 -    群組詳情 -    聯絡人詳情 -    對話 -    分享對話 -    開始對話 -    選擇聯絡人 -    剛剛 -    1 分鐘前 -    %d 分鐘前 -    未讀對話 -    正在發送… -    正在解密訊息中,請稍候… -    該用戶名稱已被使用 -    管理員 -    擁有人 -    版主 -    成員 -    訪客 -    你確定要將 %s 從聯絡人清單中移除嗎?與該聯絡人的對話將不會被清除。 -    你確定要將 %s 從書籤清單中移除嗎?與該聯絡人的對話將不會被清除。 -    在伺服器上註冊新帳戶 -    分享 -    開始對話 -    邀請聯絡人 -    聯絡人 -    取消 -    新增 -    編輯 -    刪除 -    儲存 -    好的 -    Conversations 停止運行 -    發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式。\n警告: 你的 XMPP 帳戶將被用作發送有關訊息之用。 -    現在發送 -    不再詢問 -    無法連接至帳戶 -    無法連接至多個帳戶 -    點擊此處管理帳戶。 -    附件 -    該聯絡人不在你的聯絡人清單上,需要加為聯絡人嗎? -    新增聯絡人 -    傳遞失敗 -    拒絕 -    接收圖片文件中,請稍候… -    準備傳輸圖片 -    清除歷史記錄 -    清除對話記錄 -    你確定要刪除該對話中所有訊息嗎?\n\n警告: 這將不會影響其他設備或伺服器儲存的訊息。 -    刪除訊息 -    之後結束這對話 -    選擇狀態訊息 -    發送純文字訊息 -    發送 OTR 加密訊息 -    發送 OpenPGP 加密訊息 -    用戶名稱修改成功 -    下載圖片 -    可供下載的圖像文件 -    不加密發送 -    解密失敗,可能是私鑰不正確。 -    OpenKeychain -    Conversations 使用一個名為 OpenKeychain 的第三方程式來加密、解碼訊息以及管理您的公鑰。\n\nOpenKeychain 以 GPLv3 釋出,並可在 F-Droid 和 Google Play 上下載。\n\n(之後請重新啟動 Conversations。) -    重新啟動 -    安裝 -    提供中… -    等待中… -    找不到 OpenPGP 鑰匙 -    Conversations 不能將你的訊息加密,因為聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 -    找不到多條 OpenPGP 鑰匙 -    Conversations 不能將你的訊息加密,因為多位聯絡人沒有公佈他/她的公鑰。\n\n請通知聯絡人設定 OpenPGP。 -    已收到加密訊息,點擊進行解密和查看。 -    已收到加密圖片,點擊進行解密和查看。 -    已收到圖片,點擊查看 -    一般 -    XMPP 資源 -    客戶端標示名稱 -    接收文件 -    自動接收小於 … 的文件 -    通知設定 -    通知 -    收到新訊息時通知 -    震動 -    收到新訊息時震動 -    聲音 -    收到新訊息時播放鈴聲 -    群組通知 -    當有新訊息時總是通知,而不是被標記時才通知 -    通知限期 -    收到副本後,關閉通知一小段時間 -    進階選項 -    總是不發送故障報告 -    發送「堆疊追蹤」給 Conversations 的開發人員能幫助改進本程式 -    確認訊息 -    讓你的聯絡人知道你已收到及閱讀訊息 -    介面選項 -    OpenKeychain 回報了一個錯誤 -    解密文件時出現 I/O 錯誤 -    接受 -    發生了一個錯誤 -    同意更新狀態訊息 -    預先更新狀態訊息並關注聯絡人的狀態訊息 -    關注 -    你的帳戶 -    鑰匙 -    發送狀態訊息 -    接收狀態訊息 -    關注狀態訊息 -    選擇圖片 -    拍照 -    預先同意關注請求 -    您選擇的文件不是圖片 -    轉換圖片時發生錯誤 -    找不到文件 -    一般的 I/O 錯誤。是存儲空間不足嗎? -    你用來選擇圖片的 app 沒有給予足夠權限我們去讀取文件。\n\n請使用另一文件管理器來選擇圖片 -    未知 -    暫時停用 -    在線 -    連接中\u2026 -    離線 -    未授權 -    未找到伺服器 -    未連接網絡 -    註冊失敗 -    該用戶名稱已被使用 -    註冊完成 -    伺服器不支持註冊 -    純文字內容 -    OTR -    OpenPGP -    編輯帳戶 -    刪除帳戶 -    暫時停用 -    發佈頭像 -    發布 OpenPGP 公共鑰匙 -    啟用帳戶 -    你確定嗎? -    如果刪除帳戶,則所有對話訊息將會被刪除 -    錄音 -    Jabber ID -    密碼 -    username@example.com -    確認密碼 -    密碼 -    確認密碼 -    密碼不一致 -    該 Jabber ID 無效 -    空間不足,圖片過大 -    你確定要新增 %s 為聯絡人嗎? -    線上 -    目前有空 -    離開 -    長時間離開 -    請勿打擾 -    離線 -    群組 -    其他成員 -    XEP-0280: Message Carbons -    XEP-0198: Stream Management -    XEP-0163: PEP (Avatars) -    支援 -    不支援 -    沒有公佈公鑰訊息。 -    剛剛曾在線上 -    一分鐘前曾在線上 -    %d 分鐘前曾在線上 -    一小時前曾在線上 -    %d 小時前曾在線上 -    一天前曾在線上 -    %d 天前曾在線上 -    未曾上線 -    加密的訊息。請安裝 OpenKeychain 以解密。 -    未知的 OTR 指紋 -    發現以 OpenPGP 加密的訊息 -    接收失敗 -    你的指紋 -    OTR 指紋 -    驗證 -    解密 -    群組 -    查找 -    新增聯絡人 -    加入群組 -    刪除聯絡人 -    查看聯絡人詳細訊息 -    新增 -    聯絡人已存在 -    加入 -    群組地址 -    room@conference.example.com -    儲存為書籤 -    刪除書籤 -    該書籤已存在 -     -    編輯群組主題 -    群組未找到 -    離開 -    聯絡人已新增你到聯絡人列表 -    新增為聯絡人 -    %s 讀到此處 -    發佈 -    點擊頭像可選擇頭像 -    請注意: 所有關注你狀態訊息的人將看到該圖像。 -    發佈中… -    伺服器拒絕了你的發佈請求 -    發佈頭像時發生錯誤 -    將頭像儲存至硬碟時發生錯誤 -    (或長按以回復預設頭像) -    你的伺服器不支持發佈頭像 -    私密聊天 -    給 %s -    發送私密消息給 %s -    連接 -    該帳戶已存在 -    下一步 -    已建立連接 -    其他訊息 -    略過 -    關閉通知 -    關閉該對話消息 -    通知已關閉 -    打開通知 -    群組設有密碼 -    輸入密碼 -    缺少聯絡人狀態訊息 -    請先發送關注狀態訊息請求。\n\n這將用來判斷您的聯絡人所用的客戶端類型。 -    現在發送請求 -    刪除指紋 -    你確定刪除該指紋嗎? -    忽略 -    警告: 在沒有互相關注狀態訊息的情況下發送或會引起不能預計的問題。\n\n請檢視聯絡人詳情頁面以確認你們的關注狀態。 -    加密設定 -    強制要求端到端加密 -    總是發送加密訊息 (群組訊息除外) -    不儲存加密訊息 -    警告: 此操作或會導致訊息丟失 -    專家選項 -    請小心設定 -    增加字體大小 -    讓整個 app 界面使用更大號的字體 -    用「發送」按鈕顯示狀態訊息 -    要求讀取收據 -    已被讀取的訊息會以綠色勾號表示。請注意,這個功能未必每次有效。 -    將「發送」按鈕設成不同顏色,以表示不同的狀態訊息。 -    其他 -    群組名稱 -    使用群組的名稱而不是 JID 來識別之。 - - \ No newline at end of file From 9a4b48d1ec964bdce2a3c5f8242a01c0fa4a70e0 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 3 Oct 2014 15:55:06 +0200 Subject: [PATCH 28/57] let's own otr-fingerprint copy to clipboard. --- art/ic_action_copy.svg | 108 ++++++++++++++++++ art/render.rb | 2 +- res/drawable-hdpi/ic_action_copy.png | Bin 0 -> 717 bytes res/drawable-mdpi/ic_action_copy.png | Bin 0 -> 585 bytes res/drawable-xhdpi/ic_action_copy.png | Bin 0 -> 763 bytes res/drawable-xxhdpi/ic_action_copy.png | Bin 0 -> 1040 bytes res/layout/activity_edit_account.xml | 36 ++++-- res/values-de/strings.xml | 1 + res/values/strings.xml | 3 +- .../conversations/ui/EditAccountActivity.java | 35 +++++- 10 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 art/ic_action_copy.svg create mode 100644 res/drawable-hdpi/ic_action_copy.png create mode 100644 res/drawable-mdpi/ic_action_copy.png create mode 100644 res/drawable-xhdpi/ic_action_copy.png create mode 100644 res/drawable-xxhdpi/ic_action_copy.png diff --git a/art/ic_action_copy.svg b/art/ic_action_copy.svg new file mode 100644 index 000000000..485fd2ed7 --- /dev/null +++ b/art/ic_action_copy.svg @@ -0,0 +1,108 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/art/render.rb b/art/render.rb index 5464b9f54..a78a2f473 100755 --- a/art/render.rb +++ b/art/render.rb @@ -1,6 +1,6 @@ #!/bin/env ruby resolutions={'mdpi'=> 1, 'hdpi' => 1.5, 'xhdpi' => 2, 'xxhdpi' => 3} -images = { 'conversations.svg' => ['ic_launcher',48], 'conversations_baloon.svg' => ['ic_activity', 32], 'conversations_mono.svg' => ['ic_notification',24], 'ic_received_indicator.svg' => ['ic_received_indicator',12] } +images = { 'conversations.svg' => ['ic_launcher', 48], 'conversations_baloon.svg' => ['ic_activity', 32], 'conversations_mono.svg' => ['ic_notification', 24], 'ic_received_indicator.svg' => ['ic_received_indicator', 12], 'ic_action_copy.svg' => ['ic_action_copy', 32] } images.each do |source, result| resolutions.each do |name, factor| size = factor * result[1] diff --git a/res/drawable-hdpi/ic_action_copy.png b/res/drawable-hdpi/ic_action_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..b47bb69c9a0e8e02bb84b3dedb65032133644af9 GIT binary patch literal 717 zcmV;;0y6!HP)5uNYqY61Hu(rr4j6Gtppnz8w>vi z{{X>%!P-KsBwC0~EW}0-1hI&}io`+<92hLba1p;27s9db?#;X%lWg*VE%x5LdEePL z^WM9?GfDKBecLUdE4>e3e_NxO%>fs-NXsP8BrSOiTLS=&1B32*!n_7j0;qBTu&|uz ztOG@>Ni=|az{iq-rf|D*@2<^h0aTy%NYXE_b1!B#U-`(DJ`kUQ&1p8XL%_jc|0dp7 zKQOan4Yq5O4>39elX-d>xag9X%fiM5?1Ft@S^#Y`up@}pKojqP$4S2GxDK4DYv@t~ zlZ+&-Mpbz+v)@f^(G=QoM2on0HQ=5BGaCTc3N)-rx?9i>$g2SupOa<^G&JV7hpbfy zNsGX(EPq~lzYp|&C(bP5!@z7eIh(9V`tC7|*1(^Zwprjt&|eczfEOOav>5m;vS@gV*qqKmkMI3;>@Q zzjo=uw`hmVRp=+M7!}Z!J@!1Nr`u8Dp`=&QPQ`ELYFKA{oG4{f z(kZiuKLK}2M08=#74g8#PX8Arg+yvVz!l&vaKGAUW=DZ@NxGIKt#}MecH*X`^dxY# zz+WAYfRq5lzpF!207KxpXHW-Uy@ss;NSX(#zn(PN4uPlMfwSoS7n-co=vgznndGaE z6HN_S0UX)5wwyhkLLY#&EFl4wCvU9pf4BJy>Ar`R4$qilor})W2JVIN^C3yL;g7DycX`@s^^hv+vA&Gb`InQqLxu z9hi>Yl=P8*2X}3IqY40c2~0H*eL)7z@kOdp7l4}MKCs&p;4@(0PalAwf$d+CW`O6F z0PEpI(p)TV3LrQTrpR01LnS~;C%_iu`*-YfwA6v1b71oc`Bs6I5`ZoZZD04zF6q&L z>;f=%E<6mf0L*7{4Q-#6K;^n1rX^rG6ZZ%3wHJV-cJkOD+yTCo1n&h9I69JJdjyQe z36OL^(jxG>BFD&fr(?NU5c|@3;8g{{F!iv@fzSny9I(9y>{S3H)l~`q+b*Tr0ZD7X zo5J{qwhw9na=HY*7q-31HAp!C@iA}=92Wv)l`6$iNh;nY*&gKD;dC|&kkJD0sTLrmiT|8x(!b|7 X<#>CHpqGh)00000NkvXXu0mjf#{Bw0 literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/ic_action_copy.png b/res/drawable-xhdpi/ic_action_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..a45423f69d697ce56daf0d502647afcdee3fbd7a GIT binary patch literal 763 zcmVWzXo!E%&rOh_pE%uB)!pOF{J_N&51Zz7`o0J?7iWMCJBC?V){t+f5 zzdOuxPpMvD*=e3%09*wqRSA045bm`|kq98UR$?6uV=rK^9h?BY>;(oN0Y#Fah-@OS zU=xz-8pBdaFn6@vY7L_zKw{de$Js+(5iYcbsqJuc6VV$Yxs$L?QDTokFK+-~>;{t} zpqG_kN)AwO*s&dMa!vA!b&^;CtP$YV4mUXmU>2ZMDV!sTy3Cmp0pT~Eat)5{a90`Y z0E6w|BA}O1kdg#LQeKODx5K|le)gECR4MFzT-@d>RS0>v!xOKGO1&2EWjj2mTcEdC zuECcg@4nJ za3z8;64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{Odp%to zLn`LHox3+H)KTDgy|Akei|7%PEXAbM02aX`FQk7+?Q2}n|B(Ael;(|&UKXXSY~c+a ze;8C*x?NNhvW`9K5ZLkkNlJNoy8pXBs}7ue$Mb#v=FQgCb}pfue`b6xOSs0#I0ud_ z=Uk3($zwXs_4AUIe8|_@mwuaB81fj^y)2BF?lB%^Ju$awNr(7jh4Kx4Dn$nheAuF0 z8jRHvzxFTg(LPkiRA04jHqW*g#$R))c=w!nvtRA|w;g##Gjx;_qC?Gje(QI2oX^S9 zJaFR&&zmnX=8`_sf-kIib!XMD3y0s$nDnIah!K;Txqv0poU>c3&90T4Iyv2)&w}+% z>4w)QnIC*#!aYrTW8hN;eVt+l4ub{_R|{dm2R=air>$Nvg`hdyo*-=`6e@&L%vFWICHyS>WI-5kagUJ$H(!UNo9CT#~ns7?q8ea!$Q6W>L!OtZ@eS3Ve(D8_ElxY#SZf~ z2X;v~tX|ro`{!NPkFd)TlPw)Wr#C)r+GpbZhIvkBP>b=jqdNo=7osevO{FhTL5(w~s6C(ih=% z3!Ts4FZ5SR^d!@YSLF}t9OKg_?XbQDiYOquCKntlF!Ay|VB)n~8ko%#^R;Y&nIWsC zFp~uwDF@pXW~6VZKJJp;Y8D()`Y4^}pkqUVIZ)YWaTBEtOhtO}8o=Dk;OXk;vd$@? F2>^cBxyk?l literal 0 HcmV?d00001 diff --git a/res/layout/activity_edit_account.xml b/res/layout/activity_edit_account.xml index 04f63795a..0f4bae977 100644 --- a/res/layout/activity_edit_account.xml +++ b/res/layout/activity_edit_account.xml @@ -180,13 +180,35 @@ android:textSize="?attr/TextSizeHeadline" android:textStyle="bold" /> - + android:layout_height="match_parent" + android:layout_marginTop="8dp"> + + + + + + + @@ -226,4 +248,4 @@ android:textColor="@color/secondarytext" /> - \ No newline at end of file + diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 0c230ec64..6f21a71f5 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -261,5 +261,6 @@ Sonstiges Konferenz-Name Konferenz-Thema statt Raum-JID als Name verwenden + OTR Fingerabdruck in die Zwischenablage kopiert! diff --git a/res/values/strings.xml b/res/values/strings.xml index 8d976dcef..b6e5e15c3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -261,5 +261,6 @@ Other Conference name Use room’s subject instead of JID to identify conferences + OTR fingerprint copied to clipboard! - \ No newline at end of file + diff --git a/src/eu/siacs/conversations/ui/EditAccountActivity.java b/src/eu/siacs/conversations/ui/EditAccountActivity.java index bc9461159..9aa8a9b4b 100644 --- a/src/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/eu/siacs/conversations/ui/EditAccountActivity.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.ui; import android.app.PendingIntent; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -10,9 +12,11 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.TextView; +import android.widget.Toast; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; @@ -38,6 +42,7 @@ public class EditAccountActivity extends XmppActivity { private TextView mSessionEst; private TextView mOtrFingerprint; private TextView mOtrFingerprintHeadline; + private ImageButton mOtrFingerprintToClipboardButton; private String jidToEdit; private Account mAccount; @@ -228,6 +233,7 @@ public class EditAccountActivity extends XmppActivity { this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep); this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint); this.mOtrFingerprintHeadline = (TextView) findViewById(R.id.otr_fingerprint_headline); + this.mOtrFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_to_clipboard); this.mSaveButton = (Button) findViewById(R.id.save_button); this.mCancelButton = (Button) findViewById(R.id.cancel_button); this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener); @@ -324,13 +330,29 @@ public class EditAccountActivity extends XmppActivity { } else { this.mServerInfoPep.setText(R.string.server_info_unavailable); } - String fingerprint = this.mAccount + final String fingerprint = this.mAccount .getOtrFingerprint(xmppConnectionService); if (fingerprint != null) { this.mOtrFingerprintHeadline.setVisibility(View.VISIBLE); this.mOtrFingerprint.setVisibility(View.VISIBLE); this.mOtrFingerprint.setText(fingerprint); + this.mOtrFingerprintToClipboardButton.setVisibility(View.VISIBLE); + this.mOtrFingerprintToClipboardButton + .setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + + if (OtrFingerprintToClipBoard(fingerprint)) { + Toast.makeText( + EditAccountActivity.this, + R.string.toast_message_otr_fingerprint, + Toast.LENGTH_SHORT).show(); + } + } + }); } else { + this.mOtrFingerprintToClipboardButton.setVisibility(View.GONE); this.mOtrFingerprint.setVisibility(View.GONE); this.mOtrFingerprintHeadline.setVisibility(View.GONE); } @@ -343,4 +365,15 @@ public class EditAccountActivity extends XmppActivity { this.mStats.setVisibility(View.GONE); } } + + private boolean OtrFingerprintToClipBoard(String fingerprint) { + ClipboardManager mClipBoardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + String label = getResources().getString(R.string.otr_fingerprint); + if (mClipBoardManager != null) { + ClipData mClipData = ClipData.newPlainText(label, fingerprint); + mClipBoardManager.setPrimaryClip(mClipData); + return true; + } + return false; + } } From 131f2aad76a968814fe10c06a055d6526b30e70f Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 16:33:45 +0200 Subject: [PATCH 29/57] minor graphic tweaks in copy otr fingerprint to clipboard --- res/layout/activity_edit_account.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/res/layout/activity_edit_account.xml b/res/layout/activity_edit_account.xml index 0f4bae977..04e176c0d 100644 --- a/res/layout/activity_edit_account.xml +++ b/res/layout/activity_edit_account.xml @@ -189,7 +189,8 @@ android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/action_copy_to_clipboard" - android:orientation="vertical" > + android:orientation="vertical" + android:layout_centerVertical="true"> From 18409946c638269d2c0b0b3f74d9f9f7258d7962 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Fri, 3 Oct 2014 19:24:10 +0200 Subject: [PATCH 30/57] implemented ping (xep-0199) fixed #517 --- src/eu/siacs/conversations/parser/IqParser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/eu/siacs/conversations/parser/IqParser.java b/src/eu/siacs/conversations/parser/IqParser.java index 592b77a45..3cf76f602 100644 --- a/src/eu/siacs/conversations/parser/IqParser.java +++ b/src/eu/siacs/conversations/parser/IqParser.java @@ -73,6 +73,9 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { IqPacket response = mXmppConnectionService.getIqGenerator() .discoResponse(packet); account.getXmppConnection().sendIqPacket(response, null); + } else if (packet.hasChild("ping","urn:xmpp:ping")) { + IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT); + mXmppConnectionService.sendIqPacket(account, response, null); } else { if ((packet.getType() == IqPacket.TYPE_GET) || (packet.getType() == IqPacket.TYPE_SET)) { From 0929621b570e4867bb9f7094422fc57f77afb2f8 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 4 Oct 2014 14:31:44 +0200 Subject: [PATCH 31/57] minor ui tweak --- res/layout/activity_edit_account.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/res/layout/activity_edit_account.xml b/res/layout/activity_edit_account.xml index 04e176c0d..91bda7b10 100644 --- a/res/layout/activity_edit_account.xml +++ b/res/layout/activity_edit_account.xml @@ -202,12 +202,13 @@ From 79315bdd6136b3c45629c5281437bc9d223c1011 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 4 Oct 2014 14:32:11 +0200 Subject: [PATCH 32/57] reset pending subscription request --- src/eu/siacs/conversations/entities/Contact.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eu/siacs/conversations/entities/Contact.java b/src/eu/siacs/conversations/entities/Contact.java index dfd6c0592..b1ebe6623 100644 --- a/src/eu/siacs/conversations/entities/Contact.java +++ b/src/eu/siacs/conversations/entities/Contact.java @@ -156,6 +156,7 @@ public class Contact implements ListItem { public void clearPresences() { this.presences.clearPresences(); + this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST); } public int getMostAvailableStatus() { From d5e62ffe89065e7e182f0c331eb730964f493cfa Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 4 Oct 2014 14:32:51 +0200 Subject: [PATCH 33/57] added missing status messages after message scroll --- src/eu/siacs/conversations/ui/ConversationFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 86e5257ac..c324eb320 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -170,6 +170,7 @@ public class ConversationFragment extends Fragment { conversation, timestamp); messageList.clear(); messageList.addAll(conversation.getMessages()); + updateStatusMessages(); messageListAdapter.notifyDataSetChanged(); if (size != 0) { messagesLoaded = true; From 5371dd025a3c3b341c061d59f3c3d66cb07c0a2c Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sat, 4 Oct 2014 14:33:14 +0200 Subject: [PATCH 34/57] no dns retry after nosrv error --- src/eu/siacs/conversations/utils/DNSHelper.java | 7 ++----- src/eu/siacs/conversations/xmpp/XmppConnection.java | 6 +++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java index fd3b19534..3952ad049 100644 --- a/src/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/eu/siacs/conversations/utils/DNSHelper.java @@ -30,17 +30,16 @@ public class DNSHelper { String dns[] = client.findDNS(); if (dns != null) { - // we have a list of DNS servers, let's go for (String dnsserver : dns) { InetAddress ip = InetAddress.getByName(dnsserver); Bundle b = queryDNS(host, ip); if (b.containsKey("name")) { return b; + } else if (b.containsKey("error") && "nosrv".equals(b.getString("error", null))) { + return b; } } } - - // fallback return queryDNS(host, InetAddress.getByName("8.8.8.8")); } @@ -164,10 +163,8 @@ public class DNSHelper { } } catch (SocketTimeoutException e) { - Log.d(Config.LOGTAG, "timeout during dns"); namePort.putString("error", "timeout"); } catch (Exception e) { - Log.d(Config.LOGTAG, "unhandled exception in sub project"); namePort.putString("error", "unhandled"); } return namePort; diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index b055e35a3..76cfa6037 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -166,8 +166,12 @@ public class XmppConnection implements Runnable { + ":" + srvRecordPort); socket = new Socket(srvRecordServer, srvRecordPort); } - } else { + } else if (namePort.containsKey("error") && "nosrv".equals(namePort.getString("error", null))) { socket = new Socket(account.getServer(), 5222); + } else { + Log.d(Config.LOGTAG,account.getJid()+": timeout in DNS resolution"); + changeStatus(Account.STATUS_OFFLINE); + return; } OutputStream out = socket.getOutputStream(); tagWriter.setOutputStream(out); From 5250ef536fe3f5abffd87fe25981aa0bcd85115b Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 4 Oct 2014 18:32:05 +0200 Subject: [PATCH 35/57] fixed an 'activity has leaked window' --- src/eu/siacs/conversations/ui/StartConversationActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index 1a5fba959..830bf2526 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -359,8 +359,8 @@ public class StartConversationActivity extends XmppActivity { jid.setError(getString(R.string.contact_already_exists)); } else { xmppConnectionService.createContact(contact); - switchToConversation(contact); dialog.dismiss(); + switchToConversation(contact); } } else { jid.setError(getString(R.string.invalid_jid)); @@ -421,6 +421,7 @@ public class StartConversationActivity extends XmppActivity { xmppConnectionService .joinMuc(conversation); } + dialog.dismiss(); switchToConversation(conversation); } } else { @@ -430,6 +431,7 @@ public class StartConversationActivity extends XmppActivity { if (!conversation.getMucOptions().online()) { xmppConnectionService.joinMuc(conversation); } + dialog.dismiss(); switchToConversation(conversation); } } else { From 45bd0449fb7f9fa8d09b2556a6cb2c8ff3c79d1e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 10:46:31 +0200 Subject: [PATCH 36/57] sending initial ping before going online after login/resume to ensure that all presences and messages have been loaded --- .../conversations/xmpp/XmppConnection.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 76cfa6037..07cd2b45c 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -311,7 +311,8 @@ public class XmppConnection implements Runnable { } catch (NumberFormatException e) { } - changeStatus(Account.STATUS_ONLINE); + sendInitialPing(); + } else if (nextTag.isStart("r")) { tagReader.readElement(nextTag); AckPacket ack = new AckPacket(this.stanzasReceived, smVersion); @@ -351,6 +352,21 @@ public class XmppConnection implements Runnable { } } } + + private void sendInitialPing() { + Log.d(Config.LOGTAG,account.getJid()+": sending intial ping"); + IqPacket iq = new IqPacket(IqPacket.TYPE_GET); + iq.setFrom(account.getFullJid()); + iq.addChild("ping", "urn:xmpp:ping"); + this.sendIqPacket(iq, new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Log.d(Config.LOGTAG,account.getJid()+": online with resource "+account.getResource()); + changeStatus(Account.STATUS_ONLINE); + } + }); + } private Element processPacket(Tag currentTag, int packetType) throws XmlPullParserException, IOException { @@ -681,7 +697,7 @@ public class XmppConnection implements Runnable { if (bindListener != null) { bindListener.onBind(account); } - changeStatus(Account.STATUS_ONLINE); + sendInitialPing(); } else { disconnect(true); } From 26ce62f3656f6660bf8a9a5f07f7da4a8d8c5b5e Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 11:14:50 +0200 Subject: [PATCH 37/57] end otr session instead of only resetting --- src/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index e09dd0c5b..187526590 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -73,7 +73,7 @@ public class MessageParser extends AbstractParser implements updateLastseen(packet, account, true); String body = packet.getBody(); if (body.matches("^\\?OTRv\\d*\\?")) { - conversation.resetOtrSession(); + conversation.endOtrIfNeeded(); } if (!conversation.hasValidOtrSession()) { if (properlyAddressed) { From 4a260baa1223c691e3c2909d7a4c975d0c5a3225 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 12:05:27 +0200 Subject: [PATCH 38/57] fixed #510 --- .../conversations/ui/EditAccountActivity.java | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/ui/EditAccountActivity.java b/src/eu/siacs/conversations/ui/EditAccountActivity.java index 9aa8a9b4b..0ec385470 100644 --- a/src/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/eu/siacs/conversations/ui/EditAccountActivity.java @@ -5,6 +5,8 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Intent; import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; import android.widget.AutoCompleteTextView; @@ -53,6 +55,12 @@ public class EditAccountActivity extends XmppActivity { @Override public void onClick(View v) { + if (mAccount != null + && mAccount.getStatus() == Account.STATUS_DISABLED) { + mAccount.setOption(Account.OPTION_DISABLED, false); + xmppConnectionService.updateAccount(mAccount); + return; + } if (!Validator.isValidJid(mAccountJid.getText().toString())) { mAccountJid.setError(getString(R.string.invalid_jid)); mAccountJid.requestFocus(); @@ -162,6 +170,25 @@ public class EditAccountActivity extends XmppActivity { } }; private KnownHostsAdapter mKnownHostsAdapter; + private TextWatcher mTextWatcher = new TextWatcher() { + + @Override + public void onTextChanged(CharSequence s, int start, int before, + int count) { + updateSaveButton(); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + + } + + @Override + public void afterTextChanged(Editable s) { + + } + }; protected void finishInitialSetup(final Avatar avatar) { runOnUiThread(new Runnable() { @@ -202,6 +229,11 @@ public class EditAccountActivity extends XmppActivity { this.mSaveButton.setEnabled(false); this.mSaveButton.setTextColor(getSecondaryTextColor()); this.mSaveButton.setText(R.string.account_status_connecting); + } else if (mAccount != null + && mAccount.getStatus() == Account.STATUS_DISABLED) { + this.mSaveButton.setEnabled(true); + this.mSaveButton.setTextColor(getPrimaryTextColor()); + this.mSaveButton.setText(R.string.enable); } else { this.mSaveButton.setEnabled(true); this.mSaveButton.setTextColor(getPrimaryTextColor()); @@ -209,6 +241,10 @@ public class EditAccountActivity extends XmppActivity { if (mAccount != null && mAccount.getStatus() == Account.STATUS_ONLINE) { this.mSaveButton.setText(R.string.save); + if (!accountInfoEdited()) { + this.mSaveButton.setEnabled(false); + this.mSaveButton.setTextColor(getSecondaryTextColor()); + } } else { this.mSaveButton.setText(R.string.connect); } @@ -218,12 +254,21 @@ public class EditAccountActivity extends XmppActivity { } } + protected boolean accountInfoEdited() { + return (!this.mAccount.getJid().equals( + this.mAccountJid.getText().toString())) + || (!this.mAccount.getPassword().equals( + this.mPassword.getText().toString())); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_edit_account); this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid); + this.mAccountJid.addTextChangedListener(this.mTextWatcher); this.mPassword = (EditText) findViewById(R.id.account_password); + this.mPassword.addTextChangedListener(this.mTextWatcher); this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm); this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new); this.mStats = (LinearLayout) findViewById(R.id.stats); @@ -261,7 +306,7 @@ public class EditAccountActivity extends XmppActivity { this.jidToEdit = getIntent().getStringExtra("jid"); if (this.jidToEdit != null) { this.mRegisterNew.setVisibility(View.GONE); - getActionBar().setTitle(R.string.mgmt_account_edit); + getActionBar().setTitle(jidToEdit); } else { getActionBar().setTitle(R.string.action_add_account); } @@ -336,7 +381,8 @@ public class EditAccountActivity extends XmppActivity { this.mOtrFingerprintHeadline.setVisibility(View.VISIBLE); this.mOtrFingerprint.setVisibility(View.VISIBLE); this.mOtrFingerprint.setText(fingerprint); - this.mOtrFingerprintToClipboardButton.setVisibility(View.VISIBLE); + this.mOtrFingerprintToClipboardButton + .setVisibility(View.VISIBLE); this.mOtrFingerprintToClipboardButton .setOnClickListener(new View.OnClickListener() { From 54e9235bfcbfc22250bd9a14eb8575003856b91d Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 5 Oct 2014 12:31:49 +0200 Subject: [PATCH 39/57] MUC: differentiated a few more errors. --- res/values-de/strings.xml | 3 +++ res/values/strings.xml | 3 +++ .../conversations/entities/MucOptions.java | 23 +++++++++++++++++++ .../ui/ConversationFragment.java | 14 ++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 6f21a71f5..72121774b 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -262,5 +262,8 @@ Konferenz-Name Konferenz-Thema statt Raum-JID als Name verwenden OTR Fingerabdruck in die Zwischenablage kopiert! + Du wurdest aus dem Konferenzraum verbannt + Der Konferenzraum ist nur für Mitglieder + Du wurdest aus dem Konferenzraum geworfen diff --git a/res/values/strings.xml b/res/values/strings.xml index b6e5e15c3..089a678b1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -262,5 +262,8 @@ Conference name Use room’s subject instead of JID to identify conferences OTR fingerprint copied to clipboard! + You were been banned from the conference room + The conference room is only for members + You were been kicked from the conference room diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java index 0294c8aae..595d9058a 100644 --- a/src/eu/siacs/conversations/entities/MucOptions.java +++ b/src/eu/siacs/conversations/entities/MucOptions.java @@ -15,6 +15,13 @@ public class MucOptions { public static final int ERROR_NICK_IN_USE = 1; public static final int ERROR_ROOM_NOT_FOUND = 2; public static final int ERROR_PASSWORD_REQUIRED = 3; + public static final int ERROR_BANNED = 4; + public static final int ERROR_MEMBERS_ONLY = 5; + + public static final int KICKED_FROM_ROOM = 9; + + public static final String STATUS_CODE_BANNED = "301"; + public static final String STATUS_CODE_KICKED = "307"; public interface OnRenameListener { public void onRename(boolean success); @@ -179,6 +186,18 @@ public class MucOptions { x.getContent())); } } + } else if (type.equals("unavailable") && name.equals(this.joinnick)) { + Element status = packet.findChild("x", + "http://jabber.org/protocol/muc#user").findChild( + "status"); + String code = status.getAttribute("code"); + if (code.equals(STATUS_CODE_KICKED)) { + this.isOnline = false; + this.error = KICKED_FROM_ROOM; + } else if (code.equals(STATUS_CODE_BANNED)) { + this.isOnline = false; + this.error = ERROR_BANNED; + } } else if (type.equals("unavailable")) { deleteUser(packet.getAttribute("from").split("/", 2)[1]); } else if (type.equals("error")) { @@ -199,6 +218,10 @@ public class MucOptions { this.passwordChanged = true; } this.error = ERROR_PASSWORD_REQUIRED; + } else if (error.hasChild("forbidden")) { + this.error = ERROR_BANNED; + } else if (error.hasChild("registration-required")) { + this.error = ERROR_MEMBERS_ONLY; } } } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index c324eb320..2fa6b4544 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -485,6 +485,18 @@ public class ConversationFragment extends Fragment { showSnackbar(R.string.conference_requires_password, R.string.enter_password, enterPassword); break; + case MucOptions.ERROR_BANNED: + showSnackbar(R.string.conference_banned, + R.string.leave, leaveMuc); + break; + case MucOptions.ERROR_MEMBERS_ONLY: + showSnackbar(R.string.conference_members_only, + R.string.leave, leaveMuc); + break; + case MucOptions.KICKED_FROM_ROOM: + showSnackbar(R.string.conference_kicked, + R.string.leave, leaveMuc); + break; default: break; } @@ -493,7 +505,7 @@ public class ConversationFragment extends Fragment { getActivity().invalidateOptionsMenu(); updateChatMsgHint(); if (!activity.shouldPaneBeOpen()) { - activity.xmppConnectionService.markRead(conversation,true); + activity.xmppConnectionService.markRead(conversation, true); activity.updateConversationList(); } this.updateSendButton(); From ddb76b0e7373cfc876a88520fbcf7667088a6316 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 14:05:46 +0200 Subject: [PATCH 40/57] fixed rare npe --- src/eu/siacs/conversations/ui/StartConversationActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index 830bf2526..782183603 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -403,6 +403,10 @@ public class StartConversationActivity extends XmppActivity { String conferenceJid = jid.getText().toString(); Account account = xmppConnectionService .findAccountByJid(accountJid); + if (account==null) { + dialog.dismiss(); + return; + } if (bookmarkCheckBox.isChecked()) { if (account.hasBookmarkFor(conferenceJid)) { jid.setError(getString(R.string.bookmark_already_exists)); From b0574b289fce2a5d89f131829ea178e46b7d168b Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 14:06:25 +0200 Subject: [PATCH 41/57] made conversations overview list always 1/3 on tablet devices --- res/layout-w960dp/fragment_conversations_overview.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/res/layout-w960dp/fragment_conversations_overview.xml b/res/layout-w960dp/fragment_conversations_overview.xml index 5309674be..2744f38ef 100644 --- a/res/layout-w960dp/fragment_conversations_overview.xml +++ b/res/layout-w960dp/fragment_conversations_overview.xml @@ -2,11 +2,13 @@ android:id="@+id/content_view_ll" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="horizontal"> + android:orientation="horizontal" + android:baselineAligned="false"> @@ -21,7 +23,8 @@ From 6b3097ee27ff256afc22b93efec45d84caa2f53d Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Sun, 5 Oct 2014 14:26:06 +0200 Subject: [PATCH 42/57] only delivery get and set iq packets to unhandled iq listener. only create jingle packets with type=get or set --- .../conversations/xmpp/XmppConnection.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index 07cd2b45c..b789d95fc 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -166,10 +166,12 @@ public class XmppConnection implements Runnable { + ":" + srvRecordPort); socket = new Socket(srvRecordServer, srvRecordPort); } - } else if (namePort.containsKey("error") && "nosrv".equals(namePort.getString("error", null))) { + } else if (namePort.containsKey("error") + && "nosrv".equals(namePort.getString("error", null))) { socket = new Socket(account.getServer(), 5222); } else { - Log.d(Config.LOGTAG,account.getJid()+": timeout in DNS resolution"); + Log.d(Config.LOGTAG, account.getJid() + + ": timeout in DNS resolution"); changeStatus(Account.STATUS_OFFLINE); return; } @@ -312,7 +314,7 @@ public class XmppConnection implements Runnable { } sendInitialPing(); - + } else if (nextTag.isStart("r")) { tagReader.readElement(nextTag); AckPacket ack = new AckPacket(this.stanzasReceived, smVersion); @@ -352,17 +354,18 @@ public class XmppConnection implements Runnable { } } } - + private void sendInitialPing() { - Log.d(Config.LOGTAG,account.getJid()+": sending intial ping"); + Log.d(Config.LOGTAG, account.getJid() + ": sending intial ping"); IqPacket iq = new IqPacket(IqPacket.TYPE_GET); iq.setFrom(account.getFullJid()); iq.addChild("ping", "urn:xmpp:ping"); this.sendIqPacket(iq, new OnIqPacketReceived() { - + @Override public void onIqPacketReceived(Account account, IqPacket packet) { - Log.d(Config.LOGTAG,account.getJid()+": online with resource "+account.getResource()); + Log.d(Config.LOGTAG, account.getJid() + + ": online with resource " + account.getResource()); changeStatus(Account.STATUS_ONLINE); } }); @@ -392,8 +395,11 @@ public class XmppConnection implements Runnable { while (!nextTag.isEnd(element.getName())) { if (!nextTag.isNo()) { Element child = tagReader.readElement(nextTag); - if ((packetType == PACKET_IQ) - && ("jingle".equals(child.getName()))) { + String type = currentTag.getAttribute("type"); + if (packetType == PACKET_IQ + && "jingle".equals(child.getName()) + && ("set".equalsIgnoreCase(type) || "get" + .equalsIgnoreCase(type))) { element = new JinglePacket(); element.setAttributes(currentTag.getAttributes()); } @@ -430,7 +436,9 @@ public class XmppConnection implements Runnable { } packetCallbacks.remove(packet.getId()); - } else if (this.unregisteredIqListener != null) { + } else if ((packet.getType() == IqPacket.TYPE_GET || packet + .getType() == IqPacket.TYPE_SET) + && this.unregisteredIqListener != null) { this.unregisteredIqListener.onIqPacketReceived(account, packet); } } From b788b84c31bc53feb659e1af4dcaad98396c2de7 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 6 Oct 2014 00:33:52 +0200 Subject: [PATCH 43/57] refactored muc bookmark to extend element. keep all elements the server or other clients added before --- .../conversations/entities/Bookmark.java | 115 ++++++++---------- .../conversations/entities/MucOptions.java | 11 +- .../siacs/conversations/parser/IqParser.java | 2 +- .../services/XmppConnectionService.java | 9 +- .../ui/ConversationActivity.java | 21 ++-- .../ui/StartConversationActivity.java | 2 +- .../siacs/conversations/ui/XmppActivity.java | 5 +- .../ui/adapter/ConversationAdapter.java | 3 +- .../siacs/conversations/utils/DNSHelper.java | 3 +- 9 files changed, 78 insertions(+), 93 deletions(-) diff --git a/src/eu/siacs/conversations/entities/Bookmark.java b/src/eu/siacs/conversations/entities/Bookmark.java index 14f010e79..722fb6d98 100644 --- a/src/eu/siacs/conversations/entities/Bookmark.java +++ b/src/eu/siacs/conversations/entities/Bookmark.java @@ -7,46 +7,35 @@ import android.graphics.Bitmap; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xml.Element; -public class Bookmark implements ListItem { +public class Bookmark extends Element implements ListItem { private Account account; - private String jid; - private String nick; - private String name; - private String password; - private boolean autojoin; - private boolean providePassword; private Conversation mJoinedConversation; public Bookmark(Account account, String jid) { + super("conference"); + this.setAttribute("jid", jid); + this.account = account; + } + + private Bookmark(Account account) { + super("conference"); this.account = account; - this.jid = jid; } public static Bookmark parse(Element element, Account account) { - Bookmark bookmark = new Bookmark(account, element.getAttribute("jid")); - bookmark.setName(element.getAttribute("name")); - String autojoin = element.getAttribute("autojoin"); - if (autojoin != null - && (autojoin.equals("true") || autojoin.equals("1"))) { - bookmark.setAutojoin(true); - } else { - bookmark.setAutojoin(false); - } - Element nick = element.findChild("nick"); - if (nick != null) { - bookmark.setNick(nick.getContent()); - } - Element password = element.findChild("password"); - if (password != null) { - bookmark.setPassword(password.getContent()); - bookmark.setProvidePassword(true); - } + Bookmark bookmark = new Bookmark(account); + bookmark.setAttributes(element.getAttributes()); + bookmark.setChildren(element.getChildren()); return bookmark; } public void setAutojoin(boolean autojoin) { - this.autojoin = autojoin; + if (autojoin) { + this.setAttribute("autojoin", "true"); + } else { + this.setAttribute("autojoin", "false"); + } } public void setName(String name) { @@ -54,15 +43,18 @@ public class Bookmark implements ListItem { } public void setNick(String nick) { - this.nick = nick; + Element element = this.findChild("nick"); + if (element == null) { + element = this.addChild("nick"); + } + element.setContent(nick); } public void setPassword(String password) { - this.password = password; - } - - private void setProvidePassword(boolean providePassword) { - this.providePassword = providePassword; + Element element = this.findChild("password"); + if (element != null) { + element.setContent(password); + } } @Override @@ -76,32 +68,45 @@ public class Bookmark implements ListItem { if (this.mJoinedConversation != null && (this.mJoinedConversation.getMucOptions().getSubject() != null)) { return this.mJoinedConversation.getMucOptions().getSubject(); - } else if (name != null) { - return name; + } else if (getName() != null) { + return getName(); } else { - return this.jid.split("@")[0]; + return this.getJid().split("@")[0]; } } @Override public String getJid() { - return this.jid.toLowerCase(Locale.US); + String jid = this.getAttribute("jid"); + if (jid != null) { + return jid.toLowerCase(Locale.US); + } else { + return null; + } } public String getNick() { - return this.nick; + Element nick = this.findChild("nick"); + if (nick != null) { + return nick.getContent(); + } else { + return null; + } } public boolean autojoin() { - return autojoin; + String autojoin = this.getAttribute("autojoin"); + return (autojoin != null && (autojoin.equalsIgnoreCase("true") || autojoin + .equalsIgnoreCase("1"))); } public String getPassword() { - return this.password; - } - - public boolean isProvidePassword() { - return this.providePassword; + Element password = this.findChild("password"); + if (password != null) { + return password.getContent(); + } else { + return null; + } } public boolean match(String needle) { @@ -131,27 +136,7 @@ public class Bookmark implements ListItem { } public String getName() { - return name; - } - - public Element toElement() { - Element element = new Element("conference"); - element.setAttribute("jid", this.getJid()); - if (this.getName() != null) { - element.setAttribute("name", this.getName()); - } - if (this.autojoin) { - element.setAttribute("autojoin", "true"); - } else { - element.setAttribute("autojoin", "false"); - } - if (this.nick != null) { - element.addChild("nick").setContent(this.nick); - } - if (this.password != null && isProvidePassword()) { - element.addChild("password").setContent(this.password); - } - return element; + return this.getAttribute("name"); } public void unregisterConversation() { diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java index 595d9058a..a9d568486 100644 --- a/src/eu/siacs/conversations/entities/MucOptions.java +++ b/src/eu/siacs/conversations/entities/MucOptions.java @@ -165,8 +165,7 @@ public class MucOptions { } aboutToRename = false; } - if (conversation.getBookmark() != null - && conversation.getBookmark().isProvidePassword()) { + if (conversation.getBookmark() != null) { this.passwordChanged = false; } } else { @@ -213,8 +212,7 @@ public class MucOptions { this.error = ERROR_NICK_IN_USE; } } else if (error.hasChild("not-authorized")) { - if (conversation.getBookmark() != null - && conversation.getBookmark().isProvidePassword()) { + if (conversation.getBookmark() != null) { this.passwordChanged = true; } this.error = ERROR_PASSWORD_REQUIRED; @@ -357,8 +355,7 @@ public class MucOptions { } public void setPassword(String password) { - if (conversation.getBookmark() != null - && conversation.getBookmark().isProvidePassword()) { + if (conversation.getBookmark() != null) { conversation.getBookmark().setPassword(password); } else { this.password = password; @@ -367,7 +364,7 @@ public class MucOptions { .setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); } - public boolean isPasswordChanged() { + public boolean isPasswordChanged2() { return this.passwordChanged; } diff --git a/src/eu/siacs/conversations/parser/IqParser.java b/src/eu/siacs/conversations/parser/IqParser.java index 3cf76f602..df6754f26 100644 --- a/src/eu/siacs/conversations/parser/IqParser.java +++ b/src/eu/siacs/conversations/parser/IqParser.java @@ -73,7 +73,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { IqPacket response = mXmppConnectionService.getIqGenerator() .discoResponse(packet); account.getXmppConnection().sendIqPacket(response, null); - } else if (packet.hasChild("ping","urn:xmpp:ping")) { + } else if (packet.hasChild("ping", "urn:xmpp:ping")) { IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT); mXmppConnectionService.sendIqPacket(account, response, null); } else { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 557a625b0..073bcdc50 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -748,7 +748,7 @@ public class XmppConnectionService extends Service { Element query = iqPacket.query("jabber:iq:private"); Element storage = query.addChild("storage", "storage:bookmarks"); for (Bookmark bookmark : account.getBookmarks()) { - storage.addChild(bookmark.toElement()); + storage.addChild(bookmark); } sendIqPacket(account, iqPacket, null); } @@ -1120,11 +1120,8 @@ public class XmppConnectionService extends Service { public void providePasswordForMuc(Conversation conversation, String password) { if (conversation.getMode() == Conversation.MODE_MULTI) { conversation.getMucOptions().setPassword(password); - if (conversation.getBookmark() != null - && conversation.getMucOptions().isPasswordChanged()) { - if (!conversation.getBookmark().autojoin()) { - conversation.getBookmark().setAutojoin(true); - } + if (conversation.getBookmark() != null) { + conversation.getBookmark().setAutojoin(true); pushBookmarks(conversation.getAccount()); } databaseBackend.updateConversation(conversation); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 04af0e845..1f2747f78 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -88,7 +88,7 @@ public class ConversationActivity extends XmppActivity implements } public void setSelectedConversation(Conversation conversation) { - this.selectedConversation = conversation; + this.selectedConversation = conversation; } public ListView getConversationListView() { @@ -98,21 +98,21 @@ public class ConversationActivity extends XmppActivity implements public boolean shouldPaneBeOpen() { return paneShouldBeOpen; } - + public void showConversationsOverview() { if (mContentView instanceof SlidingPaneLayout) { SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; mSlidingPaneLayout.openPane(); } } - + public void hideConversationsOverview() { if (mContentView instanceof SlidingPaneLayout) { SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; mSlidingPaneLayout.closePane(); } } - + public boolean isConversationsOverviewHideable() { if (mContentView instanceof SlidingPaneLayout) { SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; @@ -121,7 +121,7 @@ public class ConversationActivity extends XmppActivity implements return false; } } - + public boolean isConversationsOverviewVisable() { if (mContentView instanceof SlidingPaneLayout) { SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; @@ -166,13 +166,14 @@ public class ConversationActivity extends XmppActivity implements } }); mContentView = findViewById(R.id.content_view_spl); - if (mContentView==null) { + if (mContentView == null) { mContentView = findViewById(R.id.content_view_ll); } if (mContentView instanceof SlidingPaneLayout) { SlidingPaneLayout mSlidingPaneLayout = (SlidingPaneLayout) mContentView; mSlidingPaneLayout.setParallaxDistance(150); - mSlidingPaneLayout.setShadowResource(R.drawable.es_slidingpane_shadow); + mSlidingPaneLayout + .setShadowResource(R.drawable.es_slidingpane_shadow); mSlidingPaneLayout.setSliderFadeColor(0); mSlidingPaneLayout.setPanelSlideListener(new PanelSlideListener() { @@ -253,7 +254,8 @@ public class ConversationActivity extends XmppActivity implements .findItem(R.id.action_invite); MenuItem menuMute = (MenuItem) menu.findItem(R.id.action_mute); - if (isConversationsOverviewVisable() && isConversationsOverviewHideable()) { + if (isConversationsOverviewVisable() + && isConversationsOverviewHideable()) { menuArchive.setVisible(false); menuMucDetails.setVisible(false); menuContactDetails.setVisible(false); @@ -669,7 +671,8 @@ public class ConversationActivity extends XmppActivity implements public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putString(STATE_OPEN_CONVERSATION, getSelectedConversation().getUuid()); - savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable()); + savedInstanceState.putBoolean(STATE_PANEL_OPEN, + isConversationsOverviewVisable()); super.onSaveInstanceState(savedInstanceState); } diff --git a/src/eu/siacs/conversations/ui/StartConversationActivity.java b/src/eu/siacs/conversations/ui/StartConversationActivity.java index 782183603..a1a2d4c2a 100644 --- a/src/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/eu/siacs/conversations/ui/StartConversationActivity.java @@ -403,7 +403,7 @@ public class StartConversationActivity extends XmppActivity { String conferenceJid = jid.getText().toString(); Account account = xmppConnectionService .findAccountByJid(accountJid); - if (account==null) { + if (account == null) { dialog.dismiss(); return; } diff --git a/src/eu/siacs/conversations/ui/XmppActivity.java b/src/eu/siacs/conversations/ui/XmppActivity.java index 39ca623bb..cd77557c5 100644 --- a/src/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/eu/siacs/conversations/ui/XmppActivity.java @@ -208,7 +208,8 @@ public abstract class XmppActivity extends Activity { mColorOrange = getResources().getColor(R.color.orange); mColorGreen = getResources().getColor(R.color.green); mPrimaryColor = getResources().getColor(R.color.primary); - mSecondaryBackgroundColor = getResources().getColor(R.color.secondarybackground); + mSecondaryBackgroundColor = getResources().getColor( + R.color.secondarybackground); if (getPreferences().getBoolean("use_larger_font", false)) { setTheme(R.style.ConversationsTheme_LargerText); } @@ -520,7 +521,7 @@ public abstract class XmppActivity extends Activity { public int getPrimaryColor() { return this.mPrimaryColor; } - + public int getSecondaryBackgroundColor() { return this.mSecondaryBackgroundColor; } diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index 583772baf..f74856b07 100644 --- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -42,7 +42,8 @@ public class ConversationAdapter extends ArrayAdapter { ConversationActivity activity = (ConversationActivity) this.activity; if (!activity.isConversationsOverviewHideable()) { if (conv == activity.getSelectedConversation()) { - view.setBackgroundColor(activity.getSecondaryBackgroundColor()); + view.setBackgroundColor(activity + .getSecondaryBackgroundColor()); } else { view.setBackgroundColor(Color.TRANSPARENT); } diff --git a/src/eu/siacs/conversations/utils/DNSHelper.java b/src/eu/siacs/conversations/utils/DNSHelper.java index 3952ad049..c51a75ac6 100644 --- a/src/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/eu/siacs/conversations/utils/DNSHelper.java @@ -35,7 +35,8 @@ public class DNSHelper { Bundle b = queryDNS(host, ip); if (b.containsKey("name")) { return b; - } else if (b.containsKey("error") && "nosrv".equals(b.getString("error", null))) { + } else if (b.containsKey("error") + && "nosrv".equals(b.getString("error", null))) { return b; } } From 16d5429f803dfa6e76110dd83e8f04377358f839 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 6 Oct 2014 13:34:19 +0200 Subject: [PATCH 44/57] muc options clean up --- res/values/strings.xml | 6 +-- .../conversations/entities/MucOptions.java | 45 ++++++++----------- .../ui/ConversationFragment.java | 10 ++++- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 089a678b1..58af226b1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -262,8 +262,8 @@ Conference name Use room’s subject instead of JID to identify conferences OTR fingerprint copied to clipboard! - You were been banned from the conference room - The conference room is only for members - You were been kicked from the conference room + You are banned from this conference + This conference is members only + You have been kicked from this conference diff --git a/src/eu/siacs/conversations/entities/MucOptions.java b/src/eu/siacs/conversations/entities/MucOptions.java index a9d568486..12ea4e931 100644 --- a/src/eu/siacs/conversations/entities/MucOptions.java +++ b/src/eu/siacs/conversations/entities/MucOptions.java @@ -115,7 +115,6 @@ public class MucOptions { private String subject = null; private String joinnick; private String password = null; - private boolean passwordChanged = false; public MucOptions(Account account) { this.account = account; @@ -165,9 +164,6 @@ public class MucOptions { } aboutToRename = false; } - if (conversation.getBookmark() != null) { - this.passwordChanged = false; - } } else { addUser(user); } @@ -186,22 +182,26 @@ public class MucOptions { } } } else if (type.equals("unavailable") && name.equals(this.joinnick)) { - Element status = packet.findChild("x", - "http://jabber.org/protocol/muc#user").findChild( - "status"); - String code = status.getAttribute("code"); - if (code.equals(STATUS_CODE_KICKED)) { - this.isOnline = false; - this.error = KICKED_FROM_ROOM; - } else if (code.equals(STATUS_CODE_BANNED)) { - this.isOnline = false; - this.error = ERROR_BANNED; + Element x = packet.findChild("x", + "http://jabber.org/protocol/muc#user"); + if (x != null) { + Element status = x.findChild("status"); + if (status != null) { + String code = status.getAttribute("code"); + if (STATUS_CODE_KICKED.equals(code)) { + this.isOnline = false; + this.error = KICKED_FROM_ROOM; + } else if (STATUS_CODE_BANNED.equals(code)) { + this.isOnline = false; + this.error = ERROR_BANNED; + } + } } } else if (type.equals("unavailable")) { deleteUser(packet.getAttribute("from").split("/", 2)[1]); } else if (type.equals("error")) { Element error = packet.findChild("error"); - if (error.hasChild("conflict")) { + if (error != null && error.hasChild("conflict")) { if (aboutToRename) { if (renameListener != null) { renameListener.onRename(false); @@ -211,14 +211,12 @@ public class MucOptions { } else { this.error = ERROR_NICK_IN_USE; } - } else if (error.hasChild("not-authorized")) { - if (conversation.getBookmark() != null) { - this.passwordChanged = true; - } + } else if (error != null && error.hasChild("not-authorized")) { this.error = ERROR_PASSWORD_REQUIRED; - } else if (error.hasChild("forbidden")) { + } else if (error != null && error.hasChild("forbidden")) { this.error = ERROR_BANNED; - } else if (error.hasChild("registration-required")) { + } else if (error != null + && error.hasChild("registration-required")) { this.error = ERROR_MEMBERS_ONLY; } } @@ -363,9 +361,4 @@ public class MucOptions { conversation .setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); } - - public boolean isPasswordChanged2() { - return this.passwordChanged; - } - } \ No newline at end of file diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 2fa6b4544..716e299ef 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -131,6 +131,14 @@ public class ConversationFragment extends Fragment { activity.endConversation(conversation); } }; + + private OnClickListener joinMuc = new OnClickListener() { + + @Override + public void onClick(View v) { + activity.xmppConnectionService.joinMuc(conversation); + } + }; private OnClickListener enterPassword = new OnClickListener() { @@ -495,7 +503,7 @@ public class ConversationFragment extends Fragment { break; case MucOptions.KICKED_FROM_ROOM: showSnackbar(R.string.conference_kicked, - R.string.leave, leaveMuc); + R.string.join, joinMuc); break; default: break; From 0a93093bc7c0bbd2bf98da799a3d6724dae2bf02 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 6 Oct 2014 19:27:58 +0200 Subject: [PATCH 45/57] fixed npe --- src/eu/siacs/conversations/ui/ConversationActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 1f2747f78..f94d6b733 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -669,8 +669,11 @@ public class ConversationActivity extends XmppActivity implements @Override public void onSaveInstanceState(Bundle savedInstanceState) { - savedInstanceState.putString(STATE_OPEN_CONVERSATION, - getSelectedConversation().getUuid()); + Conversation conversation = getSelectedConversation(); + if (conversation!=null) { + savedInstanceState.putString(STATE_OPEN_CONVERSATION, + conversation.getUuid()); + } savedInstanceState.putBoolean(STATE_PANEL_OPEN, isConversationsOverviewVisable()); super.onSaveInstanceState(savedInstanceState); From 315731b0cf9b15a5e749a7ea35b8770e4dc94e74 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 6 Oct 2014 19:28:15 +0200 Subject: [PATCH 46/57] work around for message scroll bug --- res/layout/message_null.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/layout/message_null.xml b/res/layout/message_null.xml index 1e1485857..36eb860dd 100644 --- a/res/layout/message_null.xml +++ b/res/layout/message_null.xml @@ -1,6 +1,7 @@ + android:layout_height="0.1dp" + android:background="#00000000"> \ No newline at end of file From b6f5e4a217e3eaf6be94bc5efae41273d27944bc Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 6 Oct 2014 22:03:01 +0200 Subject: [PATCH 47/57] cleanung up the scroll fix a little --- res/layout/message_null.xml | 2 +- src/eu/siacs/conversations/ui/ConversationActivity.java | 2 +- src/eu/siacs/conversations/ui/ConversationFragment.java | 4 +--- src/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 7 +++++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/res/layout/message_null.xml b/res/layout/message_null.xml index 36eb860dd..0e0f1c924 100644 --- a/res/layout/message_null.xml +++ b/res/layout/message_null.xml @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index f94d6b733..6817a3865 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -670,7 +670,7 @@ public class ConversationActivity extends XmppActivity implements @Override public void onSaveInstanceState(Bundle savedInstanceState) { Conversation conversation = getSelectedConversation(); - if (conversation!=null) { + if (conversation != null) { savedInstanceState.putString(STATE_OPEN_CONVERSATION, conversation.getUuid()); } diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 716e299ef..928bb6f39 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -522,9 +522,7 @@ public class ConversationFragment extends Fragment { private void messageSent() { int size = this.messageList.size(); - if (size >= 1 && this.messagesView.getLastVisiblePosition() != size - 1) { - messagesView.setSelection(size - 1); - } + messagesView.setSelection(size - 1); mEditMessage.setText(""); updateChatMsgHint(); } diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 035d18c52..c8dd1f0e3 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -418,6 +418,13 @@ public class MessageAdapter extends ArrayAdapter { } if (type == STATUS || type == NULL) { + if (position == getCount() - 1) { + view.getLayoutParams().height = 1; + } else { + view.getLayoutParams().height = 0; + + } + view.setLayoutParams(view.getLayoutParams()); return view; } From 7f524352730edc630697c693a040ca570cbcedb3 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 7 Oct 2014 11:51:16 +0200 Subject: [PATCH 48/57] fixed regression of not showing status message --- src/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index c8dd1f0e3..25df83966 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -417,7 +417,10 @@ public class MessageAdapter extends ArrayAdapter { viewHolder = (ViewHolder) view.getTag(); } - if (type == STATUS || type == NULL) { + if (type == STATUS) { + return view; + } + if (type == NULL) { if (position == getCount() - 1) { view.getLayoutParams().height = 1; } else { From d5227e5c253658eb9d6bc1f7bf85397f072125d4 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 7 Oct 2014 13:37:50 +0200 Subject: [PATCH 49/57] refactored grace period --- src/eu/siacs/conversations/Config.java | 2 +- .../conversations/parser/MessageParser.java | 15 +++-------- .../conversations/parser/PresenceParser.java | 2 ++ .../services/NotificationService.java | 27 +++++++++++++++---- .../services/XmppConnectionService.java | 3 +++ 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/eu/siacs/conversations/Config.java b/src/eu/siacs/conversations/Config.java index 1725eca69..a11e17637 100644 --- a/src/eu/siacs/conversations/Config.java +++ b/src/eu/siacs/conversations/Config.java @@ -10,7 +10,7 @@ public final class Config { public static final int PING_MIN_INTERVAL = 30; public static final int PING_TIMEOUT = 10; public static final int CONNECT_TIMEOUT = 90; - public static final int CARBON_GRACE_PERIOD = 60; + public static final int CARBON_GRACE_PERIOD = 120; public static final int AVATAR_SIZE = 192; public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 187526590..8d5ca898f 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -1,10 +1,7 @@ package eu.siacs.conversations.parser; -import android.os.SystemClock; -import android.util.Log; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; -import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -19,9 +16,6 @@ import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public class MessageParser extends AbstractParser implements OnMessagePacketReceived { - - private long lastCarbonMessageReceived = -(Config.CARBON_GRACE_PERIOD * 1000); - public MessageParser(XmppConnectionService service) { super(service); } @@ -404,8 +398,6 @@ public class MessageParser extends AbstractParser implements Message message = null; boolean notify = mXmppConnectionService.getPreferences().getBoolean( "show_notification", true); - notify = notify - && (SystemClock.elapsedRealtime() - lastCarbonMessageReceived) > (Config.CARBON_GRACE_PERIOD * 1000); boolean alwaysNotifyInConference = notify && mXmppConnectionService.getPreferences().getBoolean( "always_notify_in_conference", false); @@ -431,8 +423,8 @@ public class MessageParser extends AbstractParser implements message = this.parseCarbonMessage(packet, account); if (message != null) { if (message.getStatus() == Message.STATUS_SEND) { - lastCarbonMessageReceived = SystemClock - .elapsedRealtime(); + mXmppConnectionService.getNotificationService() + .activateGracePeriod(); notify = false; mXmppConnectionService.markRead( message.getConversation(), false); @@ -454,7 +446,8 @@ public class MessageParser extends AbstractParser implements } else { mXmppConnectionService.markRead(message.getConversation(), false); - lastCarbonMessageReceived = SystemClock.elapsedRealtime(); + mXmppConnectionService.getNotificationService() + .activateGracePeriod(); notify = false; } } diff --git a/src/eu/siacs/conversations/parser/PresenceParser.java b/src/eu/siacs/conversations/parser/PresenceParser.java index 507ebbd2b..2c3a7dbcc 100644 --- a/src/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/eu/siacs/conversations/parser/PresenceParser.java @@ -58,6 +58,8 @@ public class PresenceParser extends AbstractParser implements Presences.parseShow(packet.findChild("show"))); } else if (type.equals("unavailable")) { account.removePresence(fromParts[1]); + mXmppConnectionService.getNotificationService() + .deactivateGracePeriod(); } } } else { diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 9428aa15a..53c4707f5 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -13,10 +13,12 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.PowerManager; +import android.os.SystemClock; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.text.Html; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -32,6 +34,8 @@ public class NotificationService { public int NOTIFICATION_ID = 0x2342; private Conversation mOpenConversation; private boolean mIsInForeground; + + private long mEndGracePeriod = 0L; public NotificationService(XmppConnectionService service) { this.mXmppConnectionService = service; @@ -44,10 +48,9 @@ public class NotificationService { PowerManager pm = (PowerManager) mXmppConnectionService .getSystemService(Context.POWER_SERVICE); boolean isScreenOn = pm.isScreenOn(); - if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { - return; // simply ignore + return; } String conversationUuid = message.getConversationUuid(); if (notifications.containsKey(conversationUuid)) { @@ -57,8 +60,8 @@ public class NotificationService { mList.add(message); notifications.put(conversationUuid, mList); } - updateNotification(!(this.mIsInForeground && this.mOpenConversation == null) - || !isScreenOn); + updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) + || !isScreenOn) && !inGracePeriod()); } public void clear() { @@ -161,7 +164,9 @@ public class NotificationService { } } mBuilder.setDeleteIntent(createDeleteIntent()); - mBuilder.setLights(0xffffffff, 2000, 4000); + if (!inGracePeriod()) { + mBuilder.setLights(0xffffffff, 2000, 4000); + } Notification notification = mBuilder.build(); mNotificationManager.notify(NOTIFICATION_ID, notification); } @@ -221,4 +226,16 @@ public class NotificationService { this.mIsInForeground = foreground; } + + public void activateGracePeriod() { + this.mEndGracePeriod = SystemClock.elapsedRealtime() + (Config.CARBON_GRACE_PERIOD * 1000); + } + + public void deactivateGracePeriod() { + this.mEndGracePeriod = 0L; + } + + private boolean inGracePeriod() { + return SystemClock.elapsedRealtime() < this.mEndGracePeriod; + } } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 073bcdc50..ca69b5309 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -970,6 +970,7 @@ public class XmppConnectionService extends Service { public void setOnConversationListChangedListener( OnConversationUpdate listener) { + this.mNotificationService.deactivateGracePeriod(); if (checkListeners()) { switchToForeground(); } @@ -990,6 +991,7 @@ public class XmppConnectionService extends Service { } public void setOnAccountListChangedListener(OnAccountUpdate listener) { + this.mNotificationService.deactivateGracePeriod(); if (checkListeners()) { switchToForeground(); } @@ -1008,6 +1010,7 @@ public class XmppConnectionService extends Service { } public void setOnRosterUpdateListener(OnRosterUpdate listener) { + this.mNotificationService.deactivateGracePeriod(); if (checkListeners()) { switchToForeground(); } From 919c98207bb317e2283084dcbaa34a5216997d85 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 7 Oct 2014 15:18:09 +0200 Subject: [PATCH 50/57] made disabled notifications permanent across restarts --- .../conversations/entities/Conversation.java | 23 +++++++++++++++---- .../services/NotificationService.java | 14 +++++------ .../ui/ConversationActivity.java | 2 ++ .../ui/ConversationFragment.java | 10 ++++---- .../ui/adapter/MessageAdapter.java | 2 +- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index fedb0893a..39e54a8f5 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -43,6 +43,7 @@ public class Conversation extends AbstractEntity { public static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; public static final String ATTRIBUTE_MUC_PASSWORD = "muc_password"; + public static final String ATTRIBUTE_MUTED_TILL = "muted_till"; private String name; private String contactUuid; @@ -54,8 +55,6 @@ public class Conversation extends AbstractEntity { private JSONObject attributes = new JSONObject(); - private long mutedTill = 0; - private String nextPresence; private transient CopyOnWriteArrayList messages = null; @@ -452,12 +451,13 @@ public class Conversation extends AbstractEntity { return false; } - public void setMutedTill(long mutedTill) { - this.mutedTill = mutedTill; + public void setMutedTill(long value) { + this.setAttribute(ATTRIBUTE_MUTED_TILL, String.valueOf(value)); } public boolean isMuted() { - return SystemClock.elapsedRealtime() < this.mutedTill; + return SystemClock.elapsedRealtime() < this.getLongAttribute( + ATTRIBUTE_MUTED_TILL, 0); } public boolean setAttribute(String key, String value) { @@ -489,4 +489,17 @@ public class Conversation extends AbstractEntity { } } } + + public long getLongAttribute(String key, long defaultValue) { + String value = this.getAttribute(key); + if (value == null) { + return defaultValue; + } else { + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + } } diff --git a/src/eu/siacs/conversations/services/NotificationService.java b/src/eu/siacs/conversations/services/NotificationService.java index 53c4707f5..416567071 100644 --- a/src/eu/siacs/conversations/services/NotificationService.java +++ b/src/eu/siacs/conversations/services/NotificationService.java @@ -34,7 +34,7 @@ public class NotificationService { public int NOTIFICATION_ID = 0x2342; private Conversation mOpenConversation; private boolean mIsInForeground; - + private long mEndGracePeriod = 0L; public NotificationService(XmppConnectionService service) { @@ -60,8 +60,8 @@ public class NotificationService { mList.add(message); notifications.put(conversationUuid, mList); } - updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) - || !isScreenOn) && !inGracePeriod()); + updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) + && !inGracePeriod()); } public void clear() { @@ -226,15 +226,15 @@ public class NotificationService { this.mIsInForeground = foreground; } - public void activateGracePeriod() { - this.mEndGracePeriod = SystemClock.elapsedRealtime() + (Config.CARBON_GRACE_PERIOD * 1000); + this.mEndGracePeriod = SystemClock.elapsedRealtime() + + (Config.CARBON_GRACE_PERIOD * 1000); } - + public void deactivateGracePeriod() { this.mEndGracePeriod = 0L; } - + private boolean inGracePeriod() { return SystemClock.elapsedRealtime() < this.mEndGracePeriod; } diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index 6817a3865..f3db8cb43 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -585,6 +585,8 @@ public class ConversationActivity extends XmppActivity implements + (durations[which] * 1000); } conversation.setMutedTill(till); + activity.xmppConnectionService.databaseBackend + .updateConversation(conversation); ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() .findFragmentByTag("conversation"); if (selectedFragment != null) { diff --git a/src/eu/siacs/conversations/ui/ConversationFragment.java b/src/eu/siacs/conversations/ui/ConversationFragment.java index 928bb6f39..cdaa71522 100644 --- a/src/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/eu/siacs/conversations/ui/ConversationFragment.java @@ -131,9 +131,9 @@ public class ConversationFragment extends Fragment { activity.endConversation(conversation); } }; - + private OnClickListener joinMuc = new OnClickListener() { - + @Override public void onClick(View v) { activity.xmppConnectionService.joinMuc(conversation); @@ -438,6 +438,8 @@ public class ConversationFragment extends Fragment { @Override public void onClick(View v) { conversation.setMutedTill(0); + activity.xmppConnectionService.databaseBackend + .updateConversation(conversation); updateMessages(); } }); @@ -502,8 +504,8 @@ public class ConversationFragment extends Fragment { R.string.leave, leaveMuc); break; case MucOptions.KICKED_FROM_ROOM: - showSnackbar(R.string.conference_kicked, - R.string.join, joinMuc); + showSnackbar(R.string.conference_kicked, R.string.join, + joinMuc); break; default: break; diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 25df83966..2671cf50d 100644 --- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -425,7 +425,7 @@ public class MessageAdapter extends ArrayAdapter { view.getLayoutParams().height = 1; } else { view.getLayoutParams().height = 0; - + } view.setLayoutParams(view.getLayoutParams()); return view; From 3737a96dbb517dc9d1e39d2b15cf8539cc752a45 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 7 Oct 2014 16:02:52 +0200 Subject: [PATCH 51/57] refactored read marker --- .../conversations/entities/Conversation.java | 23 ++++++++++--------- .../siacs/conversations/entities/Message.java | 6 ++--- .../conversations/parser/MessageParser.java | 18 +++++---------- .../services/XmppConnectionService.java | 5 ++-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 39e54a8f5..60afaa5de 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -68,7 +68,7 @@ public class Conversation extends AbstractEntity { private transient MucOptions mucOptions = null; - private transient String latestMarkableMessageId; + //private transient String latestMarkableMessageId; private byte[] symmetricKey; @@ -138,10 +138,17 @@ public class Conversation extends AbstractEntity { } } - public String popLatestMarkableMessageId() { - String id = this.latestMarkableMessageId; - this.latestMarkableMessageId = null; - return id; + public String getLatestMarkableMessageId() { + for(int i = this.messages.size() - 1; i >= 0; --i) { + if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED && this.messages.get(i).markable) { + if (this.messages.get(i).isRead()) { + return null; + } else { + return this.messages.get(i).getRemoteMsgId(); + } + } + } + return null; } public Message getLatestMessage() { @@ -405,12 +412,6 @@ public class Conversation extends AbstractEntity { this.nextMessage = message; } - public void setLatestMarkableMessageId(String id) { - if (id != null) { - this.latestMarkableMessageId = id; - } - } - public void setSymmetricKey(byte[] key) { this.symmetricKey = key; } diff --git a/src/eu/siacs/conversations/entities/Message.java b/src/eu/siacs/conversations/entities/Message.java index 8f9885c58..49482bbca 100644 --- a/src/eu/siacs/conversations/entities/Message.java +++ b/src/eu/siacs/conversations/entities/Message.java @@ -57,9 +57,9 @@ public class Message extends AbstractEntity { protected boolean read = true; protected String remoteMsgId = null; - protected transient Conversation conversation = null; - - protected transient Downloadable downloadable = null; + protected Conversation conversation = null; + protected Downloadable downloadable = null; + public boolean markable = false; private Message() { diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 8d5ca898f..f83290373 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -24,7 +24,6 @@ public class MessageParser extends AbstractParser implements String[] fromParts = packet.getFrom().split("/", 2); Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, fromParts[0], false); - conversation.setLatestMarkableMessageId(getMarkableMessageId(packet)); updateLastseen(packet, account, true); String pgpBody = getPgpBody(packet); Message finishedMessage; @@ -37,6 +36,7 @@ public class MessageParser extends AbstractParser implements Message.STATUS_RECEIVED); } finishedMessage.setRemoteMsgId(packet.getId()); + finishedMessage.markable = isMarkable(packet); if (conversation.getMode() == Conversation.MODE_MULTI && fromParts.length >= 2) { finishedMessage.setType(Message.TYPE_PRIVATE); @@ -108,13 +108,12 @@ public class MessageParser extends AbstractParser implements conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); return null; } - conversation - .setLatestMarkableMessageId(getMarkableMessageId(packet)); Message finishedMessage = new Message(conversation, packet.getFrom(), body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED); finishedMessage.setTime(getTimestamp(packet)); finishedMessage.setRemoteMsgId(packet.getId()); + finishedMessage.markable = isMarkable(packet); return finishedMessage; } catch (Exception e) { String receivedId = packet.getId(); @@ -156,7 +155,6 @@ public class MessageParser extends AbstractParser implements status = Message.STATUS_RECEIVED; } String pgpBody = getPgpBody(packet); - conversation.setLatestMarkableMessageId(getMarkableMessageId(packet)); Message finishedMessage; if (pgpBody == null) { finishedMessage = new Message(conversation, counterPart, @@ -166,6 +164,7 @@ public class MessageParser extends AbstractParser implements Message.ENCRYPTION_PGP, status); } finishedMessage.setRemoteMsgId(packet.getId()); + finishedMessage.markable = isMarkable(packet); if (status == Message.STATUS_RECEIVED) { finishedMessage.setTrueCounterpart(conversation.getMucOptions() .getTrueCounterpart(counterPart)); @@ -234,8 +233,6 @@ public class MessageParser extends AbstractParser implements String[] parts = fullJid.split("/", 2); Conversation conversation = mXmppConnectionService .findOrCreateConversation(account, parts[0], false); - conversation.setLatestMarkableMessageId(getMarkableMessageId(packet)); - String pgpBody = getPgpBody(message); Message finishedMessage; if (pgpBody != null) { @@ -248,6 +245,7 @@ public class MessageParser extends AbstractParser implements } finishedMessage.setTime(getTimestamp(message)); finishedMessage.setRemoteMsgId(message.getAttribute("id")); + finishedMessage.markable = isMarkable(message); if (conversation.getMode() == Conversation.MODE_MULTI && parts.length >= 2) { finishedMessage.setType(Message.TYPE_PRIVATE); @@ -385,12 +383,8 @@ public class MessageParser extends AbstractParser implements } } - private String getMarkableMessageId(Element message) { - if (message.hasChild("markable", "urn:xmpp:chat-markers:0")) { - return message.getAttribute("id"); - } else { - return null; - } + private boolean isMarkable(Element message) { + return message.hasChild("markable", "urn:xmpp:chat-markers:0"); } @Override diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index ca69b5309..6aac3f934 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1632,10 +1632,11 @@ public class XmppConnectionService extends Service { } public void markRead(Conversation conversation, boolean calledByUi) { - conversation.markRead(); mNotificationService.clear(conversation); - String id = conversation.popLatestMarkableMessageId(); + String id = conversation.getLatestMarkableMessageId(); + conversation.markRead(); if (confirmMessages() && id != null && calledByUi) { + Log.d(Config.LOGTAG,conversation.getAccount().getJid()+": sending read marker for "+conversation.getName()); Account account = conversation.getAccount(); String to = conversation.getContactJid(); this.sendMessagePacket(conversation.getAccount(), From 3d88ffc5cd4b9e500048557f9ce5f01653123526 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 8 Oct 2014 12:21:58 +0200 Subject: [PATCH 52/57] fixed possible logout bugs --- .../siacs/conversations/services/XmppConnectionService.java | 3 +++ src/eu/siacs/conversations/xmpp/XmppConnection.java | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 6aac3f934..e2c17b7e1 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -1508,6 +1508,9 @@ public class XmppConnectionService extends Service { thread.start(); scheduleWakeupCall((int) (Config.CONNECT_TIMEOUT * 1.2), false); + } else { + account.getRoster().clearPresences(); + account.setXmppConnection(null); } } }).start(); diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java index b789d95fc..54409be45 100644 --- a/src/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java @@ -910,8 +910,7 @@ public class XmppConnection implements Runnable { } public void disconnect(boolean force) { - changeStatus(Account.STATUS_OFFLINE); - Log.d(Config.LOGTAG, "disconnecting"); + Log.d(Config.LOGTAG, account.getJid()+": disconnecting"); try { if (force) { socket.close(); @@ -929,6 +928,7 @@ public class XmppConnection implements Runnable { Thread.sleep(100); } tagWriter.writeTag(Tag.end("stream:stream")); + socket.close(); } catch (IOException e) { Log.d(Config.LOGTAG, "io exception during disconnect"); From 10411944b1bd18c0b5d7b1353f4c55eb0ec4aff6 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 8 Oct 2014 14:10:37 +0200 Subject: [PATCH 53/57] bullet proofing some code --- .../persistance/DatabaseBackend.java | 3 ++ .../services/XmppConnectionService.java | 28 +++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java index 0231c0e7e..0991dd2d8 100644 --- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -210,6 +210,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { while (cursor.moveToNext()) { list.add(Account.fromCursor(cursor)); } + cursor.close(); return list; } @@ -232,6 +233,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Account.TABLENAME + " where not options & (1 <<1)", null); cursor.moveToFirst(); int count = cursor.getInt(0); + cursor.close(); return (count > 0); } @@ -258,6 +260,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { while (cursor.moveToNext()) { roster.initContact(Contact.fromCursor(cursor)); } + cursor.close(); } public void writeRoster(Roster roster) { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index e2c17b7e1..5aca9ce32 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -908,10 +908,12 @@ public class XmppConnectionService extends Service { public void archiveConversation(Conversation conversation) { if (conversation.getMode() == Conversation.MODE_MULTI) { - Bookmark bookmark = conversation.getBookmark(); - if (bookmark != null && bookmark.autojoin()) { - bookmark.setAutojoin(false); - pushBookmarks(bookmark.getAccount()); + if (conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { + Bookmark bookmark = conversation.getBookmark(); + if (bookmark != null && bookmark.autojoin()) { + bookmark.setAutojoin(false); + pushBookmarks(bookmark.getAccount()); + } } leaveMuc(conversation); } else { @@ -1639,7 +1641,8 @@ public class XmppConnectionService extends Service { String id = conversation.getLatestMarkableMessageId(); conversation.markRead(); if (confirmMessages() && id != null && calledByUi) { - Log.d(Config.LOGTAG,conversation.getAccount().getJid()+": sending read marker for "+conversation.getName()); + Log.d(Config.LOGTAG, conversation.getAccount().getJid() + + ": sending read marker for " + conversation.getName()); Account account = conversation.getAccount(); String to = conversation.getContactJid(); this.sendMessagePacket(conversation.getAccount(), @@ -1722,16 +1725,25 @@ public class XmppConnectionService extends Service { } public void sendMessagePacket(Account account, MessagePacket packet) { - account.getXmppConnection().sendMessagePacket(packet); + XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.sendMessagePacket(packet); + } } public void sendPresencePacket(Account account, PresencePacket packet) { - account.getXmppConnection().sendPresencePacket(packet); + XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.sendPresencePacket(packet); + } } public void sendIqPacket(Account account, IqPacket packet, OnIqPacketReceived callback) { - account.getXmppConnection().sendIqPacket(packet, callback); + XmppConnection connection = account.getXmppConnection(); + if (connection != null) { + connection.sendIqPacket(packet, callback); + } } public MessageGenerator getMessageGenerator() { From ce446840fcacbffae0bf1e7a3ff7218cc271d54c Mon Sep 17 00:00:00 2001 From: "M. Dietrich" Date: Wed, 8 Oct 2014 16:37:43 +0200 Subject: [PATCH 54/57] remove this.this member --- .../conversations/ui/ContactDetailsActivity.java | 14 ++++++-------- .../conversations/ui/ConversationActivity.java | 9 ++++----- .../conversations/ui/ManageAccountActivity.java | 8 +++----- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java index 9d384c601..9926e1260 100644 --- a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -39,8 +39,6 @@ import eu.siacs.conversations.utils.UIHelper; public class ContactDetailsActivity extends XmppActivity { public static final String ACTION_VIEW_CONTACT = "view_contact"; - protected ContactDetailsActivity activity = this; - private Contact contact; private String accountJid; @@ -58,8 +56,8 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(DialogInterface dialog, int which) { - activity.xmppConnectionService.deleteContactOnServer(contact); - activity.finish(); + ContactDetailsActivity.this.xmppConnectionService.deleteContactOnServer(contact); + ContactDetailsActivity.this.finish(); } }; @@ -73,14 +71,14 @@ public class ContactDetailsActivity extends XmppActivity { intent.putExtra(Intents.Insert.IM_PROTOCOL, CommonDataKinds.Im.PROTOCOL_JABBER); intent.putExtra("finishActivityOnSaveCompleted", true); - activity.startActivityForResult(intent, 0); + ContactDetailsActivity.this.startActivityForResult(intent, 0); } }; private OnClickListener onBadgeClick = new OnClickListener() { @Override public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + AlertDialog.Builder builder = new AlertDialog.Builder(ContactDetailsActivity.this); builder.setTitle(getString(R.string.action_add_phone_book)); builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid())); @@ -206,7 +204,7 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onValueEdited(String value) { contact.setServerName(value); - activity.xmppConnectionService + ContactDetailsActivity.this.xmppConnectionService .pushContactToServer(contact); populateView(); } @@ -354,7 +352,7 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(View v) { - PgpEngine pgp = activity.xmppConnectionService + PgpEngine pgp = ContactDetailsActivity.this.xmppConnectionService .getPgpEngine(); if (pgp != null) { PendingIntent intent = pgp.getIntentForKey(contact); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index f3db8cb43..ad1cd2838 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -74,7 +74,6 @@ public class ConversationActivity extends XmppActivity implements private boolean paneShouldBeOpen = true; private ArrayAdapter listAdapter; - protected ConversationActivity activity = this; private Toast prepareImageToast; private Uri pendingImageUri = null; @@ -223,7 +222,7 @@ public class ConversationActivity extends XmppActivity implements ab.setDisplayHomeAsUpEnabled(true); ab.setHomeButtonEnabled(true); if (getSelectedConversation().getMode() == Conversation.MODE_SINGLE - || activity.useSubjectToIdentifyConference()) { + || ConversationActivity.this.useSubjectToIdentifyConference()) { ab.setTitle(getSelectedConversation().getName()); } else { ab.setTitle(getSelectedConversation().getContactJid() @@ -450,7 +449,7 @@ public class ConversationActivity extends XmppActivity implements @Override public void onClick(DialogInterface dialog, int which) { - activity.xmppConnectionService + ConversationActivity.this.xmppConnectionService .clearConversationHistory(conversation); if (endConversationCheckBox.isChecked()) { endConversation(conversation); @@ -585,7 +584,7 @@ public class ConversationActivity extends XmppActivity implements + (durations[which] * 1000); } conversation.setMutedTill(till); - activity.xmppConnectionService.databaseBackend + ConversationActivity.this.xmppConnectionService.databaseBackend .updateConversation(conversation); ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager() .findFragmentByTag("conversation"); @@ -855,7 +854,7 @@ public class ConversationActivity extends XmppActivity implements @Override public void userInputRequried(PendingIntent pi, Message message) { - activity.runIntent(pi, + ConversationActivity.this.runIntent(pi, ConversationActivity.REQUEST_SEND_MESSAGE); } diff --git a/src/eu/siacs/conversations/ui/ManageAccountActivity.java b/src/eu/siacs/conversations/ui/ManageAccountActivity.java index ca17eb0df..afe9e06e9 100644 --- a/src/eu/siacs/conversations/ui/ManageAccountActivity.java +++ b/src/eu/siacs/conversations/ui/ManageAccountActivity.java @@ -24,8 +24,6 @@ import android.widget.ListView; public class ManageAccountActivity extends XmppActivity { - protected ManageAccountActivity activity = this; - protected Account selectedAccount = null; protected List accountList = new ArrayList(); @@ -72,7 +70,7 @@ public class ManageAccountActivity extends XmppActivity { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - activity.getMenuInflater().inflate(R.menu.manageaccounts_context, menu); + ManageAccountActivity.this.getMenuInflater().inflate(R.menu.manageaccounts_context, menu); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; this.selectedAccount = accountList.get(acmi.position); if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) { @@ -181,7 +179,7 @@ public class ManageAccountActivity extends XmppActivity { } private void publishOpenPGPPublicKey(Account account) { - if (activity.hasPgp()) { + if (ManageAccountActivity.this.hasPgp()) { announcePgp(account, null); } else { this.showInstallPgpDialog(); @@ -189,7 +187,7 @@ public class ManageAccountActivity extends XmppActivity { } private void deleteAccount(final Account account) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + AlertDialog.Builder builder = new AlertDialog.Builder(ManageAccountActivity.this); builder.setTitle(getString(R.string.mgmt_account_are_you_sure)); builder.setIconAttribute(android.R.attr.alertDialogIcon); builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text)); From 912474ea807b236ee9d495f298305437ba80c4b8 Mon Sep 17 00:00:00 2001 From: kruks23 Date: Wed, 8 Oct 2014 23:26:44 +0200 Subject: [PATCH 55/57] Update Spanish Translations --- res/values-es/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 85d1d7842..7fdc95c05 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -261,5 +261,9 @@ Otros Nombre de conferencia Usar el asunto de la conferencia en lugar del identificador jabber como nombre de conferencia + ¡Clave OTR copiada en el portapapeles! + Tu entrada a esta conferencia ha sido prohibida + Esta conferencia es solo para miembros + Has sido expulsado de esta conferencia \ No newline at end of file From c6f9b23def1684acd754e3db6712a7a5efbd5b42 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 9 Oct 2014 23:08:40 +0200 Subject: [PATCH 56/57] fixed npes --- src/eu/siacs/conversations/entities/Conversation.java | 3 +++ .../conversations/services/XmppConnectionService.java | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 60afaa5de..b4c99dc1a 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -139,6 +139,9 @@ public class Conversation extends AbstractEntity { } public String getLatestMarkableMessageId() { + if (this.messages == null) { + return null; + } for(int i = this.messages.size() - 1; i >= 0; --i) { if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED && this.messages.get(i).markable) { if (this.messages.get(i).isRead()) { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 5aca9ce32..e6297f4ff 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -517,7 +517,8 @@ public class XmppConnectionService extends Service { MessagePacket packet = null; boolean saveInDb = true; boolean send = false; - if (account.getStatus() == Account.STATUS_ONLINE) { + if (account.getStatus() == Account.STATUS_ONLINE + && account.getXmppConnection() != null) { if (message.getType() == Message.TYPE_IMAGE) { if (message.getPresence() != null) { if (message.getEncryption() == Message.ENCRYPTION_OTR) { @@ -567,6 +568,10 @@ public class XmppConnectionService extends Service { send = true; } } + if (!account.getXmppConnection().getFeatures().sm() + && conv.getMode() != Conversation.MODE_MULTI) { + message.setStatus(Message.STATUS_SEND); + } } else { message.setStatus(Message.STATUS_WAITING); if (message.getType() == Message.TYPE_TEXT) { @@ -592,10 +597,6 @@ public class XmppConnectionService extends Service { } conv.getMessages().add(message); - if (!account.getXmppConnection().getFeatures().sm() - && conv.getMode() != Conversation.MODE_MULTI) { - message.setStatus(Message.STATUS_SEND); - } if (saveInDb) { if (message.getEncryption() == Message.ENCRYPTION_NONE || saveEncryptedMessages()) { From 331be08859d68fa6a034b39c674fd7bb929c4a5c Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 9 Oct 2014 23:08:55 +0200 Subject: [PATCH 57/57] version bump to 0.7.3 and changelog --- AndroidManifest.xml | 6 +++--- CHANGELOG.md | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 85cf2dc65..ce4ea5df0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="31" + android:versionName="0.7.3" > - \ No newline at end of file + diff --git a/CHANGELOG.md b/CHANGELOG.md index c14f33166..29277eb40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ###Changelog +####Version 0.7.3 +* revised tablet ui +* internal rewrites +* bug fixes + ####Version 0.7.2 * show full timestamp in messages * brought back option to use JID to identify conferences