aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui')
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ChangePasswordActivity.java9
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationActivity.java4
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java156
-rw-r--r--src/main/java/eu/siacs/conversations/ui/EditMessage.java3
-rw-r--r--src/main/java/eu/siacs/conversations/ui/SettingsActivity.java87
-rw-r--r--src/main/java/eu/siacs/conversations/ui/XmppActivity.java4
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java1
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java42
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java27
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java15
-rw-r--r--src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java118
-rw-r--r--src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java48
12 files changed, 441 insertions, 73 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ChangePasswordActivity.java b/src/main/java/eu/siacs/conversations/ui/ChangePasswordActivity.java
index aa986bd1..09988b7c 100644
--- a/src/main/java/eu/siacs/conversations/ui/ChangePasswordActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ChangePasswordActivity.java
@@ -26,11 +26,14 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
mCurrentPassword.requestFocus();
mCurrentPassword.setError(getString(R.string.account_status_unauthorized));
} else if (!newPassword.equals(newPasswordConfirm)) {
- mNewPasswordConfirm.requestFocus();
- mNewPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
+ mNewPasswordConfirm.requestFocus();
+ mNewPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
+ } else if (newPassword.isEmpty()) {
+ mNewPassword.requestFocus();
+ mNewPassword.setError(getString(R.string.password_should_not_be_empty));
} else if (newPassword.trim().isEmpty()) {
mNewPassword.requestFocus();
- mNewPassword.setError(getString(R.string.password_should_not_be_empty));
+ mNewPassword.setError(getString(R.string.password_should_not_contain_only_spaces));
} else {
mCurrentPassword.setError(null);
mNewPassword.setError(null);
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
index 219a4fca..7fec827b 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java
@@ -53,6 +53,7 @@ import eu.siacs.conversations.utils.ExceptionHelper;
import eu.siacs.conversations.xmpp.OnUpdateBlocklist;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
+import github.ankushsachdeva.emojicon.EmojiconEditText;
public class ConversationActivity extends XmppActivity
implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast {
@@ -257,6 +258,7 @@ public class ConversationActivity extends XmppActivity
}
});
listView.enableSwipeToDismiss();
+ listView.setSwipeDirection(EnhancedListView.SwipeDirection.START);
listView.setSwipingLayout(R.id.swipeable_item);
listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP);
listView.setUndoHideDelay(5000);
@@ -1144,7 +1146,7 @@ public class ConversationActivity extends XmppActivity
}
prepareFileToast = Toast.makeText(getApplicationContext(),getText(R.string.preparing_file), Toast.LENGTH_LONG);
prepareFileToast.show();
- xmppConnectionService.attachFileToConversation(conversation,uri, new UiCallback<Message>() {
+ xmppConnectionService.attachFileToConversation(conversation, uri, new UiCallback<Message>() {
@Override
public void success(Message message) {
hidePrepareFileToast();
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
index de758efc..f645b241 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
@@ -11,7 +11,9 @@ import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
import android.text.InputType;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
@@ -23,12 +25,12 @@ 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;
+import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -47,7 +49,13 @@ import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
+<<<<<<< HEAD
+import eu.siacs.conversations.entities.Transferable;
+import eu.siacs.conversations.entities.DownloadableFile;
+import eu.siacs.conversations.entities.TransferablePlaceholder;
+=======
import eu.siacs.conversations.entities.DownloadableFile;
+>>>>>>> 1.6.3
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.Presences;
@@ -59,10 +67,14 @@ import eu.siacs.conversations.ui.XmppActivity.OnValueEdited;
import eu.siacs.conversations.ui.adapter.MessageAdapter;
import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked;
import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
+import eu.siacs.conversations.ui.listeners.ConversationSwipeRefreshListener;
import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.chatstate.ChatState;
import eu.siacs.conversations.xmpp.jid.Jid;
+import github.ankushsachdeva.emojicon.EmojiconGridView;
+import github.ankushsachdeva.emojicon.EmojiconsPopup;
+import github.ankushsachdeva.emojicon.emoji.Emojicon;
public class ConversationFragment extends Fragment implements EditMessage.KeyboardListener {
@@ -101,10 +113,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
};
protected ListView messagesView;
- final protected List<Message> messageList = new ArrayList<>();
+ protected SwipeRefreshLayout swipeLayout;
+ final protected List<Message> messageList = new ArrayList<>();
protected MessageAdapter messageListAdapter;
private EditMessage mEditMessage;
private ImageButton mSendButton;
+ private ImageView mEmojButton;
+ private View mRootView;
+ private EmojiconsPopup mEmojPopup;
private RelativeLayout snackbar;
private TextView snackbarMessage;
private TextView snackbarAction;
@@ -371,6 +387,107 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
});
mEditMessage.setOnEditorActionListener(mEditorActionListener);
+ // Start of emojicon
+ mEmojButton = (ImageView) view.findViewById(R.id.emoji_btn);
+ mRootView = view.findViewById(R.id.textsend);
+
+ // Give the topmost view of your activity layout hierarchy. This will be used to measure soft keyboard height
+ mEmojPopup = new EmojiconsPopup(mRootView, this.getActivity());
+
+ //Will automatically set size according to the soft keyboard size
+ mEmojPopup.setSizeForSoftKeyboard();
+
+ //If the emoji popup is dismissed, change emojiButton to smiley icon
+ mEmojPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
+
+ @Override
+ public void onDismiss() {
+ changeEmojiKeyboardIcon(mEmojButton, R.drawable.smiley);
+ }
+ });
+
+ //If the text keyboard closes, also dismiss the emoji popup
+ mEmojPopup.setOnSoftKeyboardOpenCloseListener(new EmojiconsPopup.OnSoftKeyboardOpenCloseListener() {
+
+ @Override
+ public void onKeyboardOpen(int keyBoardHeight) {
+
+ }
+
+ @Override
+ public void onKeyboardClose() {
+ if (mEmojPopup.isShowing())
+ mEmojPopup.dismiss();
+ }
+ });
+
+ //On emoji clicked, add it to edittext
+ mEmojPopup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() {
+
+ @Override
+ public void onEmojiconClicked(Emojicon emojicon) {
+ if (mEditMessage == null || emojicon == null) {
+ return;
+ }
+
+ int start = mEditMessage.getSelectionStart();
+ int end = mEditMessage.getSelectionEnd();
+ if (start < 0) {
+ mEditMessage.append(emojicon.getEmoji());
+ } else {
+ mEditMessage.getText().replace(Math.min(start, end),
+ Math.max(start, end), emojicon.getEmoji(), 0,
+ emojicon.getEmoji().length());
+ }
+ }
+ });
+
+ //On backspace clicked, emulate the KEYCODE_DEL key event
+ mEmojPopup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() {
+
+ @Override
+ public void onEmojiconBackspaceClicked(View v) {
+ KeyEvent event = new KeyEvent(
+ 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
+ mEditMessage.dispatchKeyEvent(event);
+ }
+ });
+
+ // To toggle between text keyboard and emoji keyboard keyboard(Popup)
+ mEmojButton.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+
+ //If popup is not showing => emoji keyboard is not visible, we need to show it
+ if(!mEmojPopup.isShowing()){
+
+ //If keyboard is visible, simply show the emoji popup
+ if(mEmojPopup.isKeyBoardOpen()){
+ mEmojPopup.showAtBottom();
+ changeEmojiKeyboardIcon(mEmojButton, R.drawable.ic_action_keyboard);
+ }
+
+ //else, open the text keyboard first and immediately after that show the emoji popup
+ else{
+ mEditMessage.setFocusableInTouchMode(true);
+ mEditMessage.requestFocus();
+ mEmojPopup.showAtBottomPending();
+ final InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputMethodManager.showSoftInput(mEditMessage, InputMethodManager.SHOW_IMPLICIT);
+ changeEmojiKeyboardIcon(mEmojButton, R.drawable.ic_action_keyboard);
+ }
+ }
+
+ //If popup is showing, simply dismiss it to show the undelying text keyboard
+ else{
+ mEmojPopup.dismiss();
+ }
+ }
+ });
+
+ // End of emojicon
+
mSendButton = (ImageButton) view.findViewById(R.id.textSendButton);
mSendButton.setOnClickListener(this.mSendButtonListener);
@@ -434,6 +551,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
registerForContextMenu(messagesView);
+ // Start of swipe refresh
+ // New Swipe refresh
+ swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_container);
+ swipeLayout.setOnRefreshListener(new ConversationSwipeRefreshListener(messageList, swipeLayout, this, messagesView, messageListAdapter));
+ // End of swipe refresh
+
return view;
}
@@ -572,7 +695,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
resId = R.string.file_url;
url = message.getFileParams().url.toString();
} else {
- url = message.getBody().trim();
+ url = message.getBody();
resId = R.string.file_url;
}
if (activity.copyTextToClipboard(url, resId)) {
@@ -603,7 +726,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
protected void highlightInConference(String nick) {
- String oldString = mEditMessage.getText().toString().trim();
+ String oldString = mEditMessage.getText().toString();
if (oldString.isEmpty() || mEditMessage.getSelectionStart() == 0) {
mEditMessage.getText().insert(0, nick + ": ");
} else {
@@ -669,6 +792,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
if (size > 0) {
messagesView.setSelection(size - 1);
}
+ swipeLayout.setRefreshing(false);
}
private OnClickListener mUnblockClickListener = new OnClickListener() {
@@ -1151,15 +1275,15 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
final ConversationActivity activity = (ConversationActivity) getActivity();
final XmppConnectionService xmppService = activity.xmppConnectionService;
activity.selectPresence(message.getConversation(),
- new OnPresenceSelected() {
-
- @Override
- public void onPresenceSelected() {
- message.setCounterpart(conversation.getNextCounterpart());
- xmppService.sendMessage(message);
- messageSent();
- }
- });
+ new OnPresenceSelected() {
+
+ @Override
+ public void onPresenceSelected() {
+ message.setCounterpart(conversation.getNextCounterpart());
+ xmppService.sendMessage(message);
+ messageSent();
+ }
+ });
}
public void appendText(String text) {
@@ -1224,4 +1348,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
}
+ private void changeEmojiKeyboardIcon(ImageView iconToBeChanged, int drawableResourceId){
+ iconToBeChanged.setImageResource(drawableResourceId);
+ }
+
}
diff --git a/src/main/java/eu/siacs/conversations/ui/EditMessage.java b/src/main/java/eu/siacs/conversations/ui/EditMessage.java
index a58cf2b8..a7aa2024 100644
--- a/src/main/java/eu/siacs/conversations/ui/EditMessage.java
+++ b/src/main/java/eu/siacs/conversations/ui/EditMessage.java
@@ -7,8 +7,9 @@ import android.view.KeyEvent;
import android.widget.EditText;
import eu.siacs.conversations.Config;
+import github.ankushsachdeva.emojicon.EmojiconEditText;
-public class EditMessage extends EditText {
+public class EditMessage extends EmojiconEditText {
public EditMessage(Context context, AttributeSet attrs) {
super(context, attrs);
diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
index 6e5fe610..f9238f13 100644
--- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java
@@ -1,6 +1,21 @@
package eu.siacs.conversations.ui;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Locale;
+
+import de.tzur.conversations.Settings;
+import de.duenndns.ssl.MemorizingTrustManager;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.xmpp.XmppConnection;
+import github.ankushsachdeva.emojicon.EmojiconHandler;
+
import android.app.AlertDialog;
+import android.app.Fragment;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.content.SharedPreferences;
@@ -12,17 +27,6 @@ import android.preference.Preference;
import android.preference.PreferenceManager;
import android.widget.Toast;
-import java.security.KeyStoreException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Locale;
-
-import de.duenndns.ssl.MemorizingTrustManager;
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.entities.Account;
-import eu.siacs.conversations.xmpp.XmppConnection;
-
public class SettingsActivity extends XmppActivity implements
OnSharedPreferenceChangeListener {
private SettingsFragment mSettingsFragment;
@@ -130,37 +134,46 @@ public class SettingsActivity extends XmppActivity implements
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences,
String name) {
- if (name.equals("resource")) {
- String resource = preferences.getString("resource", "mobile")
- .toLowerCase(Locale.US);
- if (xmppConnectionServiceBound) {
- for (Account account : xmppConnectionService.getAccounts()) {
- if (account.setResource(resource)) {
+ // need to synchronize the settings class first
+ Settings.synchronizeSettingsClassWithPreferences(getPreferences(), name);
+ switch (name) {
+ case "resource":
+ String resource = preferences.getString("resource", "mobile")
+ .toLowerCase(Locale.US);
+ if (xmppConnectionServiceBound) {
+ for (Account account : xmppConnectionService.getAccounts()) {
+ if (account.setResource(resource)) {
+ if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+ XmppConnection connection = account.getXmppConnection();
+ if (connection != null) {
+ connection.resetStreamId();
+ }
+ xmppConnectionService.reconnectAccountInBackground(account);
+ }
+ }
+ }
+ }
+ break;
+ case "keep_foreground_service":
+ xmppConnectionService.toggleForegroundService();
+ break;
+ case "confirm_messages":
+ if (xmppConnectionServiceBound) {
+ for (Account account : xmppConnectionService.getAccounts()) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- XmppConnection connection = account.getXmppConnection();
- if (connection != null) {
- connection.resetStreamId();
- }
- xmppConnectionService.reconnectAccountInBackground(account);
+ xmppConnectionService.sendPresence(account);
}
}
}
- }
- } else if (name.equals("keep_foreground_service")) {
- xmppConnectionService.toggleForegroundService();
- } else if (name.equals("confirm_messages")) {
- if (xmppConnectionServiceBound) {
- for (Account account : xmppConnectionService.getAccounts()) {
- if (!account.isOptionSet(Account.OPTION_DISABLED)) {
- xmppConnectionService.sendPresence(account);
- }
- }
- }
- } else if (name.equals("dont_trust_system_cas")) {
- xmppConnectionService.updateMemorizingTrustmanager();
- reconnectAccounts();
+ break;
+ case "dont_trust_system_cas":
+ xmppConnectionService.updateMemorizingTrustmanager();
+ reconnectAccounts();
+ break;
+ case "parse_emoticons":
+ EmojiconHandler.setParseEmoticons(Settings.PARSE_EMOTICONS);
+ break;
}
-
}
private void displayToast(final String msg) {
diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
index 7734dc11..2d780eda 100644
--- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java
@@ -68,6 +68,7 @@ import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
+import de.tzur.conversations.Settings;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
@@ -361,6 +362,9 @@ public abstract class XmppActivity extends Activity {
setTheme(this.mTheme);
this.mUsingEnterKey = usingEnterKey();
mUseSubject = getPreferences().getBoolean("use_subject", true);
+
+ Settings.initSettingsClassWithPreferences(getPreferences());
+
final ActionBar ab = getActionBar();
if (ab!=null) {
ab.setDisplayHomeAsUpEnabled(true);
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
index 98250af9..141dbc3a 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java
@@ -8,6 +8,7 @@ import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Switch;
import java.util.List;
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
index 6918713e..b89dd01a 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
@@ -19,13 +19,29 @@ import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.RejectedExecutionException;
+import de.tzur.conversations.Settings;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Transferable;
import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.ui.XmppActivity;
import eu.siacs.conversations.utils.UIHelper;
+import github.ankushsachdeva.emojicon.EmojiconTextView;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
public class ConversationAdapter extends ArrayAdapter<Conversation> {
@@ -56,10 +72,34 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
} else {
convName.setText(conversation.getJid().toBareJid().toString());
}
- TextView mLastMessage = (TextView) view.findViewById(R.id.conversation_lastmsg);
+ EmojiconTextView mLastMessage = (EmojiconTextView) view.findViewById(R.id.conversation_lastmsg);
TextView mTimestamp = (TextView) view.findViewById(R.id.conversation_lastupdate);
ImageView imagePreview = (ImageView) view.findViewById(R.id.conversation_lastimage);
+ if (Settings.SHOW_ONLINE_STATUS && conversation != null && conversation.getAccount().getStatus() == Account.State.ONLINE) {
+ TextView status = (TextView) view.findViewById(R.id.status);
+
+ String color = "#000000";
+ if (conversation.getMode() == Conversation.MODE_SINGLE) {
+ switch (conversation.getContact().getMostAvailableStatus()) {
+ case Presences.ONLINE:
+ case Presences.CHAT:
+ color = "#259B23";
+ break;
+ case Presences.AWAY:
+ case Presences.XA:
+ color = "#FF9800";
+ break;
+ case Presences.DND:
+ color = "#E51C23";
+ break;
+ }
+ } else if (conversation.getMode() == Conversation.MODE_MULTI && conversation.getMucOptions().online()) {
+ color = "#259B23";
+ }
+ status.setBackgroundColor(Color.parseColor(color));
+ }
+
Message message = conversation.getLatestMessage();
if (!conversation.isRead()) {
diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
index ad7d7622..4187ec60 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java
@@ -1,5 +1,16 @@
package eu.siacs.conversations.ui.adapter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.RejectedExecutionException;
+
+import de.tzur.conversations.Settings;
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.ListItem;
+import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.utils.UIHelper;
+import eu.siacs.conversations.xmpp.jid.Jid;
+
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
@@ -16,16 +27,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
-
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.entities.ListItem;
-import eu.siacs.conversations.ui.XmppActivity;
-import eu.siacs.conversations.utils.UIHelper;
-import eu.siacs.conversations.xmpp.jid.Jid;
-
public class ListItemAdapter extends ArrayAdapter<ListItem> {
protected XmppActivity activity;
@@ -57,6 +58,12 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
if (view == null) {
view = inflater.inflate(R.layout.contact, parent, false);
}
+
+ if (Settings.SHOW_ONLINE_STATUS) {
+ TextView tvStatus = (TextView) view.findViewById(R.id.contact_status);
+ tvStatus.setBackgroundColor(item.getStatusColor());
+ }
+
TextView tvName = (TextView) view.findViewById(R.id.contact_display_name);
TextView tvJid = (TextView) view.findViewById(R.id.contact_jid);
ImageView picture = (ImageView) view.findViewById(R.id.contact_photo);
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 1ddd6c44..a5b25967 100644
--- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -6,6 +6,7 @@ import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
+import android.preference.PreferenceManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -26,6 +27,8 @@ import android.widget.Toast;
import java.util.List;
+import de.tzur.conversations.Settings;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.entities.Account;
@@ -38,6 +41,7 @@ import eu.siacs.conversations.entities.Transferable;
import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.utils.GeoHelper;
import eu.siacs.conversations.utils.UIHelper;
+import github.ankushsachdeva.emojicon.EmojiconTextView;
public class MessageAdapter extends ArrayAdapter<Message> {
@@ -279,13 +283,14 @@ public class MessageAdapter extends ArrayAdapter<Message> {
i = body.indexOf(Message.MERGE_SEPARATOR,end);
}
if (message.getType() != Message.TYPE_PRIVATE) {
+
if (message.hasMeCommand()) {
final Spannable span = new SpannableString(formattedBody);
span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
viewHolder.messageBody.setText(span);
} else {
- viewHolder.messageBody.setText(formattedBody);
+ viewHolder.messageBody.setText(formattedBody);
}
} else {
String privateMarker;
@@ -424,7 +429,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
.findViewById(R.id.security_indicator);
viewHolder.image = (ImageView) view
.findViewById(R.id.message_image);
- viewHolder.messageBody = (TextView) view
+ viewHolder.messageBody = (EmojiconTextView) view
.findViewById(R.id.message_body);
viewHolder.time = (TextView) view
.findViewById(R.id.message_time);
@@ -444,7 +449,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
.findViewById(R.id.security_indicator);
viewHolder.image = (ImageView) view
.findViewById(R.id.message_image);
- viewHolder.messageBody = (TextView) view
+ viewHolder.messageBody = (EmojiconTextView) view
.findViewById(R.id.message_body);
viewHolder.time = (TextView) view
.findViewById(R.id.message_time);
@@ -555,8 +560,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else {
if (GeoHelper.isGeoUri(message.getBody())) {
displayLocationMessage(viewHolder,message);
- } else if (message.bodyIsHeart()) {
- displayHeartMessage(viewHolder, message.getBody().trim());
} else if (message.treatAsDownloadable() == Message.Decision.MUST) {
displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)));
} else {
@@ -632,7 +635,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
protected ImageView indicator;
protected ImageView indicatorReceived;
protected TextView time;
- protected TextView messageBody;
+ protected EmojiconTextView messageBody;
protected ImageView contact_picture;
protected TextView status_message;
}
diff --git a/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java
new file mode 100644
index 00000000..2154f8d8
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java
@@ -0,0 +1,118 @@
+package eu.siacs.conversations.ui.listeners;
+
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.List;
+
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.ConversationActivity;
+import eu.siacs.conversations.ui.ConversationFragment;
+import eu.siacs.conversations.ui.adapter.MessageAdapter;
+
+/**
+ * This listener updates the UI when messages are loaded from the server.
+ */
+public class ConversationMoreMessagesLoadedListener implements XmppConnectionService.OnMoreMessagesLoaded {
+ private SwipeRefreshLayout swipeLayout;
+ private List<Message> messageList;
+ private ConversationFragment fragment;
+ private ListView messagesView;
+ private MessageAdapter messageListAdapter;
+ private Toast messageLoaderToast;
+
+ public ConversationMoreMessagesLoadedListener(SwipeRefreshLayout swipeLayout, List<Message> messageList, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) {
+ this.swipeLayout = swipeLayout;
+ this.messageList = messageList;
+ this.fragment = fragment;
+ this.messagesView = messagesView;
+ this.messageListAdapter = messageListAdapter;
+ }
+
+ @Override
+ public void onMoreMessagesLoaded(final int c, final Conversation conversation) {
+ ConversationActivity activity = (ConversationActivity) fragment.getActivity();
+ if (activity.getSelectedConversation() != conversation) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ swipeLayout.setRefreshing(false);
+ }
+ });
+ return;
+ }
+ if (0 == c) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ swipeLayout.setRefreshing(false);
+ }
+ });
+ }
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ final int oldPosition = messagesView.getFirstVisiblePosition();
+ int pos = 0;
+ View v = messagesView.getChildAt(0);
+ final int pxOffset = (v == null) ? 0 : v.getTop();
+ if (-1 < oldPosition && messageList.size() > oldPosition) {
+ Message message = messageList.get(oldPosition);
+ String uuid = message != null ? message.getUuid() : null;
+ pos = getIndexOf(uuid, messageList);
+ }
+ conversation.populateWithMessages(messageList);
+ fragment.updateStatusMessages();
+ messageListAdapter.notifyDataSetChanged();
+ messagesView.setSelectionFromTop(pos, pxOffset);
+
+ if (messageLoaderToast != null) {
+ messageLoaderToast.cancel();
+ }
+ swipeLayout.setRefreshing(false);
+ }
+ });
+ }
+
+ @Override
+ public void informUser(final int resId) {
+ final ConversationActivity activity = (ConversationActivity) fragment.getActivity();
+
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (messageLoaderToast != null) {
+ messageLoaderToast.cancel();
+ }
+ messageLoaderToast = Toast.makeText(activity, resId, Toast.LENGTH_LONG);
+ messageLoaderToast.show();
+ }
+ });
+
+ }
+
+ private int getIndexOf(String uuid, List<Message> messages) {
+ if (uuid == null) {
+ return 0;
+ }
+ for(int i = 0; i < messages.size(); ++i) {
+ if (uuid.equals(messages.get(i).getUuid())) {
+ return i;
+ } else {
+ Message next = messages.get(i);
+ while(next != null && next.wasMergedIntoPrevious()) {
+ if (uuid.equals(next.getUuid())) {
+ return i;
+ }
+ next = next.next();
+ }
+
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java
new file mode 100644
index 00000000..09a8d730
--- /dev/null
+++ b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java
@@ -0,0 +1,48 @@
+package eu.siacs.conversations.ui.listeners;
+
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.List;
+
+import eu.siacs.conversations.Config;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.ConversationActivity;
+import eu.siacs.conversations.ui.ConversationFragment;
+import eu.siacs.conversations.ui.adapter.MessageAdapter;
+
+/**
+ * This listener starts loading messages from the server.
+ */
+public class ConversationSwipeRefreshListener implements SwipeRefreshLayout.OnRefreshListener {
+ private List<Message> messageList;
+ private ConversationFragment fragment;
+ private ConversationMoreMessagesLoadedListener listener;
+
+ public ConversationSwipeRefreshListener(List<Message> messageList, SwipeRefreshLayout swipeLayout, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) {
+ this.messageList = messageList;
+ this.fragment = fragment;
+ this.listener = new ConversationMoreMessagesLoadedListener(swipeLayout, messageList, fragment, messagesView, messageListAdapter);
+ }
+
+ @Override
+ public void onRefresh() {
+ Log.d(Config.LOGTAG, "Refresh swipe container");
+ synchronized (this.messageList) {
+ long timestamp;
+ if (messageList.isEmpty()) {
+ timestamp = System.currentTimeMillis();
+ } else {
+ timestamp = this.messageList.get(0).getTimeSent();
+ }
+ ConversationActivity activity = (ConversationActivity) fragment.getActivity();
+ activity.xmppConnectionService.loadMoreMessages(activity.getSelectedConversation(), timestamp, this.listener);
+ }
+ Log.d(Config.LOGTAG, "End Refresh swipe container");
+ }
+}