Commit 9d995fdf authored by Grigory Fedorov's avatar Grigory Fedorov

Merge branch 'feature/chat_design' into develop

Conflicts:
	app/build.gradle
	app/src/main/java/com/xabber/android/ui/ChatViewer.java
	app/src/main/java/com/xabber/android/ui/helper/ContactTitleActionBarInflater.java
parents e602df51 aae11448
......@@ -8,8 +8,8 @@ android {
applicationId "com.xabber.androiddev"
minSdkVersion 14
targetSdkVersion 21
versionCode 123
versionName '0.10.23a'
versionCode 129
versionName '0.10.30'
}
buildTypes {
......
......@@ -14,20 +14,6 @@
*/
package com.xabber.android.data.extension.cs;
import java.util.Calendar;
import java.util.Map;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smackx.ChatState;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
......@@ -52,6 +38,20 @@ import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.receiver.ComposingPausedReceiver;
import com.xabber.xmpp.address.Jid;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smackx.ChatState;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import java.util.Calendar;
import java.util.Map;
/**
* Provide information about chat state.
*
......@@ -260,7 +260,7 @@ public class ChatStateManager implements OnDisconnectListener,
pauseIntents.put(account, user, pendingIntent);
}
public void onPaused(Intent intent, String account, String user) {
public void onPaused(String account, String user) {
if (account == null || user == null)
return;
updateChatState(account, user, ChatState.paused);
......
......@@ -30,8 +30,7 @@ public class ComposingPausedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ChatStateManager.getInstance().onPaused(intent, getAccount(intent),
getUser(intent));
ChatStateManager.getInstance().onPaused(getAccount(intent), getUser(intent));
}
public static Intent createIntent(Context context, String account,
......
......@@ -14,13 +14,18 @@
*/
package com.xabber.android.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import com.xabber.android.data.ActivityManager;
......@@ -192,7 +197,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
if (chatState == RoomState.unavailable) {
menu.findItem(R.id.action_join_conference).setVisible(true);
menu.findItem(R.id.action_close_chat).setVisible(true);
} else {
menu.findItem(R.id.action_invite_to_chat).setVisible(true);
......@@ -206,6 +211,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
if (abstractChat instanceof RegularChat) {
menu.findItem(R.id.action_edit_contact).setVisible(true);
menu.findItem(R.id.action_close_chat).setVisible(true);
SecurityLevel securityLevel = OTRManager.getInstance().getSecurityLevel(account, user);
......@@ -386,7 +392,7 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
private void cleatInputText(String account, String user) {
for (ChatViewerFragment chat : registeredChats) {
if (chat.isEqual(account, user)) {
chat.clearInputView();
chat.clearInputText();
}
}
}
......@@ -451,8 +457,8 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
}
private void selectPage(int position, boolean smoothScroll) {
viewPager.setCurrentItem(position, smoothScroll);
onPageSelected(position);
viewPager.setCurrentItem(position, smoothScroll);
}
private static String getAccount(Intent intent) {
......@@ -596,6 +602,8 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
@Override
public void onPageSelected(int position) {
hideKeyboard(this);
AbstractChat selectedChat = chatViewerAdapter.getChatByPageNumber(position);
isChatSelected = selectedChat != null;
......@@ -687,6 +695,49 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
insertExtraText();
updateRegisteredChats();
Fragment currentFragment = chatViewerAdapter.getCurrentFragment();
if (isChatSelected) {
if (!(currentFragment instanceof ChatViewerFragment)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Debug message")
.setMessage("Recent chats selected, but contact chat expected. Reselecting...")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
selectPage(actionWithAccount, actionWithUser, false);
}
});
builder.create().show();
} else if (!((ChatViewerFragment) currentFragment).isEqual(actionWithAccount, actionWithUser)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Debug message")
.setMessage("Wrong contact chat selected. Reselecting...")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
selectPage(actionWithAccount, actionWithUser, false);
}
});
builder.create().show();
}
} else {
if (!(currentFragment instanceof RecentChatFragment)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Debug message")
.setMessage("Contact chat selected, but recent chats expected. Reselecting...")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
selectPage(null, null, false);
}
});
builder.create().show();
}
}
}
private void insertExtraText() {
......@@ -710,15 +761,24 @@ public class ChatViewer extends ManagedActivity implements OnChatChangedListener
}
@Override
public void onRecentChatSelected(AbstractChat chat) {
public void onChatSelected(AbstractChat chat) {
selectPage(chat.getAccount(), chat.getUser(), true);
}
public void selectRecentChatsPage() {
viewPager.setCurrentItem(chatViewerAdapter.getRecentChatsPosition(), true);
selectPage(null, null, false);
}
public ChatViewerAdapter getChatViewerAdapter() {
return chatViewerAdapter;
}
public static void hideKeyboard(Activity activity) {
// Check if no view has focus:
View view = activity.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
......@@ -92,12 +92,12 @@ public class RecentChatFragment extends ListFragment {
super.onListItemClick(l, v, position, id);
if (null != listener) {
listener.onRecentChatSelected((AbstractChat) getListAdapter().getItem(position));
listener.onChatSelected((AbstractChat) getListAdapter().getItem(position));
}
}
public interface RecentChatFragmentInteractionListener {
public void onRecentChatSelected(AbstractChat chat);
public void onChatSelected(AbstractChat chat);
}
public void updateChats(List<AbstractChat> chats) {
......
......@@ -32,7 +32,6 @@ import android.widget.TextView;
import com.xabber.android.data.SettingsManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.ui.helper.AbstractAvatarInflaterHelper;
import com.xabber.androiddev.R;
/**
......@@ -46,7 +45,6 @@ public abstract class BaseContactInflater {
final LayoutInflater layoutInflater;
final AbstractAvatarInflaterHelper avatarInflaterHelper;
/**
* Repeated shadow for drawable.
......@@ -62,7 +60,6 @@ public abstract class BaseContactInflater {
public BaseContactInflater(Activity activity) {
this.activity = activity;
layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
avatarInflaterHelper = AbstractAvatarInflaterHelper.createAbstractContactInflaterHelper();
Bitmap bitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.shadow);
shadowDrawable = new BitmapDrawable(activity.getResources(), bitmap);
......@@ -128,7 +125,6 @@ public abstract class BaseContactInflater {
if (SettingsManager.contactsShowAvatars()) {
viewHolder.avatar.setVisibility(View.VISIBLE);
viewHolder.avatar.setImageDrawable(abstractContact.getAvatarForContactList());
avatarInflaterHelper.updateAvatar(viewHolder.avatar, abstractContact);
((RelativeLayout.LayoutParams) viewHolder.panel.getLayoutParams())
.addRule(RelativeLayout.RIGHT_OF, R.id.avatar);
} else {
......
......@@ -13,7 +13,6 @@ import com.xabber.android.data.message.MessageManager;
import com.xabber.android.data.notification.NotificationManager;
import com.xabber.android.data.roster.AbstractContact;
import com.xabber.android.data.roster.RosterManager;
import com.xabber.android.ui.helper.AbstractAvatarInflaterHelper;
import com.xabber.androiddev.R;
import java.util.ArrayList;
......@@ -23,15 +22,12 @@ public class ChatListAdapter extends BaseAdapter {
private List<AbstractChat> chats;
private final AbstractAvatarInflaterHelper avatarInflaterHelper;
private final Context context;
public ChatListAdapter(Context context) {
this.context = context;
chats = new ArrayList<>();
avatarInflaterHelper = AbstractAvatarInflaterHelper.createAbstractContactInflaterHelper();
}
public void updateChats(List<AbstractChat> chats) {
......@@ -73,7 +69,6 @@ public class ChatListAdapter extends BaseAdapter {
final ImageView avatarView = (ImageView) view.findViewById(R.id.avatar);
avatarView.setImageDrawable(abstractContact.getAvatar());
avatarInflaterHelper.updateAvatar(avatarView, abstractContact);
final TextView textView = (TextView) view.findViewById(R.id.text);
......
......@@ -32,6 +32,7 @@ public class ChatViewerAdapter extends FragmentStatePagerAdapter {
private static final int TOTAL_COUNT = 200;
private static final int OFFSET = TOTAL_COUNT / 2;
private Fragment currentFragment;
public ChatViewerAdapter(FragmentManager fragmentManager, String account, String user, FinishUpdateListener finishUpdateListener) {
super(fragmentManager);
......@@ -133,10 +134,6 @@ public class ChatViewerAdapter extends FragmentStatePagerAdapter {
return realPosition + OFFSET;
}
public int getRecentChatsPosition() {
return OFFSET;
}
public AbstractChat getChatByPageNumber(int virtualPosition) {
int realPosition = getRealPagePosition(virtualPosition);
......@@ -182,4 +179,19 @@ public class ChatViewerAdapter extends FragmentStatePagerAdapter {
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (currentFragment instanceof ChatViewerFragment) {
((ChatViewerFragment)currentFragment).saveInputState();
}
currentFragment = (Fragment) object;
}
public Fragment getCurrentFragment() {
return currentFragment;
}
}
\ No newline at end of file
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.helper;
import android.widget.ImageView;
import com.xabber.android.data.Application;
import com.xabber.android.data.roster.AbstractContact;
/**
* Helper class to update avatar's contact item.
*
* @author alexander.ivanov
*/
public abstract class AbstractAvatarInflaterHelper {
/**
* Update avatar image view.
*
* @param avatar
* @param abstractContact
*/
public abstract void updateAvatar(ImageView avatar,
AbstractContact abstractContact);
/**
* @return New instance depend on whether new system contact list is
* supported.
*/
public static AbstractAvatarInflaterHelper createAbstractContactInflaterHelper() {
if (Application.getInstance().isContactsSupported())
return new AvatarInflaterHelper();
else
return new DummyAvatarInflaterHelper();
}
}
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.helper;
import android.annotation.TargetApi;
import android.provider.ContactsContract;
import android.widget.ImageView;
import android.widget.QuickContactBadge;
import com.xabber.android.data.roster.AbstractContact;
/**
* Helper class to add quick contact badge to the inflated contact item.
*
* @author alexander.ivanov
*/
@TargetApi(5)
public class AvatarInflaterHelper extends AbstractAvatarInflaterHelper {
@Override
public void updateAvatar(ImageView avatar, AbstractContact abstractContact) {
QuickContactBadge badge = (QuickContactBadge) avatar;
badge.assignContactFromEmail(abstractContact.getUser(), true);
badge.setMode(ContactsContract.QuickContact.MODE_SMALL);
}
}
package com.xabber.android.ui.helper;
import android.content.res.TypedArray;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.support.v7.app.ActionBar;
......@@ -30,6 +31,8 @@ public class ContactTitleActionBarInflater {
private Animation shakeAnimation = null;
private ColorDrawable defaultActionBarBackground;
public ContactTitleActionBarInflater(ActionBarActivity activity) {
this.activity = activity;
}
......@@ -39,10 +42,9 @@ public class ContactTitleActionBarInflater {
accountStatusBarColors = activity.getResources().getIntArray(R.array.account_status_bar);
ActionBar actionBar = activity.getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
actionBarView = LayoutInflater.from(activity).inflate(R.layout.contact_title, null);
......@@ -55,9 +57,15 @@ public class ContactTitleActionBarInflater {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
defaultStatusBarColor = window.getStatusBarColor();
}
TypedArray a = activity.getTheme().obtainStyledAttributes(R.style.Theme, new int[] {R.attr.colorPrimary});
int attributeResourceId = a.getResourceId(0, 0);
defaultActionBarBackground = new ColorDrawable(activity.getResources().getColor(attributeResourceId));
}
public void update(AbstractContact abstractContact) {
activity.getSupportActionBar().setDisplayShowCustomEnabled(true);
activity.getSupportActionBar().setDisplayShowTitleEnabled(false);
actionBarView.setVisibility(View.VISIBLE);
......@@ -71,13 +79,15 @@ public class ContactTitleActionBarInflater {
}
public void restoreDefaultTitleView(String title) {
activity.getSupportActionBar().setDisplayShowCustomEnabled(false);
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
actionBarView.setVisibility(View.GONE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(defaultStatusBarColor);
}
activity.getSupportActionBar().setBackgroundDrawable(null);
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
actionBarView.setVisibility(View.GONE);
activity.getSupportActionBar().setBackgroundDrawable(defaultActionBarBackground);
activity.setTitle(title);
}
......
......@@ -54,6 +54,7 @@ public class ContactTitleInflater {
titleView.setBackgroundDrawable(new ColorDrawable(accountActionBarColors[
AccountManager.getInstance().getColorLevel(abstractContact.getAccount())]));
nameView.setTextColor(activity.getResources().getColor(R.color.primary_text_default_material_dark));
nameView.setText(abstractContact.getName());
statusModeView.setImageLevel(abstractContact.getStatusMode().getStatusLevel());
avatarView.setImageDrawable(abstractContact.getAvatar());
......
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.ui.helper;
import android.widget.ImageView;
import com.xabber.android.data.roster.AbstractContact;
/**
* This dummy implementation do nothing.
*
* @author alexander.ivanov
*/
public class DummyAvatarInflaterHelper extends AbstractAvatarInflaterHelper {
@Override
public void updateAvatar(ImageView avatar, AbstractContact abstractContact) {
}
}
......@@ -14,10 +14,14 @@
*/
package com.xabber.android.utils;
import android.content.Context;
import android.content.res.Resources;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import android.content.res.Resources;
import java.util.GregorianCalendar;
/**
* Helper class to get plural forms.
......@@ -32,7 +36,7 @@ public class StringUtils {
static {
DATE_TIME = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.SHORT);
TIME = DateFormat.getTimeInstance(DateFormat.MEDIUM);
TIME = new SimpleDateFormat("H:mm");
}
private StringUtils() {
......@@ -120,17 +124,29 @@ public class StringUtils {
* @param timeStamp
* @return String with time or with date and time depend on current time.
*/
public static String getSmartTimeText(Date timeStamp) {
if (timeStamp == null)
public static String getSmartTimeText(Context context, Date timeStamp) {
if (timeStamp == null) {
return "";
Date date = new Date();
long delta = date.getTime() - timeStamp.getTime();
if (delta < 20 * 60 * 60 * 1000)
}
// today
Calendar midnight = new GregorianCalendar();
// reset hour, minutes, seconds and millis
midnight.set(Calendar.HOUR_OF_DAY, 0);
midnight.set(Calendar.MINUTE, 0);
midnight.set(Calendar.SECOND, 0);
midnight.set(Calendar.MILLISECOND, 0);
DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(context);
if (timeStamp.getTime() > midnight.getTimeInMillis()) {
synchronized (TIME) {
return TIME.format(timeStamp);
return timeFormat.format(timeStamp);
}
else
return getDateTimeText(timeStamp);
} else {
DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context);
return dateFormat.format(timeStamp) + " " + timeFormat.format(timeStamp);
}
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment