diff options
author | lookshe <github@lookshe.org> | 2016-02-16 11:41:54 +0100 |
---|---|---|
committer | lookshe <github@lookshe.org> | 2016-02-16 11:41:54 +0100 |
commit | 1e40764b20a08170f8e4bfe1f1ae1559111f2961 (patch) | |
tree | 1791a3870361f37c3c34c299d075f56ed4a6e2c2 /src/main/java/eu/siacs/conversations/ui | |
parent | a049aff638f27b68f08c753d42ef0fc2847b96cb (diff) | |
parent | d58d822215708cc0d9c841872abab448bf290e4c (diff) |
Merge tag '1.9.4' into trz/merge_1.9.4
Conflicts:
build.gradle
src/main/java/eu/siacs/conversations/generator/PresenceGenerator.java
src/main/java/eu/siacs/conversations/parser/PresenceParser.java
src/main/java/eu/siacs/conversations/services/MessageArchiveService.java
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
src/main/res/values/arrays.xml
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui')
5 files changed, 155 insertions, 41 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 37be65a9..d71958d2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -860,7 +860,7 @@ public class ConversationActivity extends XmppActivity MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp); MenuItem axolotl = popup.getMenu().findItem(R.id.encryption_choice_axolotl); pgp.setVisible(!Config.HIDE_PGP_IN_UI && !Config.X509_VERIFICATION); - none.setVisible(!Config.FORCE_E2E_ENCRYPTION); + none.setVisible(!Config.FORCE_E2E_ENCRYPTION || conversation.getMode() == Conversation.MODE_MULTI); otr.setVisible(!Config.X509_VERIFICATION); if (conversation.getMode() == Conversation.MODE_MULTI) { otr.setVisible(false); @@ -1577,4 +1577,10 @@ public class ConversationActivity extends XmppActivity public boolean highlightSelectedConversations() { return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard; } + + public void setMessagesLoaded() { + if (mConversationFragment != null) { + mConversationFragment.setMessagesLoaded(); + } + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 169c5bbe..ea3d7e71 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -8,6 +8,7 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.support.annotation.Nullable; @@ -23,6 +24,8 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; +import android.widget.AbsListView; +import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.ImageButton; @@ -41,6 +44,8 @@ import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentLinkedQueue; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; import eu.siacs.conversations.Config; @@ -52,6 +57,7 @@ import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.TransferablePlaceholder; @@ -237,6 +243,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private ConversationActivity activity; private Message selectedMessage; + public void setMessagesLoaded() { + this.messagesLoaded = true; + } + private void sendMessage() { final String body = mEditMessage.getText().toString(); if (body.length() == 0 || this.conversation == null) { @@ -887,82 +897,82 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa enum SendButtonAction {TEXT, TAKE_PHOTO, SEND_LOCATION, RECORD_VOICE, CANCEL, CHOOSE_PICTURE} - private int getSendButtonImageResource(SendButtonAction action, int status) { + private int getSendButtonImageResource(SendButtonAction action, Presence.Status status) { switch (action) { case TEXT: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_text_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_text_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_text_dnd; default: return R.drawable.ic_send_text_offline; } case TAKE_PHOTO: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_photo_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_photo_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_photo_dnd; default: return R.drawable.ic_send_photo_offline; } case RECORD_VOICE: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_voice_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_voice_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_voice_dnd; default: return R.drawable.ic_send_voice_offline; } case SEND_LOCATION: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_location_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_location_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_location_dnd; default: return R.drawable.ic_send_location_offline; } case CANCEL: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_cancel_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_cancel_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_cancel_dnd; default: return R.drawable.ic_send_cancel_offline; } case CHOOSE_PICTURE: switch (status) { - case Presences.CHAT: - case Presences.ONLINE: + case CHAT: + case ONLINE: return R.drawable.ic_send_picture_online; - case Presences.AWAY: + case AWAY: return R.drawable.ic_send_picture_away; - case Presences.XA: - case Presences.DND: + case XA: + case DND: return R.drawable.ic_send_picture_dnd; default: return R.drawable.ic_send_picture_offline; @@ -974,7 +984,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa public void updateSendButton() { final Conversation c = this.conversation; final SendButtonAction action; - final int status; + final Presence.Status status; final boolean empty = this.mEditMessage == null || this.mEditMessage.getText().length() == 0; final boolean conference = c.getMode() == Conversation.MODE_MULTI; if (conference && !c.getAccount().httpUploadAvailable()) { @@ -1021,10 +1031,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (c.getMode() == Conversation.MODE_SINGLE) { status = c.getContact().getMostAvailableStatus(); } else { - status = c.getMucOptions().online() ? Presences.ONLINE : Presences.OFFLINE; + status = c.getMucOptions().online() ? Presence.Status.ONLINE : Presence.Status.OFFLINE; } } else { - status = Presences.OFFLINE; + status = Presence.Status.OFFLINE; } this.mSendButton.setTag(action); this.mSendButton.setImageResource(getSendButtonImageResource(action, status)); @@ -1032,6 +1042,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa public void updateStatusMessages() { synchronized (this.messageList) { + if (conversation.getLastClearHistory() != 0) { + this.messageList.add(0, Message.createLoadMoreMessage(conversation)); + } if (conversation.getMode() == Conversation.MODE_SINGLE) { ChatState state = conversation.getIncomingChatState(); if (state == ChatState.COMPOSING) { diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 3765c764..db3a451b 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -32,7 +32,10 @@ import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; +import java.util.Arrays; +import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener; import eu.siacs.conversations.Config; @@ -46,6 +49,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.XmppConnection.Features; import eu.siacs.conversations.xmpp.forms.Data; @@ -54,7 +58,7 @@ import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, - OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast { + OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched { private AutoCompleteTextView mAccountJid; private EditText mPassword; @@ -220,6 +224,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate finish(); } }; + private Toast mFetchingMamPrefsToast; public void refreshUiReal() { invalidateOptionsMenu(); @@ -467,6 +472,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate final MenuItem changePassword = menu.findItem(R.id.action_change_password_on_server); final MenuItem clearDevices = menu.findItem(R.id.action_clear_devices); final MenuItem renewCertificate = menu.findItem(R.id.action_renew_certificate); + final MenuItem mamPrefs = menu.findItem(R.id.action_mam_prefs); renewCertificate.setVisible(mAccount != null && mAccount.getPrivateKeyAlias() != null); @@ -477,6 +483,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate if (!mAccount.getXmppConnection().getFeatures().register()) { changePassword.setVisible(false); } + mamPrefs.setVisible(mAccount.getXmppConnection().getFeatures().mam()); Set<Integer> otherDevices = mAccount.getAxolotlService().getOwnDeviceIds(); if (otherDevices == null || otherDevices.isEmpty()) { clearDevices.setVisible(false); @@ -487,6 +494,7 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate showMoreInfo.setVisible(false); changePassword.setVisible(false); clearDevices.setVisible(false); + mamPrefs.setVisible(false); } return true; } @@ -570,6 +578,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate changePasswordIntent.putExtra(EXTRA_ACCOUNT, mAccount.getJid().toString()); startActivity(changePasswordIntent); break; + case R.id.action_mam_prefs: + editMamPrefs(); + break; case R.id.action_clear_devices: showWipePepDialog(); break; @@ -810,6 +821,12 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate builder.create().show(); } + private void editMamPrefs() { + this.mFetchingMamPrefsToast = Toast.makeText(this, R.string.fetching_mam_prefs, Toast.LENGTH_LONG); + this.mFetchingMamPrefsToast.show(); + xmppConnectionService.fetchMamPreferences(mAccount, this); + } + @Override public void onKeyStatusUpdated(AxolotlService.FetchStatus report) { refreshUi(); @@ -889,4 +906,49 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } }); } + + @Override + public void onPreferencesFetched(final Element prefs) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mFetchingMamPrefsToast != null) { + mFetchingMamPrefsToast.cancel(); + } + AlertDialog.Builder builder = new Builder(EditAccountActivity.this); + builder.setTitle(R.string.mam_prefs); + String defaultAttr = prefs.getAttribute("default"); + final List<String> defaults = Arrays.asList("never", "roster", "always"); + final AtomicInteger choice = new AtomicInteger(Math.max(0,defaults.indexOf(defaultAttr))); + builder.setSingleChoiceItems(R.array.mam_prefs, choice.get(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + choice.set(which); + } + }); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + prefs.setAttribute("default",defaults.get(choice.get())); + xmppConnectionService.pushMamPreferences(mAccount, prefs); + } + }); + builder.create().show(); + } + }); + } + + @Override + public void onPreferencesFetchFailed() { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (mFetchingMamPrefsToast != null) { + mFetchingMamPrefsToast.cancel(); + } + Toast.makeText(EditAccountActivity.this,R.string.unable_to_fetch_mam_prefs,Toast.LENGTH_LONG).show(); + } + }); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java index ba685dcf..cd1658e0 100644 --- a/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/StartConversationActivity.java @@ -64,6 +64,7 @@ import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.ListItem; +import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; @@ -727,9 +728,11 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU for (Account account : xmppConnectionService.getAccounts()) { if (account.getStatus() != Account.State.DISABLED) { for (Contact contact : account.getRoster().getContacts()) { + Presence p = contact.getPresences().getMostAvailablePresence(); + Presence.Status s = p == null ? Presence.Status.OFFLINE : p.getStatus(); if (contact.showInRoster() && contact.match(needle) && (!this.mHideOfflineContacts - || contact.getPresences().getMostAvailableStatus() < Presences.OFFLINE)) { + || s.compareTo(Presence.Status.OFFLINE) < 0)) { this.contacts.add(contact); } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index d1db6667..78c8f67c 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -431,6 +431,19 @@ public class MessageAdapter extends ArrayAdapter<Message> { viewHolder.image.setOnLongClickListener(openContextMenu); } + private void loadMoreMessages(Conversation conversation) { + conversation.setLastClearHistory(0); + conversation.setHasMessagesLeftOnServer(true); + conversation.setFirstMamReference(null); + long timestamp = conversation.getLastMessageTransmitted(); + if (timestamp == 0) { + timestamp = System.currentTimeMillis(); + } + activity.setMessagesLoaded(); + activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp); + Toast.makeText(activity, R.string.fetching_history_from_server,Toast.LENGTH_LONG).show(); + } + @Override public View getView(int position, View view, ViewGroup parent) { final Message message = getItem(position); @@ -487,6 +500,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo); viewHolder.status_message = (TextView) view.findViewById(R.id.status_message); + viewHolder.load_more_messages = (Button) view.findViewById(R.id.load_more_messages); break; default: viewHolder = null; @@ -500,18 +514,33 @@ public class MessageAdapter extends ArrayAdapter<Message> { } } - boolean darkBackground = (type == RECEIVED && !isInValidSession); + boolean darkBackground = (type == RECEIVED && (!isInValidSession || !mUseWhiteBackground)); if (type == STATUS) { - if (conversation.getMode() == Conversation.MODE_SINGLE) { + if ("LOAD_MORE".equals(message.getBody())) { + viewHolder.status_message.setVisibility(View.GONE); + viewHolder.contact_picture.setVisibility(View.GONE); + viewHolder.load_more_messages.setVisibility(View.VISIBLE); + viewHolder.load_more_messages.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + loadMoreMessages(message.getConversation()); + } + }); + } else { + viewHolder.status_message.setVisibility(View.VISIBLE); + viewHolder.contact_picture.setVisibility(View.VISIBLE); + viewHolder.load_more_messages.setVisibility(View.GONE); + if (conversation.getMode() == Conversation.MODE_SINGLE) { viewHolder.contact_picture.setImageBitmap(AvatarService.getInstance().get(conversation.getContact(), activity.getPixel(32))); - viewHolder.contact_picture.setAlpha(0.5f); + viewHolder.contact_picture.setAlpha(0.5f); + } viewHolder.status_message.setText(message.getBody()); } return view; } else { - loadAvatar(message,viewHolder.contact_picture); + loadAvatar(message, viewHolder.contact_picture); } viewHolder.contact_picture @@ -661,6 +690,7 @@ public class MessageAdapter extends ArrayAdapter<Message> { protected ImageView contact_picture; protected TextView status_message; protected TextView encryption; + public Button load_more_messages; } class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { |