diff --git a/.gitignore b/.gitignore index 8bdd78a..ac5c454 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /captures /.idea *.iml +/app/src/main/java/saberapplications/pawpads/Util.java diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 2b6562c..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 121cdd4..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/LICENSE b/LICENSE index c1ab6ff..2c5af2b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License +git MIT License Copyright (c) 2016 Adam Szablya diff --git a/app/app-release.apk b/app/app-release.apk deleted file mode 100644 index 8c54ba1..0000000 Binary files a/app/app-release.apk and /dev/null differ diff --git a/app/build.gradle b/app/build.gradle index 04c27b1..300287d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,16 +20,34 @@ repositories { } android { - compileSdkVersion 23 - buildToolsVersion '23.0.3' + signingConfigs { + config { + keyAlias 'debug_key' + keyPassword 'RHe4bFgysjU' + storeFile file('../pawpads_debug.jks') + storePassword 'RHe4bFgysjU' + /* + Certificate fingerprints: + MD5: CD:A2:FB:81:0A:16:E6:41:B7:EF:4A:D4:6C:E6:DC:8E + SHA1: 27:51:F6:17:6F:A8:86:EC:73:46:B6:58:D8:F8:73:84:ED:AF:F6:47 + SHA256: 63:F9:79:84:56:9E:B8:C5:44:68:3A:CD:69:D8:46:71:50:34:66:B3:A7:6A:8A:D3:68:5E:C5:19:4E:3F:6D:8A + Signature algorithm name: SHA256withRSA + Version: 3 + FB hash: J1H2F2+ohuxzRrZY2PhzhO2v9kc= + */ + } + } + + compileSdkVersion 25 + buildToolsVersion '25.0.3' defaultConfig { applicationId "saberapplications.pawpads" minSdkVersion 15 targetSdkVersion 23 - versionCode 33 + versionCode 40 - versionName "2.5.2" + versionName "2.6.0" // Enabling multidex support. multiDexEnabled true @@ -44,6 +62,9 @@ android { // debug { // debuggable true // } + debug { + signingConfig signingConfigs.config + } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 @@ -58,41 +79,35 @@ android { } dependencies { - - - compile('com.twitter.sdk.android:twitter-core:2.0.0@aar') { - transitive = true; - } - - compile 'com.google.android.gms:play-services-ads:9.6.1' + compile 'com.twitter.sdk.android:twitter:3.0.0' compile 'com.quickblox:quickblox-android-sdk-core:2.6.1' compile 'com.quickblox:quickblox-android-sdk-chat:2.6.1' compile 'com.quickblox:quickblox-android-sdk-messages:2.6.1' compile 'com.quickblox:quickblox-android-sdk-location:2.6.1' compile 'com.quickblox:quickblox-android-sdk-content:2.6.1' compile 'com.quickblox:quickblox-android-sdk-customobjects:2.6.1' - compile 'com.android.support.constraint:constraint-layout:1.0.0-beta5' - compile 'com.android.support:design:23.4.0' - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:gridlayout-v7:23.4.0' - compile 'com.android.support:support-v4:23.4.0' - compile 'com.google.android.gms:play-services:9.6.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:gridlayout-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.google.android.gms:play-services-ads:11.0.0' + compile 'com.google.android.gms:play-services-plus:11.0.0' + compile 'com.google.android.gms:play-services-identity:11.0.0' + compile 'com.google.android.gms:play-services-gcm:11.0.0' + compile 'com.google.android.gms:play-services-location:11.0.0' compile 'com.android.support:multidex:1.0.1' compile 'com.squareup.retrofit:retrofit:1.9.0' - compile 'com.google.android.gms:play-services-identity:9.6.1' - compile 'com.google.android.gms:play-services-gcm:9.6.1' compile 'com.facebook.android:facebook-android-sdk:[4,5)' compile 'com.makeramen:roundedimageview:2.2.1' - compile('com.crashlytics.sdk.android:crashlytics:2.6.6@aar') { + compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { transitive = true; } - compile ('io.imoji.sdk:imoji-sdk-ui:+@aar') { - transitive=true + compile('io.imoji.sdk:imoji-sdk-ui:+@aar') { + transitive = true } - compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' - compile 'com.github.bumptech.glide:glide:3.7.0' - + compile 'org.greenrobot:eventbus:3.0.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8777d8a..e3f8860 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -121,6 +121,35 @@ android:label="@string/About" android:screenOrientation="portrait" /> + + + + + + + + + + + + + getFriendOutInvitesList() { + SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()); + return defaultSharedPreferences.getStringSet(C.FRIEND_OUT_INVITES_LIST, new HashSet()); + } + + public static void addFriendOutInviteToList(int userId) { + Set outInvites = getFriendOutInvitesList(); + outInvites.add(String.valueOf(userId)); + SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()).edit(); + editor.putStringSet(C.FRIEND_OUT_INVITES_LIST, outInvites); + editor.apply(); + } + + + public static Set getFriendAcceptedList() { + SharedPreferences defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()); + return defaultSharedPreferences.getStringSet(C.FRIEND_ACCEPTED_LIST, new HashSet()); + } + + public static void addFriendAcceptedList(int userId) { + Set outInvites = getFriendAcceptedList(); + outInvites.add(String.valueOf(userId)); + SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()).edit(); + editor.putStringSet(C.FRIEND_ACCEPTED_LIST, outInvites); + editor.apply(); + } + public static void removeFriendAcceptedList(int userId) { + Set outInvites = getFriendAcceptedList(); + outInvites.remove(String.valueOf(userId)); + SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()).edit(); + editor.putStringSet(C.FRIEND_ACCEPTED_LIST, outInvites); + editor.apply(); + } + + public static void removeFriendOutInviteFromList(int userId) { + Set outInvites = getFriendOutInvitesList(); + outInvites.remove(String.valueOf(userId)); + SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(PawPadsApplication.getInstance()).edit(); + editor.putStringSet(C.FRIEND_OUT_INVITES_LIST, outInvites); + editor.apply(); + } } diff --git a/app/src/main/java/saberapplications/pawpads/events/FriendRemovedEvent.java b/app/src/main/java/saberapplications/pawpads/events/FriendRemovedEvent.java new file mode 100644 index 0000000..8318a70 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/events/FriendRemovedEvent.java @@ -0,0 +1,20 @@ +package saberapplications.pawpads.events; + +import com.quickblox.users.model.QBUser; + +/** + * Created by Stanislav Volnjanskij on 6/15/17. + */ + +public class FriendRemovedEvent { + + QBUser user; + + public FriendRemovedEvent(QBUser user) { + this.user = user; + } + + public QBUser getUser() { + return user; + } +} diff --git a/app/src/main/java/saberapplications/pawpads/events/UpdateChatEvent.java b/app/src/main/java/saberapplications/pawpads/events/UpdateChatEvent.java new file mode 100644 index 0000000..a22d9aa --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/events/UpdateChatEvent.java @@ -0,0 +1,11 @@ +package saberapplications.pawpads.events; + +/** + * Created by developer on 13.06.17. + */ + +public class UpdateChatEvent { + + public UpdateChatEvent() { + } +} diff --git a/app/src/main/java/saberapplications/pawpads/ui/BaseActivity.java b/app/src/main/java/saberapplications/pawpads/ui/BaseActivity.java index a128260..78a0d8c 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/BaseActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/BaseActivity.java @@ -22,11 +22,15 @@ import com.google.android.gms.location.LocationListener; import com.quickblox.auth.QBAuth; import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBGroupChat; import com.quickblox.chat.QBPrivacyListsManager; import com.quickblox.chat.QBPrivateChat; +import com.quickblox.chat.QBSystemMessagesManager; import com.quickblox.chat.exception.QBChatException; +import com.quickblox.chat.listeners.QBGroupChatManagerListener; import com.quickblox.chat.listeners.QBMessageListener; import com.quickblox.chat.listeners.QBPrivateChatManagerListener; +import com.quickblox.chat.listeners.QBSystemMessageListener; import com.quickblox.chat.model.QBChatMessage; import com.quickblox.chat.model.QBPrivacyList; import com.quickblox.core.QBEntityCallback; @@ -34,6 +38,7 @@ import com.quickblox.core.exception.QBResponseException; import com.quickblox.users.model.QBUser; +import org.greenrobot.eventbus.EventBus; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; @@ -43,8 +48,10 @@ import saberapplications.pawpads.R; import saberapplications.pawpads.UserStatusHelper; import saberapplications.pawpads.Util; +import saberapplications.pawpads.events.UpdateChatEvent; import saberapplications.pawpads.service.UserLocationService; import saberapplications.pawpads.ui.chat.ChatActivity; +import saberapplications.pawpads.ui.chat.ChatGroupActivity; import saberapplications.pawpads.ui.home.SplashActivity; @@ -74,6 +81,8 @@ public void chatCreated(QBPrivateChat qbPrivateChat, final boolean createdLocall qbPrivateChat.addMessageListener(new QBMessageListener() { @Override public void processMessage(final QBPrivateChat qbPrivateChat, final QBChatMessage qbChatMessage) { + EventBus.getDefault().post(qbChatMessage); + if(isFinishing()) return; BaseActivity.this.runOnUiThread(new Runnable() { @Override public void run() { @@ -86,6 +95,7 @@ public void run() { @Override public void processError(QBPrivateChat qbPrivateChat, QBChatException e, QBChatMessage qbChatMessage) { + if(isFinishing()) return; Util.onError(e, BaseActivity.this); } @@ -94,6 +104,56 @@ public void processError(QBPrivateChat qbPrivateChat, QBChatException e, QBChatM } }; + protected QBGroupChatManagerListener groupChatListener = new QBGroupChatManagerListener() { + @Override + public void chatCreated(QBGroupChat qbGroupChat) { + qbGroupChat.addMessageListener(new QBMessageListener() { + @Override + public void processMessage(final QBGroupChat qbGroupChat, final QBChatMessage qbChatMessage) { + if(isFinishing()) return; + EventBus.getDefault().post(qbChatMessage); + BaseActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + onGroupChatMessage(qbGroupChat, qbChatMessage); + UserStatusHelper.setUserStatusByNewMessage(qbChatMessage.getSenderId()); + } + }); + + } + + @Override + public void processError(QBGroupChat qbGroupChat, QBChatException e, QBChatMessage qbChatMessage) { + if(isFinishing()) return; + Util.onError(e, BaseActivity.this); + } + + }); + } + }; + + private QBSystemMessagesManager systemMessagesManager; + + private QBSystemMessageListener systemMessageListener = new QBSystemMessageListener() { + @Override + public void processMessage(final QBChatMessage qbChatMessage) { + if(isFinishing()) return; + BaseActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + onGroupChatMessage(null, qbChatMessage); + UserStatusHelper.setUserStatusByNewMessage(qbChatMessage.getSenderId()); + } + }); + } + + @Override + public void processError(QBChatException e, QBChatMessage qbChatMessage) { + if(isFinishing()) return; + Util.onError(e, BaseActivity.this); + } + }; + BroadcastReceiver locationChanged = new BroadcastReceiver() { @Override @@ -169,6 +229,9 @@ locationChanged, new IntentFilter(UserLocationService.LOCATION_CHANGED) reconnectToChat(); }else{ QBChatService.getInstance().getPrivateChatManager().addPrivateChatManagerListener(chatListener); + QBChatService.getInstance().getGroupChatManager().addGroupChatManagerListener(groupChatListener); + systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager(); + systemMessagesManager.addSystemMessageListener(systemMessageListener); } @@ -205,6 +268,9 @@ protected void onStop() { if (QBChatService.getInstance().getPrivateChatManager() != null) { QBChatService.getInstance().getPrivateChatManager().removePrivateChatManagerListener(chatListener); } + if (QBChatService.getInstance().getGroupChatManager() != null) { + QBChatService.getInstance().getGroupChatManager().addGroupChatManagerListener(groupChatListener); + } isReopened = true; } @@ -250,6 +316,8 @@ public void onSuccess(Object o, Bundle bundle) { list.setActiveList(true); } } + QBChatService.getInstance().getPrivateChatManager().addPrivateChatManagerListener(chatListener); + QBChatService.getInstance().getGroupChatManager().addGroupChatManagerListener(groupChatListener); } catch (SmackException.NotConnectedException e) { e.printStackTrace(); } catch (XMPPException.XMPPErrorException e) { @@ -259,6 +327,9 @@ public void onSuccess(Object o, Bundle bundle) { } QBChatService.getInstance().getPrivateChatManager().addPrivateChatManagerListener(chatListener); + QBChatService.getInstance().getGroupChatManager().addGroupChatManagerListener(groupChatListener); + systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager(); + systemMessagesManager.addSystemMessageListener(systemMessageListener); runOnUiThread(new Runnable() { @Override public void run() { @@ -346,6 +417,7 @@ public boolean isLoggedIn() { } public void onChatMessage(QBPrivateChat qbPrivateChat, final QBChatMessage qbChatMessage) { + EventBus.getDefault().post(new UpdateChatEvent()); if (Util.IM_ALERT) { new AlertDialog.Builder(BaseActivity.this) .setTitle(R.string.new_chat_message) @@ -354,7 +426,7 @@ public void onChatMessage(QBPrivateChat qbPrivateChat, final QBChatMessage qbCha @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(BaseActivity.this, ChatActivity.class); - intent.putExtra(ChatActivity.DIALOG_ID, qbChatMessage.getDialogId().toString()); + intent.putExtra(ChatActivity.DIALOG_ID, qbChatMessage.getDialogId()); intent.putExtra(ChatActivity.RECIPIENT_ID, qbChatMessage.getSenderId()); startActivity(intent); } @@ -364,6 +436,31 @@ public void onClick(DialogInterface dialog, int which) { } } + public void onGroupChatMessage(QBGroupChat qbGroupChat, final QBChatMessage qbChatMessage) { + EventBus.getDefault().post(new UpdateChatEvent()); + if (Util.IM_ALERT) { + new AlertDialog.Builder(BaseActivity.this) + .setTitle(R.string.new_chat_message) + .setMessage(qbChatMessage.getBody()) + .setPositiveButton("Open chat", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(BaseActivity.this, ChatGroupActivity.class); + String dialogId; + if(qbChatMessage.getDialogId() != null && !qbChatMessage.getDialogId().equals("null")) { + dialogId = qbChatMessage.getDialogId(); + } else { + dialogId = qbChatMessage.getProperty("_id").toString(); + } + intent.putExtra(ChatActivity.DIALOG_ID, dialogId); + startActivity(intent); + } + }) + .setNegativeButton("Cancel", null) + .show(); + } + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/app/src/main/java/saberapplications/pawpads/ui/GroupEditActivity.java b/app/src/main/java/saberapplications/pawpads/ui/GroupEditActivity.java new file mode 100644 index 0000000..d2835e3 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/GroupEditActivity.java @@ -0,0 +1,536 @@ +package saberapplications.pawpads.ui; + +import android.Manifest; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.databinding.DataBindingUtil; +import android.graphics.Bitmap; +import android.media.ThumbnailUtils; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v4.util.ArrayMap; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.Toast; + +import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBGroupChat; +import com.quickblox.chat.QBGroupChatManager; +import com.quickblox.chat.model.QBDialog; +import com.quickblox.chat.model.QBDialogType; +import com.quickblox.chat.request.QBDialogRequestBuilder; +import com.quickblox.content.QBContent; +import com.quickblox.content.model.QBFile; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBPagedRequestBuilder; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import org.greenrobot.eventbus.EventBus; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.Util; +import saberapplications.pawpads.databinding.ActivityEditGroupBinding; +import saberapplications.pawpads.databinding.BindableBoolean; +import saberapplications.pawpads.databinding.BindableString; +import saberapplications.pawpads.databinding.RowParticipantsBinding; +import saberapplications.pawpads.events.UpdateChatEvent; +import saberapplications.pawpads.ui.chat.ChatGroupActivity; +import saberapplications.pawpads.ui.chat.CreateChatActivity; +import saberapplications.pawpads.ui.home.MainActivity; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.util.FileUtil; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 30.05.17. + */ + +public class GroupEditActivity extends BaseActivity { + private final static int SELECT_IMAGE = 1; + private static final int PERMISSION_REQUEST = 200; + private static final int CHANGE_PROFILE_PICTURE = 1; + public static final String DIALOG = "dialog"; + public static final int ADD_NEW_GROUP_MEMBER = 25; + public static final String NEW_ADDED_USERS_LIST = "NEW_ADDED_USERS_LIST"; + String selectedImagePath; + + Uri avatarImagePath; + + private SharedPreferences defaultSharedPreferences; + + private Runnable timeOutRunnable; + public final BindableBoolean isBusy = new BindableBoolean(); + public final BindableString progressMessage = new BindableString(); + + private ActivityEditGroupBinding binding; + public final BindableString groupName = new BindableString(); + public final BindableString groupType = new BindableString(); + public final BindableString groupParticipants = new BindableString(); + public final BindableString adminName = new BindableString(); + + private int imageAction; + private QBDialog dialog; + private ArrayList selectedNewGroupUserList; + private ParticipantsAdapter adapter; + private int currentUserId; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_group); + binding.setActivity(this); + setSupportActionBar(binding.toolbar); + + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setTitle(""); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + currentUserId = prefs.getInt(C.QB_USERID, 0); + + progressMessage.set(getString(R.string.loading)); + + adapter = new ParticipantsAdapter(); + binding.participantsListView.setAdapter(adapter); + binding.participantsListView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); + + if (getIntent().hasExtra(DIALOG)) { + dialog = (QBDialog) getIntent().getSerializableExtra(DIALOG); + } + if(dialog != null && dialog.getType() == QBDialogType.PUBLIC_GROUP) { + binding.participantsLayout.setVisibility(View.GONE); + if(currentUserId != dialog.getUserId()) binding.leaveAndDeleteBtn.setVisibility(View.GONE); + } + if(dialog != null && currentUserId != dialog.getUserId()) { + binding.groupAvatar.setEnabled(false); + binding.photoAvatarIcon.setEnabled(false); + binding.groupTitleText.setEnabled(false); + binding.groupTitleText.setCompoundDrawablesWithIntrinsicBounds(0,0,0,0); + binding.save.setVisibility(View.GONE); + } + loadData(); + } + + private void loadData() { + if(dialog == null) return; + isBusy.set(true); + if(adapter != null) adapter.clear(); + defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(GroupEditActivity.this); + + groupName.set(dialog.getName()); + groupType.set(dialog.getType() == QBDialogType.GROUP ? "Private group" : "Channel"); + int ocupantsSize = dialog.getOccupants().size(); + groupParticipants.set("Participants (" + (ocupantsSize == 0 ? ocupantsSize : ocupantsSize-1) + ")"); + binding.groupAvatar.setImageResource(R.drawable.user_placeholder); + + QBUsers.getUser(dialog.getUserId(), new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + + String username = qbUser.getFullName() == null ? qbUser.getLogin() : qbUser.getFullName(); + if(currentUserId == qbUser.getId()) username = "You (" + username + ")"; + adminName.set(username); + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.adminAvatar, + binding.adminAvatar.getWidth(), binding.adminAvatar.getHeight() + , new AvatarLoaderHelper.Callback() { + @Override + public void imageLoaded() { + isBusy.set(false); + } + }); + + } else { + isBusy.set(false); + } + } + + @Override + public void onError(QBResponseException e) { + isBusy.set(false); + Util.onError(e, GroupEditActivity.this); + } + + }); + + getUsers(dialog.getOccupants()); + + if(dialog.getPhoto() != null) { + float d = getResources().getDisplayMetrics().density; + int size = Math.round(100 * d); + try { + AvatarLoaderHelper.loadImage(Integer.parseInt(dialog.getPhoto()), binding.groupAvatar, size, size, null); + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + + + private void onGroupSettingsSaved(String message) { + if (message != null) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show(); + } + loadData(); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == SELECT_IMAGE) { + Uri selectedImageUri = data.getData(); + selectedImagePath = FileUtil.getPath(this, selectedImageUri); + System.out.println("Image Path : " + selectedImagePath); + avatarImagePath = selectedImageUri; + + displayBitmap(avatarImagePath, binding.groupAvatar); + } + if (requestCode == ADD_NEW_GROUP_MEMBER) { + selectedNewGroupUserList = data.getIntegerArrayListExtra(NEW_ADDED_USERS_LIST); + System.out.println("ADD_NEW_GROUP_MEMBER RESULT OK"); + save(); + } + } + } + + private void displayBitmap(final Uri uri, final ImageView view) { + + final int width = view.getWidth(); + final int height = view.getHeight(); + new AsyncTask() { + + @Override + protected Bitmap doInBackground(Void... params) { + Bitmap bitmap = null; + try { + bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); + Bitmap thumb = ThumbnailUtils.extractThumbnail(bitmap, width, height); + bitmap.recycle(); + return thumb; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null) + view.setImageBitmap(bitmap); + } + }.execute(); + } + + public String getPath(Uri uri) { + return uri.getPath(); + } + + + public void changeGroupPicture() { + imageAction = CHANGE_PROFILE_PICTURE; + if (!permissionCheck()) return; + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("image/*"); + startActivityForResult(intent, SELECT_IMAGE); + } + + public void save() { + if (isBusy.get()) return; + if (groupName.get().length() < 3) { + Toast.makeText(this, "Group name is too short", Toast.LENGTH_LONG).show(); + return; + } + if (groupName.get().length() > 50) { + Toast.makeText(this, "Group name can not be more than 50 characters", Toast.LENGTH_LONG).show(); + return; + } + + progressMessage.set(getString(R.string.saving)); + isBusy.set(true); + + timeOutRunnable = new Runnable() { + @Override + public void run() { + isBusy.set(false); + Toast.makeText(getApplicationContext(), "Connection timeout", Toast.LENGTH_SHORT).show(); + } + }; + //edit second parameter to set timeout period + final Handler handler = new Handler(); + handler.postDelayed(timeOutRunnable, 30000); + + AsyncTask saveTask = new AsyncTask() { + Exception e; + + @Override + protected Boolean doInBackground(Void... params) { + try { + + if (avatarImagePath != null) { + Bitmap avatar = MediaStore.Images.Media.getBitmap(getContentResolver(), avatarImagePath); + avatar = ThumbnailUtils.extractThumbnail(avatar, 500, 500); + final File file = File.createTempFile("group_photo", ".jpg", getCacheDir()); + FileOutputStream out = new FileOutputStream(file); + avatar.compress(Bitmap.CompressFormat.JPEG, 90, out); + out.close(); + QBFile qbFile = QBContent.uploadFileTask(file, false, file.getAbsolutePath()); + dialog.setPhoto(qbFile.getId().toString()); + file.delete(); + avatar.recycle(); + avatarImagePath = null; + } + + QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + QBDialogRequestBuilder requestBuilder = new QBDialogRequestBuilder(); + if(selectedNewGroupUserList != null) { + for(Integer id : selectedNewGroupUserList) { + requestBuilder.addUsers(id); + } + } + if( !groupName.get().equals(dialog.getName())) { + dialog.setName(groupName.get()); + } + dialog = groupChatManager.updateDialog(dialog, requestBuilder); + selectedNewGroupUserList = null; + + return true; + } catch (Exception e) { + this.e = e; + return false; + } + + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + isBusy.set(false); + handler.removeCallbacks(timeOutRunnable); + if (aBoolean) { + onGroupSettingsSaved("group settings saved"); + Intent resultIntent = new Intent(); + resultIntent.putExtra(ChatGroupActivity.CHANGED_GROUP_NAME, dialog.getName()); + setResult(RESULT_OK, resultIntent); + EventBus.getDefault().post(new UpdateChatEvent()); + } else { + Util.onError(e, GroupEditActivity.this); + } + } + }; + saveTask.execute(); + + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + default: + return super.onOptionsItemSelected(item); + } + + } + + public boolean permissionCheck() { + int permissionCheck = ContextCompat.checkSelfPermission(this, + Manifest.permission.READ_EXTERNAL_STORAGE); + if (permissionCheck != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + PERMISSION_REQUEST); + return false; + } + return true; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + switch (requestCode) { + case PERMISSION_REQUEST: { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + switch (imageAction) { + case CHANGE_PROFILE_PICTURE: + changeGroupPicture(); + break; + } + } + } + } + } + + private void getUsers(List userIdsList) { + if(userIdsList == null || userIdsList.size() == 0) { + adapter.disableLoadMore(); + return; + } + if(userIdsList.contains(dialog.getUserId())) userIdsList.remove(dialog.getUserId()); + isBusy.set(true); + + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + QBUsers.getUsersByIDs(userIdsList, pagedRequestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList users, Bundle params) { + if (users.size() > 0) { + adapter.addItems(users); + } + adapter.disableLoadMore(); + isBusy.set(false); + } + + @Override + public void onError(QBResponseException errors) { + if (getApplicationContext()==null) return; + Util.onError(errors, getApplicationContext()); + adapter.disableLoadMore(); + isBusy.set(false); + } + }); + } + + private class ParticipantsAdapter extends BaseListAdapter { + + int currentUserId; + ArrayMap userCache=new ArrayMap<>(); + + class ParticipantsHolder extends DataHolder{ + + private final int size; + RowParticipantsBinding binding; + ParticipantsAdapter adapter; + + ParticipantsHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + binding= DataBindingUtil.bind(v); + this.adapter= (ParticipantsAdapter) adapter; + float d= view.getResources().getDisplayMetrics().density; + size=Math.round(35 * d); + } + + @Override + public void showData(DataItem data,int position) { + QBUser user = data.model.get(); + String userName = data.model.get().getFullName() == null ? data.model.get().getLogin() : data.model.get().getFullName(); + if(currentUserId == user.getId()) userName = "You (" + userName + ")"; + binding.setUsername(userName); + int userId=user.getId(); + + binding.userAvatar.setImageResource(R.drawable.user_placeholder); + if(!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.userAvatar, size, size); + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + e.printStackTrace(); + } + }); + }else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), binding.userAvatar, size, size); + } + } + } + + @Override + public DataHolder getItemHolder(ViewGroup parent) { + View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_participants,parent,false); + return new ParticipantsAdapter.ParticipantsHolder(v,this); + } + + public void setCurrentUserId(int currentUserId) { + this.currentUserId = currentUserId; + } + + @Override + protected int getEmptyStateResId() { + return R.layout.empty_state_participants; + } + } + + public void addGroupMember() { + Intent intentAddGroupMember = new Intent(this, CreateChatActivity.class); + intentAddGroupMember.putIntegerArrayListExtra(CreateChatActivity.DIALOG_USERS_LIST, ((ArrayList) dialog.getOccupants())); + startActivityForResult(intentAddGroupMember, ADD_NEW_GROUP_MEMBER); + } + + public void leaveAndDeleteGroup() { + isBusy.set(true); + QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + if(groupChatManager == null) return; + QBGroupChat currentChatRoom = groupChatManager.getGroupChat(dialog.getRoomJid()); + try { + currentChatRoom.leave(); + currentChatRoom = null; + } catch (XMPPException e) { + e.printStackTrace(); + } catch (SmackException.NotConnectedException e) { + e.printStackTrace(); + } + + boolean forceDelete = false; + if(currentUserId == dialog.getUserId()) { + forceDelete = true; + } + groupChatManager.deleteDialog(dialog.getDialogId(), forceDelete, new QBEntityCallback() { + @Override + public void onSuccess(Void aVoid, Bundle bundle) { + Util.setCreatedChannelsCount(Util.getCreatedChannelsCount()-1); + isBusy.set(false); + Intent intent = new Intent(GroupEditActivity.this, MainActivity.class); + startActivity(intent); + finish(); + EventBus.getDefault().post(new UpdateChatEvent()); + } + + @Override + public void onError(QBResponseException e) { + isBusy.set(false); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatActivity.java b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatActivity.java index 5811599..e864a49 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatActivity.java @@ -11,6 +11,7 @@ import android.databinding.DataBindingUtil; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.location.Location; import android.media.ThumbnailUtils; import android.net.Uri; import android.os.AsyncTask; @@ -37,6 +38,7 @@ import com.bumptech.glide.load.resource.drawable.GlideDrawable; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; +import com.crashlytics.android.Crashlytics; import com.quickblox.chat.QBChat; import com.quickblox.chat.QBChatService; import com.quickblox.chat.QBPrivacyListsManager; @@ -60,6 +62,7 @@ import com.quickblox.users.QBUsers; import com.quickblox.users.model.QBUser; +import org.greenrobot.eventbus.EventBus; import org.jivesoftware.smack.SmackException; import java.io.File; @@ -87,6 +90,7 @@ import saberapplications.pawpads.databinding.ActivityChatBinding; import saberapplications.pawpads.databinding.BindableBoolean; import saberapplications.pawpads.databinding.BindableInteger; +import saberapplications.pawpads.service.UserLocationService; import saberapplications.pawpads.ui.BaseActivity; import saberapplications.pawpads.ui.profile.ProfileActivity; import saberapplications.pawpads.util.AvatarLoaderHelper; @@ -236,6 +240,7 @@ private void init() { runOnUiThread(new Runnable() { @Override public void run() { + binding.recipientAvatar.setVisibility(View.VISIBLE); if (recipient == null || userDeleted) return; if (recipient.getFileId() != null) { float d = getResources().getDisplayMetrics().density; @@ -366,21 +371,7 @@ protected Void doInBackground(Void... params) { } } } - if (!userDeleted) { - try { - privateChat = privateChatManager.getChat(recipient.getId()); - } catch (NullPointerException e) { - Log.e("QBPrivateChatManager", e.getMessage()); - e.printStackTrace(); - } - if (privateChat == null) { - privateChat = privateChatManager.createChat(recipient.getId(), messageListener); - } else { - privateChat.addMessageListener(messageListener); - } - init(); - } if (dialog == null) { if (getIntent().hasExtra(DIALOG)) { dialog = (QBDialog) getIntent().getSerializableExtra(DIALOG); @@ -391,11 +382,35 @@ protected Void doInBackground(Void... params) { //requestBuilder.eq("date_sent", getIntent().getStringExtra(DIALOG_ID)); Bundle bundle = new Bundle(); - ArrayList dialogs = QBChatService.getChatDialogs(QBDialogType.PRIVATE, requestBuilder, bundle); + ArrayList dialogs = QBChatService.getChatDialogs(null, requestBuilder, bundle); dialog = dialogs.get(0); } } + if (dialog != null && dialog.getType() != QBDialogType.PRIVATE) { + ArrayList occupansts = (ArrayList) dialog.getOccupants(); + Intent intent = new Intent(ChatActivity.this, ChatGroupActivity.class); + intent.putExtra(ChatGroupActivity.DIALOG, dialog); + intent.putExtra(ChatGroupActivity.RECIPIENT_IDS_LIST, occupansts); + startActivity(intent); + finish(); + return null; + } + + if (!userDeleted) { + try { + privateChat = privateChatManager.getChat(recipient.getId()); + } catch (NullPointerException e) { + Log.e("QBPrivateChatManager", e.getMessage()); + e.printStackTrace(); + } + if (privateChat == null) { + privateChat = privateChatManager.createChat(recipient.getId(), messageListener); + } else { + privateChat.addMessageListener(messageListener); + } + init(); + } if (dialog == null) { dialog = privateChatManager.createDialog(recipient.getId()); @@ -445,8 +460,10 @@ protected void onPostExecute(Void aVoid) { isBusy.set(false); if (error != null) { Util.onError(error, ChatActivity.this); + Crashlytics.logException(error); return; } + if(chatMessages == null) return; if (!isActivityReopened) { chatAdapter.addItems(chatMessages); if (chatMessages.size() < messagesPerPage) { @@ -543,11 +560,14 @@ public void sendChatMessage() { msg.setRecipientId(recipient.getId()); msg.setDialogId(dialog.getDialogId()); msg.setProperty("send_to_chat", "1"); - - + Location location=UserLocationService.getLastLocation(); + if (location!=null){ + msg.setProperty(C.LATITUDE, String.valueOf(location.getLatitude())); + msg.setProperty(C.LONGITUDE, String.valueOf(location.getLongitude())); } try { privateChat.sendMessage(msg); displayChatMessage(msg); + EventBus.getDefault().post(msg); } catch (SmackException.NotConnectedException e) { if (!isNetworkAvailable()) { Util.onError(getString(R.string.verify_internet_connection), this); @@ -559,6 +579,7 @@ public void sendChatMessage() { } } catch (Exception e) { Util.onError(e, ChatActivity.this); + Crashlytics.logException(e); } editText_chat_message.setText(""); } @@ -639,6 +660,7 @@ protected void onPostExecute(QBChatMessage qbChatMessage) { isBusy.set(false); if (exception != null) { Util.onError(exception, ChatActivity.this); + Crashlytics.logException(exception); return; } displayChatMessage(qbChatMessage); @@ -679,6 +701,7 @@ public void sendSticker(Uri uri) { Toast.makeText(this, R.string.reconnect_message, Toast.LENGTH_LONG).show(); } } catch (Exception e) { + Crashlytics.logException(e); Util.onError(e, ChatActivity.this); } } @@ -686,6 +709,7 @@ public void sendSticker(Uri uri) { } public void onClickImoji() { + if(binding.getShowGiphy()) onClickGiphy(); if (mStickersContainer != null && mStickersContainer.getChildCount() == 0) { hideSoftKeyboard(); mStickersContainer.addView(mStickersWidget); diff --git a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupActivity.java b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupActivity.java new file mode 100644 index 0000000..4d0ca93 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupActivity.java @@ -0,0 +1,1019 @@ +package saberapplications.pawpads.ui.chat; + +import android.Manifest; +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.databinding.DataBindingUtil; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.location.Location; +import android.media.ThumbnailUtils; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.provider.MediaStore; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v4.content.LocalBroadcastManager; +import android.support.v7.app.AlertDialog; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.Toast; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; +import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBGroupChat; +import com.quickblox.chat.QBGroupChatManager; +import com.quickblox.chat.QBSystemMessagesManager; +import com.quickblox.chat.exception.QBChatException; +import com.quickblox.chat.listeners.QBMessageListener; +import com.quickblox.chat.listeners.QBSystemMessageListener; +import com.quickblox.chat.model.QBAttachment; +import com.quickblox.chat.model.QBChatMessage; +import com.quickblox.chat.model.QBDialog; +import com.quickblox.chat.model.QBDialogType; +import com.quickblox.chat.request.QBDialogRequestBuilder; +import com.quickblox.content.QBContent; +import com.quickblox.content.model.QBFile; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.QBProgressCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBPagedRequestBuilder; +import com.quickblox.core.request.QBRequestGetBuilder; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import org.greenrobot.eventbus.EventBus; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smackx.muc.DiscussionHistory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import io.imoji.sdk.editor.ImojiCreateService; +import io.imoji.sdk.editor.ImojiEditorActivity; +import io.imoji.sdk.editor.util.EditorBitmapCache; +import io.imoji.sdk.grid.QuarterScreenWidget; +import io.imoji.sdk.grid.components.SearchResultAdapter; +import io.imoji.sdk.grid.components.WidgetDisplayOptions; +import io.imoji.sdk.grid.components.WidgetListener; +import io.imoji.sdk.objects.Imoji; +import io.imoji.sdk.objects.RenderingOptions; +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.Util; +import saberapplications.pawpads.databinding.ActivityChatGroupBinding; +import saberapplications.pawpads.databinding.BindableBoolean; +import saberapplications.pawpads.databinding.BindableInteger; +import saberapplications.pawpads.service.UserLocationService; +import saberapplications.pawpads.ui.BaseActivity; +import saberapplications.pawpads.ui.GroupEditActivity; +import saberapplications.pawpads.util.FileUtil; +import saberapplications.pawpads.views.BaseListAdapter; +import saberapplications.pawpads.views.giphyselector.Giphy; +import saberapplications.pawpads.views.giphyselector.GiphySelector; + + +public class ChatGroupActivity extends BaseActivity { + public static final String DIALOG = "dialog"; + public static final String DIALOG_ID = "dialog_id"; + public static final String CURRENT_USER_ID = "current user id"; + public static final String RECIPIENT_IDS_LIST = "recipient_ids_list"; + public static final String NEW_ADDED_USERS_LIST = "NEW_ADDED_USERS_LIST"; + public static final String CHANGED_GROUP_NAME = "CHANGED_GROUP_NAME"; + public static final String DIALOG_GROUP_TYPE = "DIALOG_GROUP_TYPE"; + public static final String IS_FIRST_OPENED = "IS_FIRST_OPENED"; + public static final int ADD_NEW_GROUP_MEMBER = 25; + public static final int GROUP_SETTINGS_CHANGE = 26; + private static final int PICKFILE_REQUEST_CODE = 2; + private static final int IMAGE_CAPTURE_REQUEST_CODE = 33; + private static final int READ_STORAGE_PERMISSION_REQUEST = 200; + private static final int WRITE_ST_CAMERA_PERMISSION_REQUEST = 205; + private static final int PICK_FILE_FOR_EDIT_REQUEST = 3; + public final BindableBoolean isSendingMessage = new BindableBoolean(); + public final BindableInteger uploadProgress = new BindableInteger(0); + public final BindableBoolean isBusy = new BindableBoolean(true); + //EditText editText_mail_id; + EditText editText_chat_message; + Button button_send_chat; + Bundle savedInstanceState; + ActivityChatGroupBinding binding; + int currentPage = 0; + int messagesPerPage = 15; + long paused; + boolean gotMessagesInOffline = false; + private Uri mPhotoUri; + // BroadcastReceiver recieve_chat; + private QBDialog dialog; + private QuarterScreenWidget mStickersWidget; + private FrameLayout mStickersContainer; + BroadcastReceiver updateChatReciever = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (dialog.getDialogId().equals(intent.getStringExtra(DIALOG_ID))) { + gotMessagesInOffline = true; + } + } + }; + + private ArrayList userIdsList; + private ArrayList recipientList; + private ArrayList selectedNewGroupUserList; + private ChatGroupMessagesAdapter chatAdapter; + private FrameLayout blockedContainer; + private ViewGroup messageContainer; + + private QBMessageListener groupChatMessageListener = new QBMessageListener() { + @Override + public void processMessage(final QBGroupChat groupChat, final QBChatMessage qbChatMessage) { + ChatGroupActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + if (currentUserId != null && qbChatMessage.getSenderId().intValue() != currentUserId.intValue()) { + displayChatMessage(qbChatMessage); + } + } + }); + } + + @Override + public void processError(final QBGroupChat groupChat, QBChatException error, QBChatMessage originMessage) { + Util.onError(error, ChatGroupActivity.this); + } + }; + + private QBSystemMessagesManager systemMessagesManager; + + private QBSystemMessageListener systemMessageListener = new QBSystemMessageListener() { + @Override + public void processMessage(QBChatMessage qbChatMessage) { + displayChatMessage(qbChatMessage); + } + + @Override + public void processError(QBChatException e, QBChatMessage qbChatMessage) { + Util.onError(e, ChatGroupActivity.this); + } + }; + + private QBGroupChat groupChat; + + private boolean isBlocked; + private boolean userDeleted; + private int currentCode; + + public static boolean isImage(File file) { + String fileName = file.getName(); + String ext = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); + return ext.equals("jpeg") || ext.equals("jpg") || ext.equals("png") || ext.equals("bmp"); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = DataBindingUtil.setContentView(this, R.layout.activity_chat_group); + binding.setActivity(this); + + setSupportActionBar(binding.toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + chatAdapter = new ChatGroupMessagesAdapter(ChatGroupActivity.this, currentUserId); + + binding.listViewChatMessages.setAdapter(chatAdapter); + chatAdapter.setCallback(new BaseListAdapter.Callback() { + @Override + public void onLoadMore() { + loadData(); + } + + @Override + public void onItemClick(QBChatMessage item) { + + } + }); + + if (savedInstanceState != null) { + dialog = (QBDialog) savedInstanceState.get(DIALOG); + userIdsList = savedInstanceState.getIntegerArrayList(RECIPIENT_IDS_LIST); + currentUserId = savedInstanceState.getInt(CURRENT_USER_ID, 0); + } + if (dialog != null && dialog.getType() != null && dialog.getType() == QBDialogType.GROUP) { + initForGroupChat(); + } + + this.savedInstanceState = savedInstanceState; + + editText_chat_message = (EditText) findViewById(R.id.editText_chat_message); + + button_send_chat = (Button) findViewById(R.id.button_send_chat); + blockedContainer = (FrameLayout) findViewById(R.id.block_container); + messageContainer = (ViewGroup) findViewById(R.id.message_container); + + LocalBroadcastManager.getInstance(this).registerReceiver(updateChatReciever, new IntentFilter(C.UPDATE_CHAT)); + binding.giphySelector.setCallback(new GiphySelector.Callback() { + @Override + public void onSelected(Giphy giphy) { + sendSticker(Uri.parse(giphy.getFull().getUrl())); + } + }); + initStickersWidget(); + + + } + + private void initForGroupChat() { + runOnUiThread(new Runnable() { + @Override + public void run() { + binding.setGroupName(dialog.getName()); + binding.addGroupMember.setVisibility(dialog.getType() == QBDialogType.GROUP ? View.VISIBLE : View.GONE); + } + }); + + } + + private void initStickersWidget() { + mStickersContainer = binding.stickersContainer; + RenderingOptions renderingOptions = new RenderingOptions( + RenderingOptions.BorderStyle.Sticker, + RenderingOptions.ImageFormat.Png, + RenderingOptions.Size.Thumbnail + ); + WidgetDisplayOptions options = new WidgetDisplayOptions(renderingOptions); + mStickersWidget = new QuarterScreenWidget( + this, + options, + new SearchResultAdapter.ImageLoader() { + @Override + public void loadImage(@NonNull ImageView target, @NonNull Uri uri, + @NonNull final SearchResultAdapter.ImageLoaderCallback callback) { + Glide.with(getApplicationContext()) + .load(uri.toString()) + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + callback.updateImageView(); + return false; + } + }) + .into(target); + } + } + ); + mStickersWidget.setWidgetListener(new WidgetListener() { + @Override + public void onCloseButtonTapped() { + // not needed + } + + @Override + public void onStickerTapped(Imoji imoji) { + sendSticker(imoji.getStandardFullSizeUri()); + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + isExternalDialogOpened = false; + if (resultCode == Activity.RESULT_OK) { + switch (requestCode) { + case PICKFILE_REQUEST_CODE: + sendAttachment(data.getData()); + break; + case IMAGE_CAPTURE_REQUEST_CODE: + sendAttachment(mPhotoUri); + break; + case PICK_FILE_FOR_EDIT_REQUEST: + openStickerEditor(data.getData()); + break; + case ImojiEditorActivity.START_EDITOR_REQUEST_CODE: + if (data.hasExtra(ImojiCreateService.IMOJI_MODEL_BUNDLE_ARG_KEY)) { + Imoji imoji = data.getParcelableExtra(ImojiCreateService.IMOJI_MODEL_BUNDLE_ARG_KEY); + sendSticker(imoji.getStandardFullSizeUri()); + } + break; + case ADD_NEW_GROUP_MEMBER: + if (data.hasExtra(NEW_ADDED_USERS_LIST)) { + selectedNewGroupUserList = data.getIntegerArrayListExtra(NEW_ADDED_USERS_LIST); + addNewMembers(); + } + break; + case GROUP_SETTINGS_CHANGE: + if (data.hasExtra(CHANGED_GROUP_NAME)) { + binding.setGroupName(data.getStringExtra(CHANGED_GROUP_NAME)); + dialog.setName(data.getStringExtra(CHANGED_GROUP_NAME)); + } + break; + } + } + if (resultCode == Activity.RESULT_CANCELED) { + isBusy.set(false); + } + } + + private void addNewMembers() { + QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + QBDialogRequestBuilder requestBuilder = new QBDialogRequestBuilder(); + if (selectedNewGroupUserList != null) { + for (Integer id : selectedNewGroupUserList) { + requestBuilder.addUsers(id); + } + + try { + dialog = groupChatManager.updateDialog(dialog, requestBuilder); + } catch (QBResponseException e) { + e.printStackTrace(); + } + notifyGroupUsers(selectedNewGroupUserList); + selectedNewGroupUserList = null; + } + } + + @Override + public void onQBConnect(final boolean isActivityReopened) { + // init recipient and dialog if intent contains only their ids + reloadData(isActivityReopened); + } + + private void reloadData(final boolean isActivityReopened) { + isBusy.set(true); + + final QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + systemMessagesManager = QBChatService.getInstance().getSystemMessagesManager(); + systemMessagesManager.addSystemMessageListener(systemMessageListener); + + if (getIntent().hasExtra(RECIPIENT_IDS_LIST)) { + userIdsList = getIntent().getIntegerArrayListExtra(RECIPIENT_IDS_LIST); + getUsers(userIdsList); + } + + new AsyncTask() { + + Exception error; + private ArrayList chatMessages; + + @Override + protected Void doInBackground(Void... params) { + Log.d("CHAT", "doInBackground"); + try { + if (currentQBUser == null) { + currentQBUser = QBUsers.getUser(preferences.getInt(C.QB_USERID, 0)); + } + currentUserId = currentQBUser.getId(); + + if (dialog == null) { + if (getIntent().hasExtra(DIALOG)) { + dialog = (QBDialog) getIntent().getSerializableExtra(DIALOG); + } + if (dialog == null && getIntent().hasExtra(DIALOG_ID)) { + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.eq("_id", getIntent().getStringExtra(DIALOG_ID)); + + Bundle bundle = new Bundle(); + ArrayList dialogs = QBChatService.getChatDialogs(QBDialogType.GROUP, requestBuilder, bundle); + if (dialogs.size() == 0) return null; + dialog = dialogs.get(0); + + if (userIdsList == null && dialog != null && dialog.getOccupants() != null) { + userIdsList = (ArrayList) dialog.getOccupants(); + } + } + } + + if (dialog == null) { + QBDialog groupDialog = new QBDialog(); + groupDialog.setName(getString(R.string.default_channel_name)); + if (getIntent().hasExtra(DIALOG_GROUP_TYPE) && + getIntent().getSerializableExtra(DIALOG_GROUP_TYPE) == QBDialogType.PUBLIC_GROUP) { + groupDialog.setType(QBDialogType.PUBLIC_GROUP); + } else { + groupDialog.setType(QBDialogType.GROUP); + groupDialog.setOccupantsIds(userIdsList); + } + dialog = groupChatManager.createDialog(groupDialog); + notifyGroupUsers(groupDialog.getOccupants()); + } + + try { + groupChat = groupChatManager.getGroupChat(dialog.getRoomJid()); + } catch (NullPointerException e) { + Log.e("QBPrivateChatManager", e.getMessage()); + e.printStackTrace(); + } + if (groupChat == null) { + groupChat = groupChatManager.createGroupChat(dialog.getRoomJid()); + } + groupChat.addMessageListener(groupChatMessageListener); + + DiscussionHistory history = new DiscussionHistory(); + history.setMaxStanzas(0); + groupChat.join(history); + + QBRequestGetBuilder requestBuilder; + if (!isActivityReopened) { + requestBuilder = new QBRequestGetBuilder(); + requestBuilder.setLimit(messagesPerPage); + requestBuilder.sortDesc("date_sent"); + chatMessages = QBChatService.getDialogMessages(dialog, requestBuilder, new Bundle()); + currentPage++; + } else if (gotMessagesInOffline) { + requestBuilder = new QBRequestGetBuilder(); + requestBuilder.addRule("date_sent", ">", String.valueOf(paused)); + requestBuilder.sortDesc("date_sent"); + chatMessages = QBChatService.getDialogMessages(dialog, requestBuilder, new Bundle()); + } + + initForGroupChat(); + + + } catch (Exception e) { + e.printStackTrace(); + error = e; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + Log.d("CHAT", "finished"); + isBusy.set(false); + if (error != null) { + Util.onError(error, ChatGroupActivity.this); + return; + } + if (!isActivityReopened) { + if (chatMessages == null) chatMessages = new ArrayList<>(); + chatAdapter.addItems(chatMessages); + if (chatMessages.size() < messagesPerPage) { + chatAdapter.disableLoadMore(); + } + } else if (gotMessagesInOffline) { + chatAdapter.addItemsToStart(chatMessages); + chatAdapter.alignToPageSize(messagesPerPage, currentPage); + gotMessagesInOffline = false; + } + + checkIsOpenedFirst(); + + } + }.execute(); + } + + private void checkIsOpenedFirst() { + if (getIntent().hasExtra(IS_FIRST_OPENED) && + getIntent().getBooleanExtra(IS_FIRST_OPENED, false)) { + Intent intent = new Intent(ChatGroupActivity.this, GroupEditActivity.class); + intent.putExtra(GroupEditActivity.DIALOG, dialog); + startActivityForResult(intent, GROUP_SETTINGS_CHANGE); + } + } + + private void notifyGroupUsers(List list) { + if (list == null || list.size() == 0) return; + for (Integer userID : list) { + QBChatMessage chatMessage = createChatNotificationForGroupChatCreation(dialog); + chatMessage.setRecipientId(userID); + try { + systemMessagesManager.sendSystemMessage(chatMessage); + } catch (SmackException.NotConnectedException e) { + e.printStackTrace(); + } catch (IllegalStateException ee) { + ee.printStackTrace(); + } + } + } + + public static QBChatMessage createChatNotificationForGroupChatCreation(QBDialog dialog) { + String dialogId = String.valueOf(dialog.getDialogId()); + String roomJid = dialog.getRoomJid(); + String occupantsIds = TextUtils.join(",", dialog.getOccupants()); + String dialogName = dialog.getName(); + String dialogTypeCode = String.valueOf(dialog.getType().ordinal()); + + QBChatMessage chatMessage = new QBChatMessage(); + chatMessage.setBody("You were added to group"); + + // Add notification_type=1 to extra params when you created a group chat + chatMessage.setProperty("notification_type", "1"); + + chatMessage.setProperty("_id", dialogId); + if (!TextUtils.isEmpty(roomJid)) { + chatMessage.setProperty("room_jid", roomJid); + } + chatMessage.setProperty("occupants_ids", occupantsIds); + if (!TextUtils.isEmpty(dialogName)) { + chatMessage.setProperty("name", dialogName); + } + chatMessage.setProperty("type", dialogTypeCode); + + return chatMessage; + } + + private void displayChatMessage(QBChatMessage message) { + Date dt = new Date(); + if (message.getSenderId() == null) { + message.setSenderId(currentQBUser.getId()); + } + if (message.getDateSent() == 0) { + message.setDateSent(dt.getTime() / 1000); + } + if (message.getAttachments() == null) { + message.setAttachments(new ArrayList()); + } + chatAdapter.addItem(message); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + LocalBroadcastManager.getInstance(this).unregisterReceiver(updateChatReciever); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putSerializable(DIALOG, dialog); + outState.putIntegerArrayList(RECIPIENT_IDS_LIST, userIdsList); + outState.putInt(CURRENT_USER_ID, currentUserId); + } + + @Override + protected void onStart() { + super.onStart(); + if (mStickersContainer.getChildCount() != 0) { + hideSoftKeyboard(); + } + } + + @Override + protected void onStop() { + super.onStop(); + paused = System.currentTimeMillis(); + if (!isExternalDialogOpened) { + isBusy.set(true); + } + } + + private void onBlocked() { + Toast.makeText(this, getString(R.string.text_you_blocked), Toast.LENGTH_LONG).show(); + messageContainer.setVisibility(View.GONE); + blockedContainer.setVisibility(View.VISIBLE); + } + + private void onUnBlocked() { + Toast.makeText(this, getString(R.string.text_you_unblocked), Toast.LENGTH_LONG).show(); + binding.setIsBlockedByOther(false); + } + + public void sendChatMessage() { + if (isBusy.get()) { + Toast.makeText(this, "Please wait until connection to server restored", Toast.LENGTH_LONG).show(); + return; + } + // send chat message to server + if (!editText_chat_message.getText().toString().equals("")) { + QBChatMessage msg = new QBChatMessage(); + msg.setBody(editText_chat_message.getText().toString()); + //SimpleDateFormat sdf = new SimpleDateFormat("HH:mm yyyy/MM/dd", Locale.US); + //msg.setProperty("date_sent",String.valueOf(sdf.format(new Date()))+""); + + msg.setProperty("save_to_history", "1"); + msg.setProperty("send_to_chat", "1"); + msg.setDialogId(dialog.getDialogId()); + Location location = UserLocationService.getLastLocation(); + if (location != null) { + msg.setProperty(C.LATITUDE, String.valueOf(location.getLatitude())); + msg.setProperty(C.LONGITUDE, String.valueOf(location.getLongitude())); + } + + try { + groupChat.sendMessage(msg); + displayChatMessage(msg); + EventBus.getDefault().post(msg); + } catch (SmackException.NotConnectedException e) { + if (!isNetworkAvailable()) { + Util.onError(getString(R.string.verify_internet_connection), this); + } else { + isReopened = true; + isBusy.set(true); + loginToChat(); + Toast.makeText(this, R.string.reconnect_message, Toast.LENGTH_LONG).show(); + } + } catch (Exception e) { + Util.onError(e, ChatGroupActivity.this); + } + editText_chat_message.setText(""); + } + } + + public void sendAttachment(Uri uri) { + if (isSendingMessage.get()) return; + isSendingMessage.set(true); + + // Get the path + + final String path = FileUtil.getPath(this, uri); + if (path == null) { + Util.onError(getString(R.string.unable_to_get_file), this); + isSendingMessage.set(false); + return; + } + final File filePhoto = new File(path); + + new AsyncTask() { + Exception exception; + + @Override + protected QBChatMessage doInBackground(Void... params) { + + try { + UploadFileTask task = new UploadFileTask(filePhoto, false, null, new QBProgressCallback() { + @Override + public void onProgressUpdate(int i) { + uploadProgress.set(i); + } + }); + + QBFile qbFile = task.execute(); + + // create a message + QBChatMessage chatMessage = new QBChatMessage(); + chatMessage.setProperty("save_to_history", "1"); // Save a message to history + + // attach a photo + QBAttachment attachment = new QBAttachment("photo"); + attachment.setId(qbFile.getId().toString()); + attachment.setName(filePhoto.getName()); + chatMessage.addAttachment(attachment); + chatMessage.setBody(filePhoto.getName()); + if (isImage(filePhoto)) { + Bitmap bitmap = BitmapFactory.decodeFile(filePhoto.getAbsolutePath()); + Bitmap thumb = ThumbnailUtils.extractThumbnail(bitmap, 300, 300); + File tmp = File.createTempFile("thumb", ".jpg"); + FileOutputStream stream = new FileOutputStream(tmp); + thumb.compress(Bitmap.CompressFormat.JPEG, 90, stream); + stream.close(); + + QBFile qbFileThumb = QBContent.uploadFileTask(tmp, false, null); + QBAttachment attachmentThumb = new QBAttachment("thumb"); + attachmentThumb.setId(qbFileThumb.getId().toString()); + attachmentThumb.setName(qbFileThumb.getName()); + chatMessage.addAttachment(attachmentThumb); + bitmap.recycle(); + } + + groupChat.sendMessage(chatMessage); + + if (filePhoto.getAbsolutePath().contains("cache")) { + filePhoto.delete(); + } + return chatMessage; + } catch (Exception e) { + e.printStackTrace(); + exception = e; + } + return null; + } + + @Override + protected void onPostExecute(QBChatMessage qbChatMessage) { + isSendingMessage.set(false); + isBusy.set(false); + if (exception != null) { + Util.onError(exception, ChatGroupActivity.this); + return; + } + displayChatMessage(qbChatMessage); + } + + }.execute(); + } + + public void sendSticker(Uri uri) { + if (isBusy.get()) { + Toast.makeText(this, "Please wait until connection to server restored", Toast.LENGTH_LONG).show(); + return; + } + if (isSendingMessage.get()) return; + isSendingMessage.set(true); + + // send sticker to chat server + if (uri.toString().contains("http")) { + QBChatMessage msg = new QBChatMessage(); + msg.setBody("sticker"); + + msg.setProperty("save_to_history", "1"); + msg.setDialogId(dialog.getDialogId()); + //msg.setProperty("send_to_chat", "1"); + msg.setProperty(C.CHAT_MSG_STICKER_PROPERTY, uri.toString()); + + try { + groupChat.sendMessage(msg); + displayChatMessage(msg); + } catch (SmackException.NotConnectedException e) { + if (!isNetworkAvailable()) { + Util.onError(getString(R.string.verify_internet_connection), this); + } else { + isReopened = true; + isBusy.set(true); + loginToChat(); + Toast.makeText(this, R.string.reconnect_message, Toast.LENGTH_LONG).show(); + } + } catch (Exception e) { + Util.onError(e, ChatGroupActivity.this); + } + } + isSendingMessage.set(false); + } + + public void onClickImoji() { + if (binding.getShowGiphy()) onClickGiphy(); + if (mStickersContainer != null && mStickersContainer.getChildCount() == 0) { + hideSoftKeyboard(); + mStickersContainer.addView(mStickersWidget); + } else { + hideStickersContainer(); + } + } + + private void hideStickersContainer() { + if (mStickersContainer != null && mStickersContainer.getChildCount() > 0) { + mStickersContainer.removeAllViews(); + } + } + + public void selectFile() { + final CharSequence[] items = { + getString(R.string.dialog_take_from_camera), + getString(R.string.dialog_get_from_gallery), + getString(R.string.cancel)}; + AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppAlertDialogTheme); + builder.setTitle(getString(R.string.dialog_send_file_title)); + builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int item) { + if (items[item].equals(getString(R.string.dialog_take_from_camera))) { + getImgFromCamera(); + } else if (items[item].equals(getString(R.string.dialog_get_from_gallery))) { + getImgFromGallery(PICKFILE_REQUEST_CODE); + } else if (items[item].equals(getString(R.string.cancel))) { + dialog.dismiss(); + } + } + }); + builder.setCancelable(false); + builder.show(); + } + + private void getImgFromCamera() { + int permCameraCheck = ContextCompat.checkSelfPermission(this, + Manifest.permission.CAMERA); + int permWriteCheck = ContextCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (permCameraCheck != PackageManager.PERMISSION_GRANTED || permWriteCheck != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, + WRITE_ST_CAMERA_PERMISSION_REQUEST); + return; + } + isExternalDialogOpened = true; + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + mPhotoUri = Uri.fromFile(getOutputMediaFile()); + intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri); + startActivityForResult(intent, IMAGE_CAPTURE_REQUEST_CODE); + } + + private static File getOutputMediaFile() { + File mediaStorageDir = new File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "PawPads"); + if (!mediaStorageDir.exists()) { + if (!mediaStorageDir.mkdirs()) { + return null; + } + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", + Locale.getDefault()).format(new Date()); + return new File(mediaStorageDir.getPath() + File.separator + + "IMG_" + timeStamp + ".jpg"); + } + + private void getImgFromGallery(int code) { + int permissionCheck = ContextCompat.checkSelfPermission(this, + Manifest.permission.READ_EXTERNAL_STORAGE); + if (permissionCheck != PackageManager.PERMISSION_GRANTED) { + currentCode = code; + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + READ_STORAGE_PERMISSION_REQUEST); + return; + } + isExternalDialogOpened = true; + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("image/*"); + startActivityForResult(Intent.createChooser(intent, "Select Picture"), code); + } + + public void loadData() { + new AsyncTask>() { + Exception e; + + @Override + protected List doInBackground(Void... params) { + ArrayList chatMessages = null; + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.setLimit(messagesPerPage); + requestBuilder.setSkip(messagesPerPage * currentPage); + requestBuilder.sortDesc("date_sent"); + try { + chatMessages = QBChatService.getDialogMessages(dialog, requestBuilder, new Bundle()); + currentPage++; + } catch (QBResponseException exc) { + exc.printStackTrace(); + this.e = exc; + } + return chatMessages; + } + + @Override + protected void onPostExecute(List chatMessages) { + if (e != null) { + Util.onError(e, ChatGroupActivity.this); + return; + } + if (chatMessages != null && chatMessages.size() > 0) { + chatAdapter.addItems(chatMessages); + } + + if (chatMessages == null || chatMessages.size() < messagesPerPage) { + chatAdapter.disableLoadMore(); + } + + } + }.execute(); + + + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + switch (requestCode) { + case READ_STORAGE_PERMISSION_REQUEST: { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + getImgFromGallery(currentCode); + } + break; + } + case WRITE_ST_CAMERA_PERMISSION_REQUEST: { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + getImgFromCamera(); + } + break; + } + } + } + + @Override + public void onGroupChatMessage(QBGroupChat qbGroupChat, final QBChatMessage qbChatMessage) { + if (dialog == null) return; + if (!qbChatMessage.getDialogId().equals(dialog.getDialogId())) return; + ChatGroupActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + if (qbChatMessage.getProperties().containsKey("blocked")) { + if (qbChatMessage.getProperty("blocked").equals("1")) { + onBlocked(); + } else if (qbChatMessage.getProperty("blocked").equals("0")) { + onUnBlocked(); + } + } else { + displayChatMessage(qbChatMessage); + } + + } + }); + } + + public void hideSoftKeyboard() { + if (getCurrentFocus() != null) { + Handler h = new Handler(); + h.postDelayed(new Runnable() { + @Override + public void run() { + InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); + } + }, 50); + } + } + + @Override + public void onBackPressed() { + if (mStickersContainer.getChildCount() != 0) { + hideStickersContainer(); + hideSoftKeyboard(); + } else { + super.onBackPressed(); + } + } + + public void onClickGiphy() { + hideSoftKeyboard(); + hideStickersContainer(); + binding.setShowGiphy(!binding.getShowGiphy()); + } + + public void onCLickCreateSticker() { + getImgFromGallery(PICK_FILE_FOR_EDIT_REQUEST); + + } + + public void openStickerEditor(Uri uri) { + isExternalDialogOpened = true; + final String path = FileUtil.getPath(this, uri); + Bitmap bitmap = null; + if (path == null) { + try { + bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + bitmap = BitmapFactory.decodeFile(path); + } + + if (bitmap == null) { + Util.onError(getString(R.string.unable_to_get_file), this); + isSendingMessage.set(false); + } + EditorBitmapCache.getInstance().put(EditorBitmapCache.Keys.INPUT_BITMAP, bitmap); + Intent intent = new Intent(this, ImojiEditorActivity.class); + startActivityForResult(intent, ImojiEditorActivity.START_EDITOR_REQUEST_CODE); + } + + private void getUsers(List userIdsList) { + if (userIdsList == null || userIdsList.size() == 0) return; + + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + QBUsers.getUsersByIDs(userIdsList, pagedRequestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList users, Bundle params) { + if (users.size() > 0) { + recipientList = users; + } + } + + @Override + public void onError(QBResponseException errors) { + if (getApplicationContext() == null) return; + Util.onError(errors, getApplicationContext()); + } + }); + } + + public void editGroupSettings() { + Intent intent = new Intent(ChatGroupActivity.this, GroupEditActivity.class); + intent.putExtra(GroupEditActivity.DIALOG, dialog); + startActivityForResult(intent, GROUP_SETTINGS_CHANGE); + } + + public void addGroupMember() { + Intent intentAddGroupMember = new Intent(this, CreateChatActivity.class); + intentAddGroupMember.putIntegerArrayListExtra(CreateChatActivity.DIALOG_USERS_LIST, ((ArrayList) dialog.getOccupants())); + startActivityForResult(intentAddGroupMember, ADD_NEW_GROUP_MEMBER); + } + +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupMessagesAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupMessagesAdapter.java new file mode 100644 index 0000000..5392eea --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatGroupMessagesAdapter.java @@ -0,0 +1,454 @@ +package saberapplications.pawpads.ui.chat; + +import android.content.Context; +import android.content.Intent; +import android.databinding.DataBindingUtil; +import android.location.Location; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.content.ContextCompat; +import android.support.v4.util.ArrayMap; +import android.text.Layout; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.drawable.GlideDrawable; +import com.bumptech.glide.load.resource.gif.GifDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; +import com.quickblox.chat.model.QBAttachment; +import com.quickblox.chat.model.QBChatMessage; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBPagedRequestBuilder; +import com.quickblox.core.request.QBRequestGetBuilder; +import com.quickblox.customobjects.QBCustomObjects; +import com.quickblox.customobjects.model.QBCustomObject; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; + +import io.fabric.sdk.android.services.concurrency.AsyncTask; +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.Util; +import saberapplications.pawpads.databinding.ChatGroupMessageLeftBinding; +import saberapplications.pawpads.databinding.ChatGroupMessageRightBinding; +import saberapplications.pawpads.service.FileDownloadService; +import saberapplications.pawpads.service.UserLocationService; +import saberapplications.pawpads.ui.profile.ProfileActivity; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.util.OtherUsersLocationsCache; +import saberapplications.pawpads.views.BaseChatAdapter; +import saberapplications.pawpads.views.BaseListAdapter; + + +/** + * Created by developer on 31.05.17. + */ + +public class ChatGroupMessagesAdapter extends BaseChatAdapter { + private Context mContext; + private LayoutInflater mInflater; + private static int currentUserId; + private ArrayMap userCache = new ArrayMap<>(); + + public ChatGroupMessagesAdapter(Context context, int userId) { + mContext = context; + mInflater = LayoutInflater.from(mContext); + currentUserId = userId; + } + + @Override + public DataHolder getChatItemHolderRight(ViewGroup parent) { + View v = mInflater.inflate(R.layout.chat_group_message_right, parent, false); + return new ChatGroupMessagesAdapter.HolderRight(v, this); + } + + @Override + public DataHolder getChatItemHolderLeft(ViewGroup parent) { + View v = mInflater.inflate(R.layout.chat_group_message_left, parent, false); + return new ChatGroupMessagesAdapter.HolderLeft(v, this); + } + + @Override + public boolean getMessageSelf(int position) { + QBChatMessage message = items.get(position).model.get(); + return message.getSenderId() == currentUserId; + } + public boolean groupWithPrevMessage(int position,QBChatMessage currentMessage){ + QBChatMessage prevMessage = items.get(position).model.get(); + long timeDiff=currentMessage.getDateSent()-prevMessage.getDateSent(); + return prevMessage.getSenderId().equals(currentMessage.getSenderId()) && timeDiff { + protected ChatGroupMessagesAdapter adapter; + QBAttachment attachment; + + public MessageHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + this.adapter = (ChatGroupMessagesAdapter) adapter; + } + + @Override + public void showData(DataItem model, int position) { + + } + + public void downloadAttachment() { + if (attachment != null) { + FileDownloadService.startService(adapter.mContext, attachment); + } + } + + protected void loadUserAvatar(final int userId, final ImageView avatar, final int avatarSize) { + Glide.clear(avatar); + Glide.with(avatar.getContext()).load(R.drawable.user_placeholder).into(avatar); + avatar.setTag(R.id.user_id,userId); + if (!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + int storedId= (int) avatar.getTag(R.id.user_id); + if (qbUser.getFileId() != null && storedId==userId) { + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + } else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), avatar, avatarSize, avatarSize); + } + } + + + + protected void loadUsername(final int userId, final TextView username){ + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFullName() != null) { + username.setText(qbUser.getFullName()); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + } + + protected void checkIsUserBlocked(final int recipientId, final View view) { + if (view == null) return; + new AsyncTask() { + + @Override + protected Boolean doInBackground(Void... voids) { + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.eq("source_user", currentUserId); + requestBuilder.eq("blocked_user", recipientId); + + ArrayList blocks = null; + try { + blocks = QBCustomObjects.getObjects("BlockList", requestBuilder, new Bundle()); + } catch (QBResponseException e) { + e.printStackTrace(); + } + return (blocks != null && blocks.size() > 0); + } + + @Override + protected void onPostExecute(Boolean result) { + if (result) view.setVisibility(View.VISIBLE); + } + }.execute(); + } + + } + + public static class HolderRight extends ChatGroupMessagesAdapter.MessageHolder { + + ChatGroupMessageRightBinding binding; + + protected HolderRight(View v, ChatGroupMessagesAdapter adapter) { + super(v, adapter); + binding = DataBindingUtil.bind(v); + binding.setHolder(this); + } + + @Override + public void showData(DataItem model, int position) { + QBChatMessage item = model.model.get(); + Date date = new Date(item.getDateSent() * 1000); + binding.setMessage(item.getBody()); + binding.setDate(adapter.formatDate(date)); + binding.avatarGroupUser.setImageResource(R.drawable.user_placeholder); + binding.avatarGroupUser.setVisibility(View.INVISIBLE); + binding.blockedStatus.setVisibility(View.GONE); + if (position > 0) { + if (adapter.groupWithPrevMessage(position - 1,item)) { + binding.text.setBackgroundResource(R.drawable.message_right); + binding.setIsLast(false); + } else { + binding.text.setBackgroundResource(R.drawable.message_right_last); + binding.setIsLast(true); + } + } else { + binding.text.setBackgroundResource(R.drawable.message_right_last); + binding.setIsLast(true); + } + if (binding.getIsLast()) { + int userId = item.getSenderId(); + float d = view.getResources().getDisplayMetrics().density; + binding.avatarGroupUser.setVisibility(View.VISIBLE); + loadUserAvatar(userId, binding.avatarGroupUser, Math.round(25 * d)); + checkIsUserBlocked(item.getSenderId(), binding.blockedStatus); + } + + binding.setShowThumbNail(false); + if (item.getAttachments().size() > 0) { + Iterator iterator = item.getAttachments().iterator(); + attachment = iterator.next(); + if (attachment.getName() != null) { + binding.setMessage(attachment.getName()); + } else { + binding.setMessage(item.getBody()); + } + + + if (iterator.hasNext()) { + QBAttachment thumbAttachment = iterator.next(); + if (thumbAttachment.getType().equals("thumb")) { + binding.setMessage(""); + binding.thumb.setImageBitmap(null); + binding.setShowThumbNail(true); + AvatarLoaderHelper.loadImage(Integer.parseInt(thumbAttachment.getId()), binding.thumb, 300, 300); + } + } + } else { + attachment = null; + } + if (item.getProperty(C.CHAT_MSG_STICKER_PROPERTY) != null) { + binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), android.R.color.transparent)); + binding.setShowThumbNail(true); + binding.stickerProgressBar.setVisibility(View.VISIBLE); + + String url = item.getProperty(C.CHAT_MSG_STICKER_PROPERTY).toString(); + Glide.clear(binding.thumb); + if (url.matches("\\.gif")) { + Glide.with(itemView.getContext()) + .load(Uri.parse(url)).asGif() + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, Uri model, Target target, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + + @Override + public boolean onResourceReady(GifDrawable resource, Uri model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + }) + .into(binding.thumb); + } else { + Glide.with(itemView.getContext()) + .load(Uri.parse(url)) + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, Uri model, Target target, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + + @Override + public boolean onResourceReady(GlideDrawable resource, Uri model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + }) + .into(binding.thumb); + } + + } + } + } + + public static class HolderLeft extends ChatGroupMessagesAdapter.MessageHolder { + + ChatGroupMessageLeftBinding binding; + private QBChatMessage item; + + protected HolderLeft(View v, ChatGroupMessagesAdapter adapter) { + super(v, adapter); + binding = DataBindingUtil.bind(v); + binding.setHolder(this); + } + + @Override + public void showData(DataItem model, int position) { + item = model.model.get(); + Date date = new Date(item.getDateSent() * 1000); + binding.setDate(adapter.formatDate(date)); + binding.setMessage(item.getBody()); + + binding.avatarGroupUser.setImageResource(R.drawable.user_placeholder); + binding.avatarGroupUser.setVisibility(View.INVISIBLE); + binding.blockedStatus.setVisibility(View.GONE); + if (position > 0) { + if (adapter.groupWithPrevMessage(position - 1,item)) { + binding.text.setBackgroundResource(R.drawable.message_left); + binding.setIsLast(false); + } else { + binding.text.setBackgroundResource(R.drawable.message_left_last); + binding.setIsLast(true); + } + } else { + binding.text.setBackgroundResource(R.drawable.message_left_last); + binding.setIsLast(true); + + } + if (binding.getIsLast()) { + int userId = item.getSenderId(); + float d = view.getResources().getDisplayMetrics().density; + binding.avatarGroupUser.setVisibility(View.VISIBLE); + loadUserAvatar(userId, binding.avatarGroupUser, Math.round(25 * d)); + loadUsername(userId, binding.leftUsername); + checkIsUserBlocked(item.getSenderId(), binding.blockedStatus); + } + + if (item.getAttachments().size() > 0) { + if (item.getAttachments().size() > 0) { + Iterator iterator = item.getAttachments().iterator(); + attachment = iterator.next(); + binding.setMessage(attachment.getName()); + if (iterator.hasNext()) { + QBAttachment thumbAttachment = iterator.next(); + if (thumbAttachment.getType().equals("thumb")) { + binding.setMessage(""); + binding.setShowThumbNail(true); + AvatarLoaderHelper.loadImage(Integer.parseInt(thumbAttachment.getId()), binding.thumb, 300, 300); + } + } + } else { + attachment = null; + } + + } else { + attachment = null; + binding.setShowThumbNail(false); + } + final Location currentLocation= UserLocationService.getLastLocation(); + if(item.getProperty(C.LATITUDE)!=null && currentLocation!=null){ + Location messageLocation=new Location(""); + messageLocation.setLatitude(Double.parseDouble((String) item.getProperty(C.LATITUDE))); + messageLocation.setLongitude(Double.parseDouble((String) item.getProperty(C.LONGITUDE))); + binding.setDistance( + Util.formatDistance(currentLocation.distanceTo(messageLocation)) + ); + }else if(currentLocation!=null){ + OtherUsersLocationsCache.get(item.getSenderId()).callback(new OtherUsersLocationsCache.Callback() { + @Override + public void location(Location location) { + binding.setDistance( + Util.formatDistance(currentLocation.distanceTo(location)) + ); + } + }); + } + + if (item.getProperty(C.CHAT_MSG_STICKER_PROPERTY) != null) { + binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), android.R.color.transparent)); + binding.setShowThumbNail(true); + binding.stickerProgressBar.setVisibility(View.VISIBLE); + + String url = item.getProperty(C.CHAT_MSG_STICKER_PROPERTY).toString(); + + Glide.with(itemView.getContext()) + .load(Uri.parse(url)) + .listener(new RequestListener() { + @Override + public boolean onException(Exception e, Uri model, Target target, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + + @Override + public boolean onResourceReady(GlideDrawable resource, Uri model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { + if (binding.stickerProgressBar != null) { + binding.stickerProgressBar.setVisibility(View.GONE); + } + return false; + } + }) + .into(binding.thumb); + } + } + + public void openUserProfile() { + final int userId = item.getSenderId(); + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + pagedRequestBuilder.setPage(1); + pagedRequestBuilder.setPerPage(1); + QBUsers.getUsersByIDs(new ArrayList() {{ + add(userId); + }}, pagedRequestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList qbUsers, Bundle bundle) { + Intent intent=new Intent(itemView.getContext(), ProfileActivity.class); + intent.putExtra(C.QB_USER,qbUsers.get(0)); + itemView.getContext().startActivity(intent); + } + @Override + public void onError(QBResponseException e) { + Util.onError(e, itemView.getContext()); + } + }); + } + } + + public String formatDate(Date date) { + + Calendar today = GregorianCalendar.getInstance(); + today.set(Calendar.HOUR, 0); + today.set(Calendar.MINUTE, 0); + today.set(Calendar.SECOND, 0); + + if (today.getTime().compareTo(date) < 0) { + SimpleDateFormat dateFormat = new SimpleDateFormat("h:mm a"); + return dateFormat.format(date); + } else { + SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM h:mm a"); + return dateFormat.format(date); + } + + + } +} diff --git a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatMessagesAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatMessagesAdapter.java index 9d7d390..3f7c6e4 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/chat/ChatMessagesAdapter.java +++ b/app/src/main/java/saberapplications/pawpads/ui/chat/ChatMessagesAdapter.java @@ -104,7 +104,7 @@ public void showData(DataItem model, int position) { binding.setMessage(item.getBody()); binding.setDate(adapter.formatDate(date)); if (position > 0) { - if (adapter.getMessageSelf(position - 1)) { + if (adapter.groupWithPrevMessage(position - 1,item)) { binding.text.setBackgroundResource(R.drawable.message_right); binding.setIsLast(false); } else { @@ -139,7 +139,7 @@ public void showData(DataItem model, int position) { attachment = null; } if (item.getProperty(C.CHAT_MSG_STICKER_PROPERTY) != null) { - binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), R.color.tw__transparent)); + binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), android.R.color.transparent)); binding.setShowThumbNail(true); binding.stickerProgressBar.setVisibility(View.VISIBLE); @@ -210,7 +210,7 @@ public void showData(DataItem model, int position) { binding.setDate(adapter.formatDate(date)); binding.setMessage(item.getBody()); if (position > 0) { - if (!adapter.getMessageSelf(position - 1)) { + if (adapter.groupWithPrevMessage(position - 1,item)) { binding.text.setBackgroundResource(R.drawable.message_left); binding.setIsLast(false); } else { @@ -244,7 +244,7 @@ public void showData(DataItem model, int position) { binding.setShowThumbNail(false); } if (item.getProperty(C.CHAT_MSG_STICKER_PROPERTY) != null) { - binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), R.color.tw__transparent)); + binding.text.setBackgroundColor(ContextCompat.getColor(itemView.getContext(),android.R.color.transparent)); binding.setShowThumbNail(true); binding.stickerProgressBar.setVisibility(View.VISIBLE); @@ -291,4 +291,9 @@ public String formatDate(Date date) { } + public boolean groupWithPrevMessage(int position,QBChatMessage currentMessage){ + QBChatMessage prevMessage = items.get(position).model.get(); + long timeDiff=currentMessage.getDateSent()-prevMessage.getDateSent(); + return prevMessage.getSenderId().equals(currentMessage.getSenderId()) && timeDiff, CreateChatListAdapter.OnUserSelectedListener { + public static final String DIALOG_USERS_LIST = "DIALOG_USERS_LIST"; + ActivityCreateChatBinding binding; + CreateChatListAdapter adapter; + int dialogsLoadCurrentPage = 0; + int usersLoadCurrentPage = 0; + int searchUsersLoadCurrentPage = 1; + private int currentUserId; + public final BindableBoolean isBlockedByMe=new BindableBoolean(); + public final BindableBoolean isBusy=new BindableBoolean(); + public final BindableString progressMessage=new BindableString(); + Set userIdsSet = new HashSet<>(); + QBRoster chatRoster; + List existDialogUserIds = new ArrayList<>(); + List selectedUsersList = new ArrayList<>(); + private SelectedAvatarsAdapter selectedAvatarsAdapter; + List localUsers = new ArrayList<>(); + private Set filteredUsers; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_create_chat); + binding = DataBindingUtil.setContentView(this, R.layout.activity_create_chat); + binding.setActivity(this); + adapter = new CreateChatListAdapter(); + adapter.setUserSelectedListener(this); + setSupportActionBar(binding.toolbar); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + binding.toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + } + }); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + currentUserId = prefs.getInt(C.QB_USERID, 0); + adapter.setCurrentUserId(currentUserId); + binding.listView.setAdapter(adapter); + adapter.setCallback(this); + binding.swipelayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + adapter.clear(); + dialogsLoadCurrentPage = 0; + usersLoadCurrentPage = 0; + searchUsersLoadCurrentPage = 1; + loadData(); + binding.swipelayout.setRefreshing(false); + } + }); + initChatRoster(); + + selectedAvatarsAdapter = new SelectedAvatarsAdapter(); + selectedAvatarsAdapter.setShowInitialLoad(false); + selectedAvatarsAdapter.disableLoadMore(); + binding.selectedAvatarsList.setAdapter(selectedAvatarsAdapter); + + if(getIntent().hasExtra(DIALOG_USERS_LIST)) { + existDialogUserIds = getIntent().getIntegerArrayListExtra(DIALOG_USERS_LIST); + binding.toolbarTitle.setText(getString(R.string.add_participant)); + } + initSearchPanel(); + } + + @Override + public void onStart() { + super.onStart(); + Handler h = new Handler(); + h.postDelayed(new Runnable() { + @Override + public void run() { + if(adapter.isShowInitialLoad()) { + adapter.clear(); + dialogsLoadCurrentPage = 0; + usersLoadCurrentPage = 0; + searchUsersLoadCurrentPage = 1; + loadData(); + } + } + }, 500); + } + + @Override + protected void onStop() { + adapter.clearSelectedUsersList(); + super.onStop(); + } + + private void initChatRoster() { + if(chatRoster == null) chatRoster = ChatRosterHelper.getChatRoster(); + } + + private void initSearchPanel() { + binding.searchAutocompleteText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + String query = v.getText().toString(); + if(query.length() > 0) { + hideSoftKeyboard(); + loadDataBySearchQuery(query); + } + return true; + } + return false; + } + }); + + binding.searchAutocompleteText.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) {} + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if(s.length() == 0) { + adapter.clear(); + adapter.addItems(localUsers); + adapter.disableLoadMore(); + } + } + }); + } + + public void loadData() { + if(chatRoster != null) { + Collection entries = chatRoster.getEntries(); + for(QBRosterEntry entry : entries) { + userIdsSet.add(entry.getUserId()); + } + } + + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.setLimit(10); + requestBuilder.setSkip(dialogsLoadCurrentPage * 10); + requestBuilder.sortDesc("last_message_date_sent"); + QBChatService.getChatDialogs(null, requestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList dialogs, Bundle args) { + if (dialogs.size() > 0) { + for(QBDialog dialog : dialogs) { + List occupants = dialog.getOccupants(); + try { + Integer recipientId = occupants.get(0) == currentUserId ? occupants.get(1) : occupants.get(0); + userIdsSet.add(recipientId); + } catch (Exception e) { + e.printStackTrace(); + } + } + getUsers(); + dialogsLoadCurrentPage++; + } + } + + @Override + public void onError(QBResponseException e) { + if (getApplicationContext()==null) return; + Util.onError(e, getApplicationContext()); + adapter.disableLoadMore(); + binding.swipelayout.setRefreshing(false); + } + }); + + } + + private void loadDataBySearchQuery(final String searchQuery) { + adapter.clear(); + adapter.setShowInitialLoad(true); + filteredUsers = new HashSet<>(); + for (QBUser user : localUsers) { + if (user.getFullName() != null && user.getFullName().contains(searchQuery) || + user.getLogin() != null && user.getLogin().contains(searchQuery) || + user.getEmail() != null && user.getEmail().contains(searchQuery)) + filteredUsers.add(user); + } + + new AsyncTask() { + @Override + protected Boolean doInBackground(Void... params) { + + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + Bundle bundle = new Bundle(); + try { + ArrayList resultByFullNameUsers = QBUsers.getUsersByFullName(searchQuery, pagedRequestBuilder, bundle); + if (resultByFullNameUsers.size() > 0) { + for (QBUser user : resultByFullNameUsers) { + if (user.getFullName() != null && user.getFullName().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + + ArrayList usersLogins = new ArrayList<>(); + usersLogins.add(searchQuery); + try { + ArrayList resultByLoginUsers = QBUsers.getUsersByLogins(usersLogins, pagedRequestBuilder, bundle); + if (resultByLoginUsers.size() > 0) { + for (QBUser user : resultByLoginUsers) { + if (user.getLogin() != null && user.getLogin().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + + ArrayList usersEmails = new ArrayList<>(); + usersEmails.add(searchQuery); + try { + ArrayList resultByEmailUsers = QBUsers.getUsersByEmails(usersEmails, pagedRequestBuilder, bundle); + if (resultByEmailUsers.size() > 0) { + for (QBUser user : resultByEmailUsers) { + if (user.getEmail() != null && user.getEmail().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + return true; + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + super.onPostExecute(aBoolean); + processSearchComplete(filteredUsers); + } + }.execute(); + } + + private void processSearchComplete(Set users) { + if(getIntent().hasExtra(DIALOG_USERS_LIST)) { + for (Iterator i = filteredUsers.iterator(); i.hasNext();) { + QBUser user = i.next(); + if(existDialogUserIds.contains(user.getId())) { + i.remove(); + } + } + } + + if (users.size() > 0) { + adapter.addItems(new ArrayList<>(users)); + } + + if (users.size() == 0 || users.size() < 10) { + adapter.disableLoadMore(); + } + binding.swipelayout.setRefreshing(false); + } + + private void getUsers() { + if(userIdsSet.size() > 0) { + + if(getIntent().hasExtra(DIALOG_USERS_LIST)) { + for(Integer id : existDialogUserIds) { + if(userIdsSet.contains(id)) userIdsSet.remove(id); + } + } + + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + pagedRequestBuilder.setPage(usersLoadCurrentPage); + pagedRequestBuilder.setPerPage(10); + QBUsers.getUsersByIDs(userIdsSet, pagedRequestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList users, Bundle params) { + if (adapter==null) return; + if (users.size() > 0) { + adapter.addItems(users); + localUsers.addAll(users); + usersLoadCurrentPage++; + } + + if (users.size() == 0 || users.size() < 10) { + adapter.disableLoadMore(); + } + binding.swipelayout.setRefreshing(false); + } + + @Override + public void onError(QBResponseException errors) { + if (getApplicationContext()==null) return; + Util.onError(errors, getApplicationContext()); + } + }); + } else { + adapter.disableLoadMore(); + binding.swipelayout.setRefreshing(false); + } + } + + @Override + public void onLoadMore() { + loadData(); + } + + @Override + public void onItemClick(final QBUser user) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (user != null) { + Intent intent = new Intent(CreateChatActivity.this, ProfileActivity.class); + intent.putExtra(C.QB_USERID, user.getId()); + intent.putExtra(C.QB_USER, user); + startActivity(intent); + } + } + }, 50); + } + + public void createChatOrAddMember() { + if(adapter == null) return; + List usersList = selectedUsersList; + if(usersList.size() == 0) return; + + if(getIntent().hasExtra(DIALOG_USERS_LIST)) { + Intent resultIntent = new Intent(); + ArrayList ids = new ArrayList<>(); + for (QBUser user : usersList) { + ids.add(user.getId()); + } + resultIntent.putIntegerArrayListExtra(GroupEditActivity.NEW_ADDED_USERS_LIST, ids); + setResult(RESULT_OK, resultIntent); + finish(); + return; + } + + if(usersList.size() > 1) { + // PRIVATE GROUP + ArrayList occupantIdsList = new ArrayList<>(); + for (QBUser user : usersList) { + occupantIdsList.add(user.getId()); + } + + QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + if (groupChatManager == null) return; + Intent i = new Intent(CreateChatActivity.this, ChatGroupActivity.class); + + i.putExtra(ChatGroupActivity.DIALOG_GROUP_TYPE, QBDialogType.GROUP); + i.putExtra(ChatGroupActivity.RECIPIENT_IDS_LIST, occupantIdsList); + i.putExtra(ChatGroupActivity.IS_FIRST_OPENED, true); + startActivity(i); + finish(); + } else if(usersList.size() == 1) { + // PRIVATE CHAT 1-1 + QBUser user = usersList.get(0); + QBPrivateChatManager chatManager = QBChatService.getInstance().getPrivateChatManager(); + if (chatManager == null) return; + Intent i = new Intent(CreateChatActivity.this, ChatActivity.class); + + i.putExtra(ChatActivity.RECIPIENT, user); + i.putExtra(Util.IS_BLOCKED, isBlockedByMe.get()); + startActivity(i); + finish(); + } + } + + @Override + public void userSelected(QBUser user) { + if(selectedUsersList.contains(user)) { + selectedUsersList.remove(user); + selectedAvatarsAdapter.removeItem(user); + } else { + selectedUsersList.add(user); + selectedAvatarsAdapter.addItem(user); + } + } + + private class SelectedAvatarsAdapter extends BaseListAdapter { + + int currentUserId; + ArrayMap userCache=new ArrayMap<>(); + + class SelectedAvatarsHolder extends DataHolder{ + + private final int size; + private RowSelectedAvatarBinding avatarBinding; + private SelectedAvatarsAdapter adapter; + + SelectedAvatarsHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + avatarBinding= DataBindingUtil.bind(v); + this.adapter= (SelectedAvatarsAdapter) adapter; + float d= view.getResources().getDisplayMetrics().density; + size=Math.round(35 * d); + } + + @Override + public void showData(DataItem data,int position) { + QBUser user = data.model.get(); + int userId=user.getId(); + + avatarBinding.userAvatar.setImageResource(R.drawable.user_placeholder); + if(!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), avatarBinding.userAvatar, size, size); + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + e.printStackTrace(); + } + }); + }else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), avatarBinding.userAvatar, size, size); + } + } + } + + @Override + public DataHolder getItemHolder(ViewGroup parent) { + View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_selected_avatar,parent,false); + return new SelectedAvatarsAdapter.SelectedAvatarsHolder(v,this); + } + + public void setCurrentUserId(int currentUserId) { + this.currentUserId = currentUserId; + } + + @Override + protected int getEmptyStateResId() { + return R.layout.empty_state_participants; + } + } + +} diff --git a/app/src/main/java/saberapplications/pawpads/ui/chat/CreateChatListAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/chat/CreateChatListAdapter.java new file mode 100644 index 0000000..eabfa10 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/chat/CreateChatListAdapter.java @@ -0,0 +1,139 @@ +package saberapplications.pawpads.ui.chat; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v4.util.ArrayMap; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; + +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import saberapplications.pawpads.R; +import saberapplications.pawpads.UserStatusHelper; +import saberapplications.pawpads.databinding.RowCreateChatItemBinding; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 26.05.17. + */ + +public class CreateChatListAdapter extends BaseListAdapter { + + private int currentUserId; + private ArrayMap userCache = new ArrayMap<>(); + private static OnUserSelectedListener mSelectedListener; + private static Set selectedUsers = new HashSet<>(); + + public interface OnUserSelectedListener { + public void userSelected(QBUser user); + } + + public void setUserSelectedListener(OnUserSelectedListener selectedListener) { + mSelectedListener = selectedListener; + } + + public static class CreateChatListHolder extends DataHolder{ + + private final int size; + RowCreateChatItemBinding binding; + CreateChatListAdapter adapter; + + public CreateChatListHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + binding= DataBindingUtil.bind(v); + this.adapter= (CreateChatListAdapter) adapter; + float d= view.getResources().getDisplayMetrics().density; + size=Math.round(60 * d); + } + + @Override + public void showData(final DataItem data, int position) { + final QBUser user = data.model.get(); + String userName = data.model.get().getFullName() == null ? data.model.get().getLogin() : data.model.get().getFullName(); + binding.setUsername(userName); + final int userId=user.getId(); + + binding.checkbox.setChecked(false); + if(selectedUsers.contains(userId)) binding.checkbox.setChecked(true); + binding.avatar.setImageResource(R.drawable.user_placeholder); + if(!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.avatar, size, size); + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + }else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), binding.avatar, size, size); + } + + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser != null) { + binding.setBindStatusVisibility(true); + binding.setOnlineStatus(UserStatusHelper.getUserStatus(qbUser)); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + + binding.checkboxLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(binding.checkbox.isChecked()) { + binding.checkbox.setChecked(false); + if(selectedUsers.contains(userId)) selectedUsers.remove(userId); + } else { + binding.checkbox.setChecked(true); + if(!selectedUsers.contains(userId)) selectedUsers.add(userId); + } + mSelectedListener.userSelected(user); + } + }); + } + } + + @Override + public DataHolder getItemHolder(ViewGroup parent) { + View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_create_chat_item,parent,false); + return new CreateChatListAdapter.CreateChatListHolder(v,this); + } + + public void setCurrentUserId(int currentUserId) { + this.currentUserId = currentUserId; + } + + @Override + protected int getEmptyStateResId() { + return R.layout.empty_state_create_chat; + } + + protected void clearSelectedUsersList() { + selectedUsers.clear(); + } +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsActivity.java b/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsActivity.java new file mode 100644 index 0000000..e41bdad --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsActivity.java @@ -0,0 +1,486 @@ +package saberapplications.pawpads.ui.friends; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.databinding.DataBindingUtil; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.support.v4.widget.SwipeRefreshLayout; +import android.text.Html; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.widget.ImageView; +import android.widget.TextView; + +import com.crashlytics.android.Crashlytics; +import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBRoster; +import com.quickblox.chat.listeners.QBRosterListener; +import com.quickblox.chat.listeners.QBSubscriptionListener; +import com.quickblox.chat.model.QBPresence; +import com.quickblox.chat.model.QBRosterEntry; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBPagedRequestBuilder; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.roster.packet.RosterPacket; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.Util; +import saberapplications.pawpads.databinding.ActivityFriendsBinding; +import saberapplications.pawpads.events.FriendRemovedEvent; +import saberapplications.pawpads.ui.BaseActivity; +import saberapplications.pawpads.ui.profile.ProfileActivity; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.views.BaseListAdapter; + +public class FriendsActivity extends BaseActivity implements BaseListAdapter.Callback { + public static final String TAG = FriendsActivity.class.getSimpleName(); + ActivityFriendsBinding binding; + FriendsAdapter adapter; + int currentPage = 1; + private int currentUserId; + QBRoster chatRoster; + AlertDialog requestDialog; + private boolean isLoading; + private int newUserInviteId; + boolean skipNextUpdate = false; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_friends); + binding = DataBindingUtil.setContentView(this, R.layout.activity_friends); + binding.setActivity(this); + adapter = new FriendsAdapter(); + setSupportActionBar(binding.toolbar); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + binding.toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + } + }); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + currentUserId = prefs.getInt(C.QB_USERID, 0); + adapter.setCurrentUserId(currentUserId); + binding.friendsListView.setAdapter(adapter); + adapter.setCallback(this); + binding.swipelayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (isLoading) { + binding.swipelayout.setRefreshing(false); + return; + } + adapter.setShowInitialLoad(true); + adapter.clear(); + currentPage = 0; + loadData(); + binding.swipelayout.setRefreshing(false); + } + }); + + chatRoster = getChatRoster(); + + EventBus.getDefault().register(this); + loadData(); + } + + private void showAddToFriendsRequestDialog(final QBUser user) { + if (user == null) return; + + if (requestDialog != null && requestDialog.isShowing()) return; + final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this) + .setCancelable(true); + + View view = LayoutInflater.from(this).inflate(R.layout.dialog_add_to_friends, null); + ImageView dialogAvatar = (ImageView) view.findViewById(R.id.dialog_avatar); + if (user.getFileId() != null) { + float density = getResources().getDisplayMetrics().density; + AvatarLoaderHelper.loadImage(user.getFileId(), dialogAvatar, + Math.round(density * 60), Math.round(density * 60)); + } + + TextView messageText = (TextView) view.findViewById(R.id.message_text); + String userName = user.getFullName() == null ? user.getLogin() : user.getFullName(); + String sourceString = getString(R.string.user) + " " + userName + " " + getString(R.string.wants_to_add_you_to_friendlist); + messageText.setText(Html.fromHtml(sourceString)); + + builder.setView(view); + + requestDialog = builder.create(); + requestDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + requestDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + requestDialog.show(); + + TextView acceptButton = (TextView) view.findViewById(R.id.send_friend_request); + acceptButton.setText(getString(R.string.accept_invite)); + acceptButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + acceptRequest(user.getId()); + requestDialog.dismiss(); + } + }); + + TextView rejectButton = (TextView) view.findViewById(R.id.cancel_button); + rejectButton.setText(getString(R.string.reject_invite)); + rejectButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + rejectRequest(user.getId()); + requestDialog.dismiss(); + } + }); + } + + private void loadDataAfterChanges() { + adapter.clear(); + currentPage = 0; + loadData(); + binding.swipelayout.setRefreshing(false); + } + + private void acceptRequest(final int userId) { + try { + chatRoster.confirmSubscription(userId); + Util.addFriendAcceptedList(userId); + Util.removeFriendOutInviteFromList(userId); + } catch (SmackException.NotConnectedException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.reconnect_message)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.you_are_not_logged_in)); + } catch (XMPPException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } catch (SmackException.NoResponseException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } + } + + private void rejectRequest(int userId) { + try { + skipNextUpdate = true; + chatRoster.reject(userId); + chatRoster.unsubscribe(userId); + if (chatRoster.getEntry(userId) != null && chatRoster.contains(userId)) { + chatRoster.removeEntry(chatRoster.getEntry(userId)); + } + if (newUserInviteId == userId) newUserInviteId = 0; + for (int i = 0; i < adapter.getItems().size(); i++) { + BaseListAdapter.DataItem item = adapter.getItems().get(i); + if (item.model.get().getId().intValue() == userId) { + adapter.getItems().remove(i); + adapter.notifyItemRemoved(i); + } + } + Util.removeFriendAcceptedList(userId); + + } catch (SmackException.NotConnectedException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.reconnect_message)); + } catch (XMPPException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.you_are_not_logged_in)); + } catch (SmackException.NoResponseException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } + } + + synchronized public void loadData() { + if (isLoading) return; + isLoading = true; + HashSet usersIds = new HashSet<>(); + if (chatRoster != null) { + Collection entries; + if (chatRoster.getUnfiledEntries() != null && chatRoster.getUnfiledEntries().size() > 0) { + entries = chatRoster.getUnfiledEntries(); + } else { + entries = chatRoster.getEntries(); + } + Log.d(TAG, "Collection entries " + entries.toString()); + Set acceptedUsers = Util.getFriendAcceptedList(); + Set invites = Util.getFriendOutInvitesList(); + for(QBRosterEntry entry : entries) { + if (acceptedUsers.contains(entry.getUserId().toString()) + && entry.getType() == RosterPacket.ItemType.none + && entry.getStatus() == null) { + rejectRequest(entry.getUserId()); + } else if (invites.contains(entry.getUserId().toString()) + && entry.getStatus()!=null + && entry.getStatus().name().equals("subscribe") + ){ + acceptRequest(entry.getUserId()); + usersIds.add(entry.getUserId()); + }else{ + usersIds.add(entry.getUserId()); + } + } + } + + if (Util.getFriendOutInvitesList().contains(String.valueOf(newUserInviteId))) { + // user who you sent request, sent request to you at the same time + acceptRequest(newUserInviteId); + newUserInviteId = 0; + } + + + boolean isFindRejectedInvites = false; + List rejectedInvites = new ArrayList<>(); + for (String userId : Util.getFriendOutInvitesList()) { + int id = Integer.parseInt(userId); + if (usersIds.contains(id) && chatRoster.getEntry(id) != null && + chatRoster.getEntry(id).getType() == RosterPacket.ItemType.none && + chatRoster.getEntry(id).getStatus() == null) { + isFindRejectedInvites = true; + rejectedInvites.add(userId); + } + } + if (isFindRejectedInvites) { + for (String userId : rejectedInvites) { + int id = Integer.parseInt(userId); + rejectRequest(id); + Util.removeFriendOutInviteFromList(id); + } + rejectedInvites.clear(); + } + + if (newUserInviteId != 0 && !usersIds.contains(newUserInviteId)) + getUserById(newUserInviteId); + + if (usersIds.size() > 0) { + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + pagedRequestBuilder.setPage(currentPage); + pagedRequestBuilder.setPerPage(10); + QBUsers.getUsersByIDs(usersIds, pagedRequestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList users, Bundle params) { + if (adapter == null) return; + if (users.size() == 0 || users.size() < 10) { + adapter.disableLoadMore(); + } + if (users.size() > 0) { + adapter.addItems(users); + currentPage++; + } + + binding.swipelayout.setRefreshing(false); + isLoading = false; + } + + @Override + public void onError(QBResponseException errors) { + if (getApplicationContext() == null) return; + adapter.disableLoadMore(); + Util.onError(errors, getApplicationContext()); + isLoading = false; + } + }); + } else { + adapter.disableLoadMore(); + binding.swipelayout.setRefreshing(false); + isLoading = false; + } + } + + @Override + public void onLoadMore() { + loadData(); + } + + @Override + public void onItemClick(final QBUser user) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (user != null) { + if (chatRoster != null && chatRoster.getEntry(user.getId()) != null && + chatRoster.getEntry(user.getId()).getType() == RosterPacket.ItemType.none && + chatRoster.getEntry(user.getId()).getStatus() == null) { + showAddToFriendsRequestDialog(user); + } else { + Intent intent = new Intent(FriendsActivity.this, ProfileActivity.class); + intent.putExtra(C.QB_USERID, user.getId()); + intent.putExtra(C.QB_USER, user); + startActivity(intent); + } + } + } + }, 50); + } + + public QBRoster getChatRoster() { + QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() { + @Override + public void subscriptionRequested(int userId) { + Log.d(TAG, "subscriptionRequested " + userId); + newUserInviteId = userId; + try { + chatRoster.reload(); + runOnUiThread(new Runnable() { + @Override + public void run() { + loadDataAfterChanges(); + } + }); + } catch (SmackException.NotConnectedException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.reconnect_message)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.you_are_not_logged_in)); + } + } + }; + + QBRosterListener rosterListener = new QBRosterListener() { + @Override + public void entriesDeleted(final Collection userIds) { + Log.d(TAG, "entriesDeleted " + userIds.toString()); + runOnUiThread(new Runnable() { + @Override + public void run() { + if (chatRoster != null) { + for (Integer userId : userIds) { + try { + + + if (chatRoster.getEntry(userId) != null && chatRoster.contains(userId)) { + chatRoster.removeEntry(chatRoster.getEntry(userId)); + } + if (userId.intValue() == newUserInviteId) { + newUserInviteId = 0; + } + for (int i = 0; i < adapter.getItems().size(); i++) { + BaseListAdapter.DataItem item = adapter.getItems().get(i); + if (item.model.get().getId().intValue() == userId) { + adapter.getItems().remove(i); + adapter.notifyItemRemoved(i); + } + } + + } catch (SmackException.NotConnectedException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.reconnect_message)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.you_are_not_logged_in)); + } catch (XMPPException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } catch (SmackException.NoResponseException e) { + handleOnError(FriendsActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } + } + } + } + }); + + } + + @Override + public void entriesAdded(Collection userIds) { + Log.d(TAG, "entriesAdded " + userIds.toString()); + } + + @Override + public void entriesUpdated(final Collection userIds) { + Log.d(TAG, "entriesUpdated " + userIds.toString()); + + runOnUiThread( + new Runnable() { + @Override + public void run() { + Set acceptedUsers = Util.getFriendAcceptedList(); + int i=0; + for (QBRosterEntry entry : chatRoster.getEntries()) { + if (acceptedUsers.contains(entry.getUserId().toString()) + && entry.getType() == RosterPacket.ItemType.none + && entry.getStatus() == null) { + rejectRequest(entry.getUserId()); + return; + } + i++; + } + + adapter.notifyDataSetChanged(); + + } + }); + } + + @Override + public void presenceChanged(QBPresence presence) { + Log.d(TAG, "presenceChanged " + presence.toString()); + } + }; + + // Do this after success Chat login + QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener); + if (chatRoster == null) return null; + chatRoster.addRosterListener(rosterListener); + + return chatRoster; + } + + private void getUserById(int userId) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser result, Bundle params) { + adapter.addItem(result); + } + + @Override + public void onError(QBResponseException e) { + Util.onError(e, FriendsActivity.this); + } + + }); + } + + public static void handleOnError(Context context, Exception e, String message) { + e.printStackTrace(); + Crashlytics.logException(e); + Util.showAlert(context, message); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onFriendRemoved(FriendRemovedEvent event) { + ArrayList> items = adapter.getItems(); + for (int i = 0; i < items.size(); i++) { + BaseListAdapter.DataItem item = items.get(i); + if (item.model.get().getId().intValue() == event.getUser().getId().intValue()) { + items.remove(i); + adapter.notifyItemRemoved(i); + if (newUserInviteId == event.getUser().getId().intValue()) { + newUserInviteId = 0; + } + } + } + + } +} diff --git a/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsAdapter.java new file mode 100644 index 0000000..8e42d3f --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/friends/FriendsAdapter.java @@ -0,0 +1,118 @@ +package saberapplications.pawpads.ui.friends; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v4.util.ArrayMap; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.quickblox.chat.QBRoster; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import org.jivesoftware.smack.roster.packet.RosterPacket; + +import saberapplications.pawpads.R; +import saberapplications.pawpads.UserStatusHelper; +import saberapplications.pawpads.databinding.RowFriendsBinding; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.util.ChatRosterHelper; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 22.05.17. + */ + +public class FriendsAdapter extends BaseListAdapter { + + int currentUserId; + ArrayMap userCache=new ArrayMap<>(); + public static class FriendsDialogHolder extends DataHolder{ + + private final int size; + RowFriendsBinding binding; + FriendsAdapter adapter; + QBRoster chatRoster = ChatRosterHelper.getChatRoster(); + + public FriendsDialogHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + binding= DataBindingUtil.bind(v); + this.adapter= (FriendsAdapter) adapter; + float d= view.getResources().getDisplayMetrics().density; + size=Math.round(60 * d); + } + + @Override + public void showData(DataItem data,int position) { + QBUser user = data.model.get(); + String userName = data.model.get().getFullName() == null ? data.model.get().getLogin() : data.model.get().getFullName(); + binding.setUsername(userName); + int userId=user.getId(); + + binding.newFriendRequest.setVisibility(View.GONE); + binding.newFriendRequestIndicator.setVisibility(View.GONE); + if(chatRoster != null && chatRoster.getEntry(userId) != null && + chatRoster.getEntry(userId).getType() == RosterPacket.ItemType.none && + chatRoster.getEntry(userId).getStatus() == null) { + binding.newFriendRequest.setVisibility(View.VISIBLE); + binding.newFriendRequestIndicator.setVisibility(View.VISIBLE); + }else if (chatRoster != null && !chatRoster.contains(userId)){ + binding.newFriendRequest.setVisibility(View.VISIBLE); + binding.newFriendRequestIndicator.setVisibility(View.VISIBLE); + } + + binding.avatar.setImageResource(R.drawable.user_placeholder); + if(!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.avatar, size, size); + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + }else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), binding.avatar, size, size); + } + + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser != null) { + binding.setBindStatusVisibility(true); + binding.setOnlineStatus(UserStatusHelper.getUserStatus(qbUser)); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + } + } + + @Override + public DataHolder getItemHolder(ViewGroup parent) { + View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_friends,parent,false); + return new FriendsAdapter.FriendsDialogHolder(v,this); + } + + public void setCurrentUserId(int currentUserId) { + this.currentUserId = currentUserId; + } + + @Override + protected int getEmptyStateResId() { + return R.layout.empty_state_friends; + } +} diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/ChannelsFragment.java b/app/src/main/java/saberapplications/pawpads/ui/home/ChannelsFragment.java new file mode 100644 index 0000000..038dac9 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/home/ChannelsFragment.java @@ -0,0 +1,222 @@ +package saberapplications.pawpads.ui.home; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.widget.SwipeRefreshLayout; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBGroupChatManager; +import com.quickblox.chat.model.QBChatMessage; +import com.quickblox.chat.model.QBDialog; +import com.quickblox.chat.model.QBDialogType; +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBRequestGetBuilder; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; + +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.Util; +import saberapplications.pawpads.databinding.FragmentChannelsBinding; +import saberapplications.pawpads.ui.chat.ChatGroupActivity; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 08.06.17. + */ + +public class ChannelsFragment extends Fragment implements BaseListAdapter.Callback { + + private static final int MAX_AMOUNT_OF_CREATED_CHANNELS = 3; + FragmentChannelsBinding binding; + ChatsAdapter adapter; + int currentPage = 0; + private int currentUserId; + private boolean isLoading; + + public ChannelsFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View view = inflater.inflate(R.layout.fragment_channels, container, false); + binding = DataBindingUtil.bind(view); + binding.setFragment(this); + adapter = new ChatsAdapter(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + currentUserId = prefs.getInt(C.QB_USERID, 0); + adapter.setCurrentUserId(currentUserId); + binding.listView.setAdapter(adapter); + adapter.setCallback(this); + binding.swipelayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if(isLoading) { + binding.swipelayout.setRefreshing(false); + return; + } + adapter.setShowInitialLoad(true); + adapter.clear(); + currentPage = 0; + loadData(); + binding.swipelayout.setRefreshing(false); + } + }); + checkAmountOfCreatedChannels(); + EventBus.getDefault().register(this); + return view; + } + + @Override + public void onStart() { + super.onStart(); + Handler h = new Handler(); + h.postDelayed(new Runnable() { + @Override + public void run() { + if (adapter.getItemCount()<=1){ + adapter.clear(); + currentPage = 0; + loadData(); + } + } + }, 700); + adapter.notifyDataSetChanged(); + } + + public void loadData() { + isLoading = true; + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.setLimit(10); + requestBuilder.setSkip(currentPage * 10); + requestBuilder.sortDesc("last_message_date_sent"); + QBChatService.getChatDialogs(QBDialogType.PUBLIC_GROUP, requestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList dialogs, Bundle args) { + if (adapter==null) return; + if (dialogs.size() > 0) { + adapter.addItems(dialogs); + currentPage++; + } + + if (dialogs.size() == 0 || dialogs.size() < 10) { + adapter.disableLoadMore(); + } + binding.swipelayout.setRefreshing(false); + isLoading = false; + } + + @Override + public void onError(QBResponseException e) { + if (adapter!=null) adapter.disableLoadMore(); + binding.swipelayout.setRefreshing(false); + isLoading = false; + if (getContext()==null) return; + Util.onError(e, getContext()); + } + }); + } + + public void reloadData() { + if(isLoading) return; + adapter.setShowInitialLoad(true); + adapter.clear(); + currentPage = 0; + loadData(); + binding.swipelayout.setRefreshing(false); + } + + private void checkAmountOfCreatedChannels() { + QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); + requestBuilder.setLimit(100); + requestBuilder.sortDesc("last_message_date_sent"); + QBChatService.getChatDialogs(QBDialogType.PUBLIC_GROUP, requestBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList dialogs, Bundle args) { + if(dialogs.size() == 0) return; + int amountOfCreatedChannels = 0; + for (QBDialog dialog : dialogs) { + if(dialog.getUserId() == currentUserId) { + amountOfCreatedChannels++; + } + } + Util.setCreatedChannelsCount(amountOfCreatedChannels); + } + + @Override + public void onError(QBResponseException errors) { + errors.printStackTrace(); + } + }); + } + + @Override + public void onLoadMore() { + loadData(); + } + + @Override + public void onItemClick(final QBDialog dialog) { + ArrayList occupansts = (ArrayList) dialog.getOccupants(); + Intent intent = new Intent(getContext(), ChatGroupActivity.class); + intent.putExtra(ChatGroupActivity.DIALOG, dialog); + intent.putExtra(ChatGroupActivity.RECIPIENT_IDS_LIST, occupansts); + startActivity(intent); + } + + public void createNewPublicGroup() { + if(Util.getCreatedChannelsCount() < MAX_AMOUNT_OF_CREATED_CHANNELS) { + QBGroupChatManager groupChatManager = QBChatService.getInstance().getGroupChatManager(); + if (groupChatManager == null) return; + Intent i = new Intent(getActivity(), ChatGroupActivity.class); + i.putExtra(ChatGroupActivity.DIALOG_GROUP_TYPE, QBDialogType.PUBLIC_GROUP); + i.putExtra(ChatGroupActivity.IS_FIRST_OPENED, true); + startActivity(i); + Util.setCreatedChannelsCount(Util.getCreatedChannelsCount()+1); + } else { + Toast.makeText(getActivity(), getActivity().getString(R.string.sorry_cannot_create_more_three_channels), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(QBChatMessage msg) { + ArrayList> items = adapter.getItems(); + for(int i=0;i item=items.get(i); + QBDialog dlg=item.model.get(); + if (dlg.getDialogId().equals(msg.getDialogId())){ + dlg.setLastMessageDateSent(msg.getDateSent()); + dlg.setLastMessage(msg.getBody()); + dlg.setLastMessageUserId(msg.getSenderId()); + items.remove(i); + items.add(0,item); + adapter.notifyItemChanged(i); + adapter.notifyItemChanged(0); + binding.listView.scrollToPosition(0); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/ChatsAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/home/ChatsAdapter.java index 719f9f0..4db03b9 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/ChatsAdapter.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/ChatsAdapter.java @@ -6,8 +6,10 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import com.quickblox.chat.model.QBDialog; +import com.quickblox.chat.model.QBDialogType; import com.quickblox.core.QBEntityCallback; import com.quickblox.core.exception.QBResponseException; import com.quickblox.users.QBUsers; @@ -44,7 +46,11 @@ public ChatDialogHolder(View v, BaseListAdapter adapter) { @Override public void showData(DataItem data,int position) { QBDialog dialog=data.model.get(); - binding.setLastMessage(data.model.get().getLastMessage()); + String lastMessage = data.model.get().getLastMessage(); + if(lastMessage != null && lastMessage.length() > 25) { + lastMessage = lastMessage.substring(0, 22) + "..."; + } + binding.setLastMessage(lastMessage); binding.setUsername(data.model.get().getName()); int userId=0; for(int uid:dialog.getOccupants()){ @@ -54,13 +60,35 @@ public void showData(DataItem data,int position) { } binding.avatar.setImageResource(R.drawable.user_placeholder); - if(!adapter.userCache.containsKey(userId)) { + binding.avatarLastMessage.setImageResource(R.drawable.user_placeholder); + binding.avatarLastMessage.setVisibility(View.GONE); + + if(dialog.getType() == QBDialogType.GROUP || dialog.getType() == QBDialogType.PUBLIC_GROUP) { + try { + int lastMsgUserId = data.model.get().getLastMessageUserId(); + float d= view.getResources().getDisplayMetrics().density; + binding.avatarLastMessage.setVisibility(View.VISIBLE); + loadUserAvatar(lastMsgUserId, binding.avatarLastMessage, Math.round(25 * d)); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + AvatarLoaderHelper.loadImage(Integer.parseInt(dialog.getPhoto()), binding.avatar, size, size, null); + } catch (Exception e) { + e.printStackTrace(); + } + binding.setBindStatusVisibility(false); + + } else { + loadUserAvatar(userId, binding.avatar, size); + QBUsers.getUser(userId, new QBEntityCallback() { @Override public void onSuccess(QBUser qbUser, Bundle bundle) { - if (qbUser.getFileId() != null) { - AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.avatar, size, size); - adapter.userCache.put(qbUser.getId(), qbUser); + if (qbUser != null) { + binding.setBindStatusVisibility(true); + binding.setOnlineStatus(UserStatusHelper.getUserStatus(qbUser)); } } @@ -69,24 +97,28 @@ public void onError(QBResponseException e) { } }); - }else { - AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), binding.avatar, size, size); } + } - QBUsers.getUser(userId, new QBEntityCallback() { - @Override - public void onSuccess(QBUser qbUser, Bundle bundle) { - if (qbUser != null) { - binding.setBindStatusVisibility(true); - binding.setOnlineStatus(UserStatusHelper.getUserStatus(qbUser)); + private void loadUserAvatar(int userId, final ImageView avatar, final int avatarSize) { + if (!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), avatar, avatarSize, avatarSize); + adapter.userCache.put(qbUser.getId(), qbUser); + } } - } - @Override - public void onError(QBResponseException e) { + @Override + public void onError(QBResponseException e) { - } - }); + } + }); + } else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), avatar, avatarSize, avatarSize); + } } } diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/ChatsFragment.java b/app/src/main/java/saberapplications/pawpads/ui/home/ChatsFragment.java index 36cce4e..49f0c32 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/ChatsFragment.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/ChatsFragment.java @@ -14,11 +14,17 @@ import android.view.ViewGroup; import com.quickblox.chat.QBChatService; +import com.quickblox.chat.model.QBChatMessage; import com.quickblox.chat.model.QBDialog; +import com.quickblox.chat.model.QBDialogType; import com.quickblox.core.QBEntityCallback; import com.quickblox.core.exception.QBResponseException; import com.quickblox.core.request.QBRequestGetBuilder; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + import java.util.ArrayList; import java.util.List; @@ -27,6 +33,8 @@ import saberapplications.pawpads.Util; import saberapplications.pawpads.databinding.FragmentChatsBinding; import saberapplications.pawpads.ui.chat.ChatActivity; +import saberapplications.pawpads.ui.chat.ChatGroupActivity; +import saberapplications.pawpads.ui.chat.CreateChatActivity; import saberapplications.pawpads.views.BaseListAdapter; /** @@ -38,18 +46,19 @@ public class ChatsFragment extends Fragment implements BaseListAdapter.Callback< ChatsAdapter adapter; int currentPage = 0; private int currentUserId; + private boolean isLoading; public ChatsFragment() { // Required empty public constructor } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_chats, container, false); binding = DataBindingUtil.bind(view); + binding.setFragment(this); adapter = new ChatsAdapter(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); currentUserId = prefs.getInt(C.QB_USERID, 0); @@ -59,12 +68,18 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, binding.swipelayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { + if (isLoading) { + binding.swipelayout.setRefreshing(false); + return; + } + adapter.setShowInitialLoad(true); adapter.clear(); currentPage = 0; loadData(); binding.swipelayout.setRefreshing(false); } }); + EventBus.getDefault().register(this); return view; } @@ -75,48 +90,66 @@ public void onStart() { h.postDelayed(new Runnable() { @Override public void run() { - if(adapter.isShowInitialLoad()) { - adapter.clear(); - currentPage = 0; - loadData(); - } + if (adapter.getItemCount() <= 1) { + currentPage = 0; + adapter.clear(); + loadData(); + } } - }, 5000); - adapter.notifyDataSetChanged(); + }, 500); } public void loadData() { + isLoading = true; QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder(); requestBuilder.setLimit(10); requestBuilder.setSkip(currentPage * 10); + requestBuilder.in("type","2","3"); requestBuilder.sortDesc("last_message_date_sent"); + QBChatService.getChatDialogs(null, requestBuilder, new QBEntityCallback>() { @Override public void onSuccess(ArrayList dialogs, Bundle args) { - if (adapter==null) return; + if (adapter == null) return; + if (dialogs.size() == 0 || dialogs.size() < 10) { + adapter.disableLoadMore(); + } if (dialogs.size() > 0) { - adapter.addItems(dialogs); + ArrayList privateDialogs = new ArrayList<>(); + for (QBDialog dialog : dialogs) { + if (!dialog.getType().equals(QBDialogType.PUBLIC_GROUP)) + privateDialogs.add(dialog); + } + adapter.addItems(privateDialogs); currentPage++; } - if (dialogs.size() == 0 || dialogs.size() < 10) { - adapter.disableLoadMore(); - } - binding.swipelayout.setRefreshing(false); + binding.swipelayout.setRefreshing(false); + isLoading = false; } @Override public void onError(QBResponseException e) { - if (getContext()==null) return; + adapter.disableLoadMore(); + binding.swipelayout.setRefreshing(false); + isLoading = false; + if (getContext() == null) return; Util.onError(e, getContext()); } - - }); } + public void reloadData() { + if (isLoading) return; + adapter.setShowInitialLoad(true); + adapter.clear(); + currentPage = 0; + loadData(); + binding.swipelayout.setRefreshing(false); + } + @Override public void onLoadMore() { loadData(); @@ -124,15 +157,51 @@ public void onLoadMore() { @Override public void onItemClick(final QBDialog dialog) { + if (dialog.getType() == QBDialogType.GROUP) { + ArrayList occupansts = (ArrayList) dialog.getOccupants(); + Intent intent = new Intent(getContext(), ChatGroupActivity.class); + intent.putExtra(ChatGroupActivity.DIALOG, dialog); + intent.putExtra(ChatGroupActivity.RECIPIENT_IDS_LIST, occupansts); + startActivity(intent); + } else { + List occupansts = dialog.getOccupants(); + Integer recipientId = occupansts.get(0) == currentUserId ? occupansts.get(1) : occupansts.get(0); + + Intent intent = new Intent(getContext(), ChatActivity.class); + intent.putExtra(ChatActivity.DIALOG, dialog); + intent.putExtra(ChatActivity.RECIPIENT_ID, recipientId); + startActivity(intent); + } + } - - List occupansts = dialog.getOccupants(); - Integer recipientId = occupansts.get(0) == currentUserId ? occupansts.get(1) : occupansts.get(0); - - Intent intent = new Intent(getContext(), ChatActivity.class); - intent.putExtra(ChatActivity.DIALOG, dialog); - intent.putExtra(ChatActivity.RECIPIENT_ID, recipientId); + public void createNewChatOrGroup() { + Intent intent = new Intent(getContext(), CreateChatActivity.class); startActivity(intent); + } + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(QBChatMessage msg) { + ArrayList> items = adapter.getItems(); + for(int i=0;i item=items.get(i); + QBDialog dlg=item.model.get(); + if (dlg.getDialogId().equals(msg.getDialogId())){ + dlg.setLastMessageDateSent(msg.getDateSent()); + dlg.setLastMessage(msg.getBody()); + dlg.setLastMessageUserId(msg.getSenderId()); + item.model.set(dlg); + items.remove(i); + items.add(0,item); + adapter.notifyItemChanged(i); + adapter.notifyItemChanged(0); + binding.listView.scrollToPosition(0); + } + } } } diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/MainActivity.java b/app/src/main/java/saberapplications/pawpads/ui/home/MainActivity.java index 1c03fb1..791ea54 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/MainActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/MainActivity.java @@ -48,6 +48,10 @@ import com.quickblox.users.QBUsers; import com.quickblox.users.model.QBUser; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + import java.io.IOException; import java.util.ArrayList; @@ -56,14 +60,17 @@ import saberapplications.pawpads.UserLocalStore; import saberapplications.pawpads.Util; import saberapplications.pawpads.databinding.ActivityMainBinding; +import saberapplications.pawpads.events.UpdateChatEvent; import saberapplications.pawpads.model.UserProfile; import saberapplications.pawpads.service.UserLocationService; import saberapplications.pawpads.ui.AboutActivity; import saberapplications.pawpads.ui.BaseActivity; import saberapplications.pawpads.ui.chat.ChatActivity; +import saberapplications.pawpads.ui.friends.FriendsActivity; import saberapplications.pawpads.ui.login.LoginActivity; import saberapplications.pawpads.ui.profile.ProfileActivity; import saberapplications.pawpads.ui.profile.ProfileEditActivity; +import saberapplications.pawpads.ui.search.SearchActivity; import saberapplications.pawpads.ui.settings.PrefrenceActivity; import saberapplications.pawpads.util.AvatarLoaderHelper; import saberapplications.pawpads.util.LocationServiceHelper; @@ -82,6 +89,7 @@ public class MainActivity extends BaseActivity { ActivityMainBinding binding; NearByFragment nearByFragment; ChatsFragment chatsFragment; + ChannelsFragment channelsFragment; UserLocalStore userLocalStore; private UserListAdapter adapter; private Location lastListUpdatedLocation; @@ -145,6 +153,7 @@ public void onDrawerOpened(View drawerView) { nearByFragment = new NearByFragment(); chatsFragment = new ChatsFragment(); + channelsFragment = new ChannelsFragment(); binding.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override @@ -162,7 +171,15 @@ public void run() { chatsFragment.loadData(); } },50); - + } + if (position == 2 && (channelsFragment.adapter==null || channelsFragment.adapter.getItemCount()==0)) { + Handler handler=new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + channelsFragment.loadData(); + } + },50); } } @@ -172,6 +189,7 @@ public void onPageScrollStateChanged(int state) { } }); binding.viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager())); + binding.viewPager.setOffscreenPageLimit(2); binding.tabLayout.setupWithViewPager(binding.viewPager); //banner ad @@ -183,6 +201,7 @@ public void onPageScrollStateChanged(int state) { if (checkPermissions()){ LocationServiceHelper.checkService(this); } + EventBus.getDefault().register(this); } @Override @@ -309,12 +328,16 @@ protected void onStop() { if (QBChatService.getInstance() != null && QBChatService.getInstance().getPrivateChatManager() != null && chatListener != null) { QBChatService.getInstance().getPrivateChatManager().removePrivateChatManagerListener(chatListener); } + if (QBChatService.getInstance() != null && QBChatService.getInstance().getGroupChatManager() != null && groupChatListener != null) { + QBChatService.getInstance().getGroupChatManager().removeGroupChatManagerListener(groupChatListener); + } } } @Override protected void onDestroy() { + EventBus.getDefault().unregister(this); super.onDestroy(); LocalBroadcastManager.getInstance(this).unregisterReceiver(userDataChanged); } @@ -530,15 +553,16 @@ public ViewPagerAdapter(FragmentManager fm) { public Fragment getItem(int position) { if (position == 0) { return nearByFragment; - } else { + } else if(position == 1){ return chatsFragment; + } else { + return channelsFragment; } - } @Override public int getCount() { - return 2; + return 3; } @@ -546,30 +570,50 @@ public int getCount() { public CharSequence getPageTitle(int position) { if (position == 0) { return getString(R.string.near_by); - } else { + } else if(position == 1) { return getString(R.string.chats); + } else { + return getString(R.string.channels); } } } + public void openProfile() { + if(currentQBUser == null) return; + Intent intent = new Intent(this, ProfileActivity.class); + intent.putExtra(C.QB_USERID, currentQBUser.getId()); + intent.putExtra(C.QB_USER, currentQBUser); + startActivity(intent); + + animateActivityStarting(); + } public void editProfile() { - binding.navigationDrawer.closeDrawer(Gravity.LEFT); Intent intent = new Intent(this, ProfileEditActivity.class); startActivity(intent); + animateActivityStarting(); } public void openSettings() { - binding.navigationDrawer.closeDrawer(Gravity.LEFT); startActivity(new Intent(this, PrefrenceActivity.class)); + animateActivityStarting(); } public void openAbout() { - binding.navigationDrawer.closeDrawer(Gravity.LEFT); startActivity(new Intent(this, AboutActivity.class)); + animateActivityStarting(); + } + private void animateActivityStarting() { + overridePendingTransition(R.anim.fade_in, R.anim.fade_out); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + binding.navigationDrawer.closeDrawer(Gravity.LEFT); + } + }, 300); } public void logout() { @@ -594,12 +638,26 @@ private boolean checkPermissions() { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST); return false; } - } return true; } + public void search() { + Intent intent = new Intent(MainActivity.this, SearchActivity.class); + startActivity(intent); + } + public void openFriendsActivity() { + Intent intent = new Intent(MainActivity.this, FriendsActivity.class); + startActivity(intent); + animateActivityStarting(); + } + + @Subscribe(threadMode = ThreadMode.POSTING) + public void onChatMessageEvent(UpdateChatEvent event) { + //if(chatsFragment.isVisible()) chatsFragment.reloadData(); + //if(channelsFragment.isVisible()) channelsFragment.reloadData(); + } } diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/NearByAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/home/NearByAdapter.java index e9cda39..25ae3ae 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/NearByAdapter.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/NearByAdapter.java @@ -18,6 +18,7 @@ import saberapplications.pawpads.Util; import saberapplications.pawpads.databinding.RowNearByBinding; import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.util.OtherUsersLocationsCache; import saberapplications.pawpads.views.BaseListAdapter; /** @@ -103,6 +104,7 @@ public String getDistance(QBLocation qbLocation){ Location userLocation = new Location(""); userLocation.setLatitude(qbLocation.getLatitude()); userLocation.setLongitude(qbLocation.getLongitude()); + OtherUsersLocationsCache.put(data.model.get().getLocation().getUserId(),userLocation); return Util.formatDistance(userLocation.distanceTo(adapter.getLocation())); } diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/NearByFragment.java b/app/src/main/java/saberapplications/pawpads/ui/home/NearByFragment.java index 713fc24..273e1ab 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/NearByFragment.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/NearByFragment.java @@ -112,6 +112,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, @Override public void onRefresh() { adapter.clear(); + adapter.setShowInitialLoad(true); currentPage=1; loadData(); binding.swipelayout.setRefreshing(false); @@ -121,6 +122,9 @@ public void onRefresh() { progressMessage.set(getString(R.string.obtaining_location)); if (UserLocationService.getLastLocation()!=null){ loadData(); + } else { + adapter.disableLoadMore(); + isBusy.set(false); } return view; } @@ -156,9 +160,14 @@ protected List doInBackground(Void... params) { ArrayList dialogList = QBChatService.getChatDialogs(null, requestBuilder, out); if (dialogList != null && dialogList.size() > 0) { for (QBDialog dialog : dialogList) { - int userId = dialog.getOccupants().get(0) == currentUserId ? dialog.getOccupants().get(1) : dialog.getOccupants().get(0); - if (dialog.getLastMessageDateSent() > 0) { - lastMessages.put(userId, dialog.getLastMessageDateSent()); + try { + if (dialog.getOccupants()==null || dialog.getOccupants().size()==0) continue; + int userId = dialog.getOccupants().get(0) == currentUserId ? dialog.getOccupants().get(1) : dialog.getOccupants().get(0); + if (dialog.getLastMessageDateSent() > 0) { + lastMessages.put(userId, dialog.getLastMessageDateSent()); + } + } catch (Exception e) { + e.printStackTrace(); } } } @@ -222,6 +231,7 @@ protected void onPostExecute(List nearByItems) { } binding.swipelayout.setRefreshing(false); + isBusy.set(false); } }; diff --git a/app/src/main/java/saberapplications/pawpads/ui/home/SplashActivity.java b/app/src/main/java/saberapplications/pawpads/ui/home/SplashActivity.java index 0808132..036d6ae 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/home/SplashActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/home/SplashActivity.java @@ -22,15 +22,17 @@ import saberapplications.pawpads.R; import saberapplications.pawpads.Util; import saberapplications.pawpads.ui.login.LoginActivity; +import saberapplications.pawpads.views.NetworkStateChangedHelper; public class SplashActivity extends AppCompatActivity { boolean returnResult; private SharedPreferences prefs; - + NetworkStateChangedHelper networkStateChangedHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + networkStateChangedHelper=new NetworkStateChangedHelper(this); prefs = PreferenceManager.getDefaultSharedPreferences(this); setContentView(R.layout.activity_splash); if (getIntent() != null) { @@ -52,6 +54,10 @@ public boolean isLoggedIn() { @Override protected void onStart() { super.onStart(); + if (!networkStateChangedHelper.isConnected()){ + networkStateChangedHelper.checkNeworkConnection(); + return; + } QBAuth.createSession(new QBEntityCallback() { @Override public void onSuccess(QBSession qbSession, Bundle bundle) { diff --git a/app/src/main/java/saberapplications/pawpads/ui/login/ForgotPasswordActivity.java b/app/src/main/java/saberapplications/pawpads/ui/login/ForgotPasswordActivity.java index 9aa20f7..4dea995 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/login/ForgotPasswordActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/login/ForgotPasswordActivity.java @@ -55,7 +55,7 @@ protected void onCreate(Bundle savedInstanceState) { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { hideSoftKeyboard(); if (actionId== EditorInfo.IME_ACTION_DONE){ - recover(); + //recover(); return true; } return false; diff --git a/app/src/main/java/saberapplications/pawpads/ui/login/LoginActivity.java b/app/src/main/java/saberapplications/pawpads/ui/login/LoginActivity.java index cdd8810..795118d 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/login/LoginActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/login/LoginActivity.java @@ -49,6 +49,7 @@ import saberapplications.pawpads.databinding.ActivityLoginBinding; import saberapplications.pawpads.ui.home.MainActivity; import saberapplications.pawpads.ui.register.RegisterActivity; +import saberapplications.pawpads.views.NetworkStateChangedHelper; /** * Created by blaze on 10/21/2015. @@ -64,10 +65,11 @@ public class LoginActivity extends AppCompatActivity { private TwitterAuthClient twitterAuthClient; public final ObservableBoolean isBusy = new ObservableBoolean(false); ActivityLoginBinding binding; - + NetworkStateChangedHelper networkStateChangedHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + networkStateChangedHelper=new NetworkStateChangedHelper(this); binding = DataBindingUtil.setContentView(this, R.layout.activity_login); binding.setActivity(this); setTitle("PawPads | Login"); @@ -83,7 +85,6 @@ protected void onCreate(Bundle savedInstanceState) { forgotpasswordLink = (TextView) findViewById(R.id.tvForgottenPassLink); userLocalStore = new UserLocalStore(this); - //FB setup callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback() { @@ -205,7 +206,7 @@ protected Void doInBackground(Void... params) { try { QBAuth.createSession(); - QBUser user = QBUsers.signInUsingSocialProvider(QBProvider.TWITTER, sessionData.getAuthToken().token, sessionData.getAuthToken().secret); + QBUser user = QBUsers.signInUsingSocialProvider(QBProvider.TWITTER,sessionData.getAuthToken().token, sessionData.getAuthToken().secret); onSuccessLogin(user, null, sessionData.getAuthToken().token, sessionData.getAuthToken().secret); } catch (QBResponseException e) { diff --git a/app/src/main/java/saberapplications/pawpads/ui/profile/ProfileActivity.java b/app/src/main/java/saberapplications/pawpads/ui/profile/ProfileActivity.java index 366c4a8..9c1ce25 100644 --- a/app/src/main/java/saberapplications/pawpads/ui/profile/ProfileActivity.java +++ b/app/src/main/java/saberapplications/pawpads/ui/profile/ProfileActivity.java @@ -1,20 +1,28 @@ package saberapplications.pawpads.ui.profile; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.databinding.DataBindingUtil; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; +import android.text.Html; +import android.view.LayoutInflater; import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import com.crashlytics.android.Crashlytics; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; import com.google.android.gms.ads.InterstitialAd; @@ -22,6 +30,7 @@ import com.quickblox.chat.QBPrivacyListsManager; import com.quickblox.chat.QBPrivateChat; import com.quickblox.chat.QBPrivateChatManager; +import com.quickblox.chat.QBRoster; import com.quickblox.chat.model.QBChatMessage; import com.quickblox.chat.model.QBPrivacyList; import com.quickblox.chat.model.QBPrivacyListItem; @@ -32,6 +41,10 @@ import com.quickblox.users.QBUsers; import com.quickblox.users.model.QBUser; +import org.greenrobot.eventbus.EventBus; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.roster.packet.RosterPacket; import org.json.JSONArray; import java.util.ArrayList; @@ -47,10 +60,12 @@ import saberapplications.pawpads.databinding.ActivityProfilepageBinding; import saberapplications.pawpads.databinding.BindableBoolean; import saberapplications.pawpads.databinding.BindableString; +import saberapplications.pawpads.events.FriendRemovedEvent; import saberapplications.pawpads.model.UserProfile; import saberapplications.pawpads.ui.BaseActivity; import saberapplications.pawpads.ui.chat.ChatActivity; import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.util.ChatRosterHelper; public class ProfileActivity extends BaseActivity { @@ -58,17 +73,19 @@ public class ProfileActivity extends BaseActivity { private TextView isBlockedView; private QBUser qbUser; - public final BindableBoolean isBlockedByOther=new BindableBoolean(); - public final BindableBoolean isBlockedByMe=new BindableBoolean(); - public final BindableBoolean isBusy=new BindableBoolean(); - public final BindableString progressMessage=new BindableString(); + public final BindableBoolean isBlockedByOther = new BindableBoolean(); + public final BindableBoolean isBlockedByMe = new BindableBoolean(); + public final BindableBoolean isBusy = new BindableBoolean(); + public final BindableString progressMessage = new BindableString(); UserProfile profile; ActivityProfilepageBinding binding; + QBRoster chatRoster; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - binding=DataBindingUtil.setContentView(this,R.layout.activity_profilepage); + binding = DataBindingUtil.setContentView(this, R.layout.activity_profilepage); binding.setActivity(this); setSupportActionBar(binding.toolbar); @@ -79,28 +96,56 @@ protected void onCreate(Bundle savedInstanceState) { progressMessage.set(getString(R.string.loading)); isBlockedView = (TextView) findViewById(R.id.is_blocked); - qbUser= (QBUser) getIntent().getSerializableExtra(C.QB_USER); + qbUser = (QBUser) getIntent().getSerializableExtra( C.QB_USER); binding.setUser(qbUser); + + initChatRoster(); + setFriendsUI(); + + if (isOwnProfile()) { + isBlockedByMe.set(true); + hideFieldsInOwnProfile(); + } + //banner ad - AdView adView = (AdView)findViewById(R.id.profileAdView); + AdView adView = (AdView) findViewById(R.id.profileAdView); adView.loadAd(requestNewAd()); } + private boolean isOwnProfile() { + if (qbUser != null && qbUser.getId() == preferences.getInt(C.QB_USERID, 0)) { + return true; + } + return false; + } + + private void hideFieldsInOwnProfile() { + binding.blockUserView.setVisibility(View.GONE); + binding.blockUserView.setText(""); + binding.blockUserView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); + binding.openChatButton.setVisibility(View.GONE); + binding.addToFriendsButton.setVisibility(View.GONE); + binding.openChatButtonBg.setVisibility(View.GONE); + binding.addToFriendsButtonBg.setVisibility(View.GONE); + binding.unblockButton.setVisibility(View.GONE); + } + @Override public void onQBConnect(boolean isActivityReopened) throws Exception { if (isActivityReopened) return; isBusy.set(true); new AsyncTask() { Exception e; + @Override protected Void doInBackground(Void... params) { try { // qbUser = QBUsers.getUser(getIntent().getExtras().getInt(C.QB_USERID, -1)); - if(currentQBUser==null) { + if (currentQBUser == null) { currentQBUser = QBUsers.getUser(PreferenceManager.getDefaultSharedPreferences(ProfileActivity.this).getInt(C.QB_USERID, -1)); } - if (qbUser.getFullName()==null){ + if (qbUser.getFullName() == null) { qbUser.setFullName(qbUser.getLogin()); } binding.setUser(qbUser); @@ -115,18 +160,16 @@ protected Void doInBackground(Void... params) { requestBuilder.eq("source_user", currentQBUser.getId()); requestBuilder.eq("blocked_user", qbUser.getId()); ArrayList blocks = QBCustomObjects.getObjects("BlockList", requestBuilder, new Bundle()); - isBlockedByMe.set( blocks.size() > 0); + if (!isOwnProfile()) isBlockedByMe.set(blocks.size() > 0); requestBuilder = new QBRequestGetBuilder(); requestBuilder.eq("source_user", qbUser.getId()); requestBuilder.eq("blocked_user", currentQBUser.getId()); blocks = QBCustomObjects.getObjects("BlockList", requestBuilder, new Bundle()); - isBlockedByOther.set(blocks.size() > 0); - - + if (!isOwnProfile()) isBlockedByOther.set(blocks.size() > 0); } catch (QBResponseException e) { e.printStackTrace(); - this.e=e; + this.e = e; } return null; @@ -136,51 +179,60 @@ protected Void doInBackground(Void... params) { @Override protected void onPostExecute(Void aVoid) { isBusy.set(false); - if (e!=null) { + if (e != null) { Util.onError(e, ProfileActivity.this); return; } - if (profile.getAge()>0){ - Calendar calendar= GregorianCalendar.getInstance(); - binding.age.setText(String.format(getString(R.string.age),calendar.get(Calendar.YEAR)-profile.getAge())); + if (profile.getAge() > 0) { + Calendar calendar = GregorianCalendar.getInstance(); + binding.age.setText(String.format(getString(R.string.age), calendar.get(Calendar.YEAR) - profile.getAge())); } - float density=getResources().getDisplayMetrics().density; - if (profile.getGender().equals("M")){ - Drawable drawable= ContextCompat.getDrawable(ProfileActivity.this,R.drawable.male_icon); - drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight()); + float density = getResources().getDisplayMetrics().density; + if (profile.getGender().equals("M")) { + Drawable drawable = ContextCompat.getDrawable(ProfileActivity.this, R.drawable.male_icon); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); binding.age.setCompoundDrawables(drawable - ,null,null,null); - }else if(profile.getGender().equals("F")){ - Drawable drawable= ContextCompat.getDrawable(ProfileActivity.this,R.drawable.female_icon); - drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight()); + , null, null, null); + } else if (profile.getGender().equals("F")) { + Drawable drawable = ContextCompat.getDrawable(ProfileActivity.this, R.drawable.female_icon); + drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); binding.age.setCompoundDrawables(drawable - ,null,null,null); + , null, null, null); } - if (qbUser.getFileId()!=null){ + if (qbUser.getFileId() != null) { AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.userAvatar, - Math.round(density*100), Math.round(density*100)); + Math.round(density * 100), Math.round(density * 100)); + + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.avatarHolder, + Math.round(density * 60), Math.round(density * 60)); } - if (profile.getBackgroundId()>0){ - int height=Math.round(density*147); - int width=getResources().getDisplayMetrics().widthPixels; + if (profile.getBackgroundId() > 0) { + int height = Math.round(density * 147); + int width = getResources().getDisplayMetrics().widthPixels; AvatarLoaderHelper.loadImage(profile.getBackgroundId(), binding.userBackground, - width,height); + width, height); } binding.age.invalidate(); - setBlockedUI(isBlockedByMe.get()); + if (isBlockedByMe.get() && !isOwnProfile()) { + binding.userBlockedHeaderInfo.setVisibility(View.VISIBLE); + binding.userBackground.setImageResource(R.color.blocked_red); + } + + setFriendsUI(); + if (isOwnProfile()) hideFieldsInOwnProfile(); } }.execute(); } - public AdRequest requestNewAd(){ + public AdRequest requestNewAd() { AdRequest adRequest = new AdRequest.Builder() .build(); return adRequest; @@ -197,7 +249,7 @@ public AdRequest requestNewAd(){ // } - public void openChat(){ + public void openChat() { isBusy.set(true); progressMessage.set(getString(R.string.loading)); QBPrivateChatManager chatManager = QBChatService.getInstance().getPrivateChatManager(); @@ -227,7 +279,6 @@ public boolean onOptionsItemSelected(MenuItem item) { } - private void setBlockedUI(boolean isBlocked) { isBlockedByMe.set(isBlocked); @@ -253,7 +304,8 @@ private void saveBlockListToPreferences(QBPrivacyList list) { editor.apply(); } - public void blockUser(){ + + public void blockUser() { isBusy.set(true); progressMessage.set(getString(R.string.blocking_user)); new AsyncTask() { @@ -289,11 +341,11 @@ protected Void doInBackground(Void... params) { QBCustomObjects.createObject(object); QBPrivateChat privatChat = QBChatService.getInstance().getPrivateChatManager().getChat(currentQBUser.getId()); - if (privatChat==null){ - privatChat=QBChatService.getInstance().getPrivateChatManager().createChat(currentQBUser.getId(),null); + if (privatChat == null) { + privatChat = QBChatService.getInstance().getPrivateChatManager().createChat(currentQBUser.getId(), null); } - QBChatMessage message=new QBChatMessage(); - message.setProperty("blocked","1"); + QBChatMessage message = new QBChatMessage(); + message.setProperty("blocked", "1"); privatChat.sendMessage(message); } catch (Exception e) { @@ -306,7 +358,7 @@ protected Void doInBackground(Void... params) { protected void onPostExecute(Void aVoid) { isBusy.set(false); if (error != null) { - new AlertDialog.Builder(ProfileActivity.this,R.style.AppAlertDialogTheme) + new AlertDialog.Builder(ProfileActivity.this, R.style.AppAlertDialogTheme) .setMessage(error) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override @@ -317,12 +369,16 @@ public void onClick(DialogInterface dialog, int which) { }).show(); } else { setBlockedUI(true); + binding.userBackground.setImageResource(R.color.blocked_red); + binding.userStatusInfo.setVisibility(View.GONE); + binding.userBlockedHeaderInfo.setVisibility(View.VISIBLE); Toast.makeText(ProfileActivity.this, R.string.user_added_to_block_list, Toast.LENGTH_LONG).show(); } } }.execute(); } - public void unblockUser(){ + + public void unblockUser() { isBusy.set(true); progressMessage.set(getString(R.string.unblocking_user)); new AsyncTask() { @@ -357,11 +413,11 @@ protected Boolean doInBackground(Void... params) { saveBlockListToPreferences(list); QBPrivateChat privatChat = QBChatService.getInstance().getPrivateChatManager().getChat(currentQBUser.getId()); - if (privatChat==null){ - privatChat=QBChatService.getInstance().getPrivateChatManager().createChat(currentQBUser.getId(),null); + if (privatChat == null) { + privatChat = QBChatService.getInstance().getPrivateChatManager().createChat(currentQBUser.getId(), null); } - QBChatMessage message=new QBChatMessage(); - message.setProperty("blocked","0"); + QBChatMessage message = new QBChatMessage(); + message.setProperty("blocked", "0"); privatChat.sendMessage(message); @@ -378,6 +434,15 @@ protected void onPostExecute(Boolean result) { isBusy.set(false); if (result) { setBlockedUI(false); + binding.userBlockedHeaderInfo.setVisibility(View.GONE); + float density = getResources().getDisplayMetrics().density; + if (profile.getBackgroundId() > 0) { + int height = Math.round(density * 147); + int width = getResources().getDisplayMetrics().widthPixels; + AvatarLoaderHelper.loadImage(profile.getBackgroundId(), binding.userBackground, width, height); + } else { + binding.userBackground.setImageResource(R.drawable.app_bar_bg); + } Toast.makeText(ProfileActivity.this, R.string.user_removed_from_block_list, Toast.LENGTH_LONG).show(); } else { @@ -387,4 +452,174 @@ protected void onPostExecute(Boolean result) { } + + private void initChatRoster() { + if (chatRoster == null) chatRoster = ChatRosterHelper.getChatRoster(); + } + + private void setFriendsUI() { + if (chatRoster == null) return; + if (chatRoster.contains(qbUser.getId())) { + int userId = qbUser.getId(); + if (chatRoster != null && chatRoster.getEntry(userId) != null && + chatRoster.getEntry(userId).getType() == RosterPacket.ItemType.none && + chatRoster.getEntry(userId).getStatus() == RosterPacket.ItemStatus.subscribe) { + binding.addToFriendsButton.setVisibility(View.GONE); + binding.deleteFromFriends.setVisibility(View.GONE); + binding.userStatusInfo.setVisibility(isBlockedByMe.get() ? View.GONE : View.VISIBLE); + } else { + binding.addToFriendsButton.setImageResource(R.drawable.added_to_friend); + binding.deleteFromFriends.setVisibility(View.VISIBLE); + binding.userStatusInfo.setVisibility(View.GONE); + } + } else { + binding.addToFriendsButton.setImageResource(R.drawable.add_to_friend); + binding.deleteFromFriends.setVisibility(View.GONE); + binding.userStatusInfo.setVisibility(View.GONE); + } + // binding.deleteFromFriends.setVisibility(View.VISIBLE); + binding.gridLayout.requestLayout(); + } + + public void addUserToFriends() { + if (qbUser.getId() == null || qbUser.getId() == preferences.getInt(C.QB_USERID, 0)) return; + if (chatRoster.contains(qbUser.getId())) return; + + final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this) + .setCancelable(true); + + View view = LayoutInflater.from(this).inflate(R.layout.dialog_add_to_friends, null); + ImageView dialogAvatar = (ImageView) view.findViewById(R.id.dialog_avatar); + dialogAvatar.setImageDrawable(binding.avatarHolder.getDrawable()); + + TextView messageText = (TextView) view.findViewById(R.id.message_text); + String sourceString = getString(R.string.dialog_add_friend_add) + " " + qbUser.getFullName() + " " + getString(R.string.dialog_add_to_friend); + messageText.setText(Html.fromHtml(sourceString)); + + builder.setView(view); + + final android.app.AlertDialog dialog = builder.create(); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + dialog.show(); + + TextView sendButton = (TextView) view.findViewById(R.id.send_friend_request); + sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + addToFriends(); + dialog.dismiss(); + } + }); + + TextView cancelButton = (TextView) view.findViewById(R.id.cancel_button); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + } + + private void addToFriends() { + + int userId = qbUser.getId(); + if (chatRoster.contains(userId)) { + try { + chatRoster.subscribe(userId); + Util.addFriendOutInviteToList(userId); + binding.addToFriendsButton.setVisibility(View.GONE); + binding.deleteFromFriends.setVisibility(View.GONE); + binding.userStatusInfo.setVisibility(isBlockedByMe.get() ? View.GONE : View.VISIBLE); + } catch (SmackException.NotConnectedException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.reconnect_message)); + } + } else { + try { + chatRoster.createEntry(userId, null); + Util.addFriendOutInviteToList(userId); + binding.addToFriendsButton.setVisibility(View.GONE); + binding.deleteFromFriends.setVisibility(View.GONE); + binding.userStatusInfo.setVisibility(isBlockedByMe.get() ? View.GONE : View.VISIBLE); + } catch (SmackException.NotConnectedException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.reconnect_message)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.you_are_not_logged_in)); + } catch (XMPPException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } catch (SmackException.NoResponseException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } + } + + + } + + public void removeUserFromFriends() { + if (qbUser.getId() == null || qbUser.getId() == preferences.getInt(C.QB_USERID, 0)) return; + if (!chatRoster.contains(qbUser.getId())) return; + + final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this) + .setCancelable(true); + + View view = LayoutInflater.from(this).inflate(R.layout.dialog_add_to_friends, null); + ImageView dialogAvatar = (ImageView) view.findViewById(R.id.dialog_avatar); + dialogAvatar.setImageDrawable(binding.avatarHolder.getDrawable()); + + TextView messageText = (TextView) view.findViewById(R.id.message_text); + String sourceString = getString(R.string.dialog_remove_friend) + " " + qbUser.getFullName() + " " + getString(R.string.dialog_remove_from_friend); + messageText.setText(Html.fromHtml(sourceString)); + + builder.setView(view); + + final android.app.AlertDialog dialog = builder.create(); + dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); + dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + dialog.show(); + + TextView sendButton = (TextView) view.findViewById(R.id.send_friend_request); + sendButton.setText(getString(R.string.remove)); + sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + removeFromFriends(); + } + }); + + TextView cancelButton = (TextView) view.findViewById(R.id.cancel_button); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + } + + private void removeFromFriends() { + int userId = qbUser.getId(); + try { + chatRoster.unsubscribe(userId); + if (chatRoster.getEntry(userId) != null && chatRoster.contains(userId)) { + chatRoster.removeEntry(chatRoster.getEntry(userId)); + Util.removeFriendOutInviteFromList(userId); + } + setFriendsUI(); + EventBus.getDefault().post(new FriendRemovedEvent(qbUser)); + } catch (SmackException.NotConnectedException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.reconnect_message)); + } catch (SmackException.NotLoggedInException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.you_are_not_logged_in)); + } catch (XMPPException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } catch (SmackException.NoResponseException e) { + handleOnError(ProfileActivity.this, e, getString(R.string.something_wrong_try_again_later)); + } + } + + public static void handleOnError(Context context, Exception e, String message) { + e.printStackTrace(); + Crashlytics.logException(e); + Util.showAlert(context, message); + } } diff --git a/app/src/main/java/saberapplications/pawpads/ui/search/SearchActivity.java b/app/src/main/java/saberapplications/pawpads/ui/search/SearchActivity.java new file mode 100644 index 0000000..b6025ec --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/search/SearchActivity.java @@ -0,0 +1,203 @@ +package saberapplications.pawpads.ui.search; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.databinding.DataBindingUtil; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.core.request.QBPagedRequestBuilder; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import saberapplications.pawpads.C; +import saberapplications.pawpads.R; +import saberapplications.pawpads.databinding.ActivitySearchBinding; +import saberapplications.pawpads.ui.BaseActivity; +import saberapplications.pawpads.ui.profile.ProfileActivity; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 05.06.17. + */ + +public class SearchActivity extends BaseActivity implements BaseListAdapter.Callback { + ActivitySearchBinding binding; + SearchAdapter adapter; + private int currentUserId; + private Set filteredUsers; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_search); + binding = DataBindingUtil.setContentView(this, R.layout.activity_search); + binding.setActivity(this); + adapter = new SearchAdapter(); + setSupportActionBar(binding.toolbar); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + binding.toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + } + }); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + currentUserId = prefs.getInt(C.QB_USERID, 0); + adapter.setCurrentUserId(currentUserId); + binding.searchListView.setAdapter(adapter); + adapter.setCallback(this); + adapter.setShowInitialLoad(false); + adapter.disableLoadMore(); + initSearchPanel(); + } + + private void initSearchPanel() { + binding.toolbarSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + String query = v.getText().toString(); + if(query.length() > 0) { + hideSoftKeyboard(); + loadDataBySearchQuery(query); + } + return true; + } + return false; + } + }); + + binding.toolbarSearchText.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) {} + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if(s.length() == 0) { + binding.clearSearchText.setVisibility(View.INVISIBLE); + adapter.clear(); + adapter.disableLoadMore(); + binding.emptySearchStateLayout.setVisibility(View.VISIBLE); + } else { + if(binding.clearSearchText.getVisibility() == View.INVISIBLE) + binding.clearSearchText.setVisibility(View.VISIBLE); + } + } + }); + } + + private void loadDataBySearchQuery(final String searchQuery) { + binding.emptySearchStateLayout.setVisibility(View.GONE); + adapter.clear(); + adapter.setShowInitialLoad(true); + filteredUsers = new HashSet<>(); + + new AsyncTask() { + @Override + protected Boolean doInBackground(Void... params) { + + QBPagedRequestBuilder pagedRequestBuilder = new QBPagedRequestBuilder(); + Bundle bundle = new Bundle(); + try { + ArrayList resultByFullNameUsers = QBUsers.getUsersByFullName(searchQuery, pagedRequestBuilder, bundle); + if (resultByFullNameUsers.size() > 0) { + for (QBUser user : resultByFullNameUsers) { + if (user.getFullName() != null && user.getFullName().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + + ArrayList usersLogins = new ArrayList<>(); + usersLogins.add(searchQuery); + try { + ArrayList resultByLoginUsers = QBUsers.getUsersByLogins(usersLogins, pagedRequestBuilder, bundle); + if (resultByLoginUsers.size() > 0) { + for (QBUser user : resultByLoginUsers) { + if (user.getLogin() != null && user.getLogin().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + + ArrayList usersEmails = new ArrayList<>(); + usersEmails.add(searchQuery); + try { + ArrayList resultByEmailUsers = QBUsers.getUsersByEmails(usersEmails, pagedRequestBuilder, bundle); + if (resultByEmailUsers.size() > 0) { + for (QBUser user : resultByEmailUsers) { + if (user.getEmail() != null && user.getEmail().contains(searchQuery)) + filteredUsers.add(user); + } + } + } catch (QBResponseException e) { + e.printStackTrace(); + } + return true; + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + super.onPostExecute(aBoolean); + processSearchComplete(filteredUsers); + } + }.execute(); + } + + private void processSearchComplete(Set users) { + if (users.size() > 0) { + adapter.addItems(new ArrayList<>(users)); + } + + if (users.size() == 0 || users.size() < 10) { + adapter.disableLoadMore(); + } + } + + public void clearSearchQuery() { + binding.toolbarSearchText.setText(""); + } + + @Override + public void onLoadMore() { + //nothing to do + } + + @Override + public void onItemClick(final QBUser user) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + if (user != null) { + Intent intent = new Intent(SearchActivity.this, ProfileActivity.class); + intent.putExtra(C.QB_USERID, user.getId()); + intent.putExtra(C.QB_USER, user); + startActivity(intent); + } + } + }, 50); + } +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/ui/search/SearchAdapter.java b/app/src/main/java/saberapplications/pawpads/ui/search/SearchAdapter.java new file mode 100644 index 0000000..687bfa4 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/ui/search/SearchAdapter.java @@ -0,0 +1,102 @@ +package saberapplications.pawpads.ui.search; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v4.util.ArrayMap; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.users.QBUsers; +import com.quickblox.users.model.QBUser; + +import saberapplications.pawpads.R; +import saberapplications.pawpads.UserStatusHelper; +import saberapplications.pawpads.databinding.RowSearchUserItemBinding; +import saberapplications.pawpads.util.AvatarLoaderHelper; +import saberapplications.pawpads.views.BaseListAdapter; + +/** + * Created by developer on 05.06.17. + */ + +public class SearchAdapter extends BaseListAdapter { + + private int currentUserId; + private ArrayMap userCache = new ArrayMap<>(); + + public static class SearchAdapterHolder extends DataHolder{ + + private final int size; + RowSearchUserItemBinding binding; + SearchAdapter adapter; + + public SearchAdapterHolder(View v, BaseListAdapter adapter) { + super(v, adapter); + binding= DataBindingUtil.bind(v); + this.adapter= (SearchAdapter) adapter; + float d= view.getResources().getDisplayMetrics().density; + size=Math.round(60 * d); + } + + @Override + public void showData(final DataItem data, int position) { + final QBUser user = data.model.get(); + String userName = data.model.get().getFullName() == null ? data.model.get().getLogin() : data.model.get().getFullName(); + binding.setUsername(userName); + int userId=user.getId(); + + binding.avatar.setImageResource(R.drawable.user_placeholder); + if(!adapter.userCache.containsKey(userId)) { + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser.getFileId() != null) { + AvatarLoaderHelper.loadImage(qbUser.getFileId(), binding.avatar, size, size); + adapter.userCache.put(qbUser.getId(), qbUser); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + }else { + AvatarLoaderHelper.loadImage(adapter.userCache.get(userId).getFileId(), binding.avatar, size, size); + } + + QBUsers.getUser(userId, new QBEntityCallback() { + @Override + public void onSuccess(QBUser qbUser, Bundle bundle) { + if (qbUser != null) { + binding.setBindStatusVisibility(true); + binding.setOnlineStatus(UserStatusHelper.getUserStatus(qbUser)); + } + } + + @Override + public void onError(QBResponseException e) { + + } + }); + } + } + + @Override + public DataHolder getItemHolder(ViewGroup parent) { + View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_search_user_item,parent,false); + return new SearchAdapter.SearchAdapterHolder(v,this); + } + + public void setCurrentUserId(int currentUserId) { + this.currentUserId = currentUserId; + } + + @Override + protected int getEmptyStateResId() { + return R.layout.empty_state_create_chat; + } +} \ No newline at end of file diff --git a/app/src/main/java/saberapplications/pawpads/util/AvatarLoaderHelper.java b/app/src/main/java/saberapplications/pawpads/util/AvatarLoaderHelper.java index 13bee2d..a390321 100644 --- a/app/src/main/java/saberapplications/pawpads/util/AvatarLoaderHelper.java +++ b/app/src/main/java/saberapplications/pawpads/util/AvatarLoaderHelper.java @@ -1,15 +1,19 @@ package saberapplications.pawpads.util; +import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ThumbnailUtils; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; import com.bumptech.glide.Glide; import com.quickblox.content.QBContent; import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.QBProgressCallback; import com.quickblox.core.exception.QBResponseException; import java.io.File; @@ -25,13 +29,16 @@ * Created by Stanislav Volnyansky on 10.03.16. */ public class AvatarLoaderHelper { + public static void loadImage(int fileId, final ImageView imageView, final int width, final int height) { loadImage(fileId, imageView, width, height, null); } public static void loadImageSync(int fileId, final ImageView imageView, final int width, final int height) { try { - if (fileId == 0) return; + if (fileId == 0) { + return; + } File CacheDir = PawPadsApplication.getInstance().getCacheDir(); final File file = new File(CacheDir.getAbsolutePath() + "/" + fileId + ".jpg"); Bitmap image=null; @@ -62,55 +69,79 @@ public void run() { } } - public static void loadImage(int fileId, final ImageView imageView, final int width, final int height, final Callback callback) { + public static void loadImage(final int fileId, final ImageView imageView, final int width, final int height, final Callback callback) { if (fileId == 0) return; File CacheDir = PawPadsApplication.getInstance().getCacheDir(); final File file = new File(CacheDir.getAbsolutePath() + "/" + fileId + ".jpg"); // Trying get image from cache if (file.exists()) { - Glide.with(imageView.getContext()).load(file).centerCrop().override(width, height).into(imageView); + try { + Glide.with(imageView.getContext()).load(file).centerCrop().override(width, height).into(imageView); + } catch (Exception e) { + e.printStackTrace(); + } if (callback != null) callback.imageLoaded(); } else { - - QBContent.downloadFileTask(fileId, new QBEntityCallback() { - @Override - public void onSuccess(InputStream inputStream, Bundle params) { - new AsyncTask() { - + QBContent.downloadFileById(fileId, new QBEntityCallback() { @Override - protected Bitmap doInBackground(InputStream... params) { - return BitmapFactory.decodeStream(params[0]); + public void onSuccess(InputStream inputStream, Bundle bundle) { + new AsyncTask() { + + @Override + protected Boolean doInBackground(InputStream... params) { + Bitmap bitmap= BitmapFactory.decodeStream(params[0]); + try { + FileOutputStream stream = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); + stream.close(); + bitmap.recycle(); + bitmap = null; + return true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + @Override + protected void onPostExecute(Boolean res) { + if (!res) return; + try { + if (imageView.getContext() instanceof AppCompatActivity){ + Activity activity=(AppCompatActivity)imageView.getContext(); + if (activity.isFinishing() ) return; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + if ( activity.isDestroyed()){ + return; + } + } + } + Glide.with(imageView.getContext()).load(file).centerCrop().override(width, height).into(imageView); + } + catch(Exception ex){ + + } finally { + + } + if (callback != null) callback.imageLoaded(); + + } + }.execute(inputStream); } @Override - protected void onPostExecute(Bitmap bitmap) { - super.onPostExecute(bitmap); - - try { - FileOutputStream stream = new FileOutputStream(file); - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); - stream.close(); - bitmap.recycle(); - bitmap = null; - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - Glide.with(imageView.getContext()).load(file).centerCrop().override(width, height).into(imageView); - if (callback != null) callback.imageLoaded(); - + public void onError(QBResponseException e) { + Util.onError(e, PawPadsApplication.getInstance().getApplicationContext()); } - }.execute(inputStream); - } - - @Override - public void onError(QBResponseException e) { - Util.onError(e, PawPadsApplication.getInstance().getApplicationContext()); - } - + }, new QBProgressCallback() { + @Override + public void onProgressUpdate(int i) { - }); + } + } + ); } diff --git a/app/src/main/java/saberapplications/pawpads/util/ChatRosterHelper.java b/app/src/main/java/saberapplications/pawpads/util/ChatRosterHelper.java new file mode 100644 index 0000000..c7395f8 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/util/ChatRosterHelper.java @@ -0,0 +1,56 @@ +package saberapplications.pawpads.util; + +import android.util.Log; + +import com.quickblox.chat.QBChatService; +import com.quickblox.chat.QBRoster; +import com.quickblox.chat.listeners.QBRosterListener; +import com.quickblox.chat.listeners.QBSubscriptionListener; +import com.quickblox.chat.model.QBPresence; + +import java.util.Collection; + +/** + * Created by developer on 22.05.17. + */ + +public class ChatRosterHelper { + public static final String TAG = ChatRosterHelper.class.getSimpleName(); + + public static QBRoster getChatRoster() { + QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() { + @Override + public void subscriptionRequested(int userId) { + Log.d(TAG, "subscriptionRequested " + userId); + } + }; + + QBRosterListener rosterListener = new QBRosterListener() { + @Override + public void entriesDeleted(Collection userIds) { + Log.d(TAG, "entriesDeleted " + userIds.toString()); + } + + @Override + public void entriesAdded(Collection userIds) { + Log.d(TAG, "entriesAdded " + userIds.toString()); + } + + @Override + public void entriesUpdated(Collection userIds) { + Log.d(TAG, "entriesUpdated " + userIds.toString()); + } + + @Override + public void presenceChanged(QBPresence presence) { + Log.d(TAG, "presenceChanged " + presence.toString()); + } + }; + + // Do this after success Chat login + QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener); + if(chatRoster == null) return null; + chatRoster.addRosterListener(rosterListener); + return chatRoster; + } +} diff --git a/app/src/main/java/saberapplications/pawpads/util/OtherUsersLocationsCache.java b/app/src/main/java/saberapplications/pawpads/util/OtherUsersLocationsCache.java new file mode 100644 index 0000000..e118415 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/util/OtherUsersLocationsCache.java @@ -0,0 +1,82 @@ +package saberapplications.pawpads.util; + +import android.location.Location; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.util.SparseArrayCompat; + +import com.quickblox.core.QBEntityCallback; +import com.quickblox.core.exception.QBResponseException; +import com.quickblox.location.QBLocations; +import com.quickblox.location.model.QBLocation; +import com.quickblox.location.request.QBLocationRequestBuilder; + +import java.util.ArrayList; + +/** + * Created by Stanislav Volnjanskij on 7/21/17. + */ + +public class OtherUsersLocationsCache { + private static class CacheEntry{ + public Location location; + public long time; + + public CacheEntry(Location location) { + this.location = location; + time=System.currentTimeMillis(); + } + } + private static SparseArrayCompat cache=new SparseArrayCompat<>(); + public static void put(Integer id,Location location){ + cache.put(id,new CacheEntry(location)); + } + public static Adapter get(final Integer id){ + final Adapter adapter=new Adapter(); + long now=System.currentTimeMillis(); + if (cache.indexOfKey(id)>0 && (now-cache.get(id).time)<600000 ){ + new Handler().postDelayed( + new Runnable() { + @Override + public void run() { + adapter.setLocation(cache.get(id).location); + } + },50 + ); + + return adapter; + } + + QBLocationRequestBuilder getLocationsBuilder = new QBLocationRequestBuilder(); + getLocationsBuilder.setLastOnly(); + // radius in kilometers + getLocationsBuilder.setUserId(id); + QBLocations.getLocations(getLocationsBuilder, new QBEntityCallback>() { + @Override + public void onSuccess(ArrayList qbLocations, Bundle bundle) { + Location location=new Location(""); + location.setLongitude(qbLocations.get(0).getLongitude()); + location.setLatitude(qbLocations.get(0).getLatitude()); + cache.put(id,new CacheEntry(location)); + adapter.setLocation(location); + } + @Override + public void onError(QBResponseException e) {} + }); + return adapter; + } + + public static class Adapter{ + Callback callback; + public void callback(Callback c){ + this.callback=c; + } + public void setLocation(Location location){ + callback.location(location); + } + } + + public interface Callback{ + public void location(Location location); + } +} diff --git a/app/src/main/java/saberapplications/pawpads/views/BaseListAdapter.java b/app/src/main/java/saberapplications/pawpads/views/BaseListAdapter.java index e97e269..6015661 100644 --- a/app/src/main/java/saberapplications/pawpads/views/BaseListAdapter.java +++ b/app/src/main/java/saberapplications/pawpads/views/BaseListAdapter.java @@ -188,9 +188,6 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { @Override public int getItemCount() { if(items.size()==0) return 1; - if (isBusy && !showInitialLoad){ - return 0; - } if (loadMoreEnabled) { return items.size() + 1; }else{ @@ -207,13 +204,15 @@ public void setBusy(boolean busy) { } public void addItems(List items) { + for (T item : items) { DataItem dataItem = new DataItem<>(); dataItem.model.set(item); this.items.add(dataItem); } isBusy = false; - notifyDataSetChanged(); + showInitialLoad=false; + notifyItemRangeInserted(this.items.size(),items.size()); } public void addItem(T data) { @@ -222,7 +221,7 @@ public void addItem(T data) { this.items.add(item); isBusy = false; //Collections.sort(items, Collections.reverseOrder()); - notifyDataSetChanged(); + notifyItemChanged(this.items.size()-1); } @@ -271,7 +270,10 @@ public boolean isShowInitialLoad() { public void setShowInitialLoad(boolean showInitialLoad) { this.showInitialLoad = showInitialLoad; } - public List getItems(){ + public ArrayList> getItems(){ + return items; + } + public List getDataItems(){ ArrayList out=new ArrayList<>(); for (DataItem item:items ){ diff --git a/app/src/main/java/saberapplications/pawpads/views/NetworkStateChangedHelper.java b/app/src/main/java/saberapplications/pawpads/views/NetworkStateChangedHelper.java new file mode 100644 index 0000000..328ab63 --- /dev/null +++ b/app/src/main/java/saberapplications/pawpads/views/NetworkStateChangedHelper.java @@ -0,0 +1,68 @@ +package saberapplications.pawpads.views; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; + +import saberapplications.pawpads.R; + +/** + * Created by Stanislav Volnjanskij on 7/10/17. + */ + +public class NetworkStateChangedHelper { + AppCompatActivity activity; + private static boolean dialogIsShown=false; + private AlertDialog dialog; + + public NetworkStateChangedHelper(AppCompatActivity activity) { + this.activity = activity; + } + + BroadcastReceiver networkStateChanged=new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + checkNeworkConnection(); + } + }; + + public void register(){ + activity.registerReceiver(networkStateChanged,new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + } + public void unRegister(){ + activity.unregisterReceiver(networkStateChanged); + if (dialogIsShown) dialogIsShown=false; + } + public boolean isConnected(){ + ConnectivityManager cm = + (ConnectivityManager)activity.getSystemService(Context.CONNECTIVITY_SERVICE); + + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + boolean isConnected = activeNetwork!=null && activeNetwork.isConnectedOrConnecting(); + return isConnected; + } + public synchronized void checkNeworkConnection(){ + if (!isConnected() && !dialogIsShown){ + dialogIsShown=true; + dialog = new AlertDialog.Builder(activity) + .setMessage(R.string.interner_not_connecteed) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + activity.finish(); + } + }) + .show(); + + }else if(!isConnected() && dialogIsShown && dialog==null){ + activity.finish(); + } + } + +} diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..facfb01 --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..89f9d53 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/add_participant.png b/app/src/main/res/drawable-hdpi/add_participant.png new file mode 100644 index 0000000..af2f0d0 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_participant.png differ diff --git a/app/src/main/res/drawable-hdpi/add_to_friend.png b/app/src/main/res/drawable-hdpi/add_to_friend.png new file mode 100644 index 0000000..2be04df Binary files /dev/null and b/app/src/main/res/drawable-hdpi/add_to_friend.png differ diff --git a/app/src/main/res/drawable-hdpi/added_to_friend.png b/app/src/main/res/drawable-hdpi/added_to_friend.png new file mode 100644 index 0000000..f2d767e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/added_to_friend.png differ diff --git a/app/src/main/res/drawable-hdpi/block_small.png b/app/src/main/res/drawable-hdpi/block_small.png new file mode 100644 index 0000000..159a99f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/block_small.png differ diff --git a/app/src/main/res/drawable-hdpi/chat_button_new.png b/app/src/main/res/drawable-hdpi/chat_button_new.png new file mode 100644 index 0000000..50ae3ef Binary files /dev/null and b/app/src/main/res/drawable-hdpi/chat_button_new.png differ diff --git a/app/src/main/res/drawable-hdpi/edit_white.png b/app/src/main/res/drawable-hdpi/edit_white.png new file mode 100644 index 0000000..0eb9233 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/edit_white.png differ diff --git a/app/src/main/res/drawable-hdpi/lock.png b/app/src/main/res/drawable-hdpi/lock.png new file mode 100644 index 0000000..25c29a1 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/lock.png differ diff --git a/app/src/main/res/drawable-hdpi/lock_grey.png b/app/src/main/res/drawable-hdpi/lock_grey.png new file mode 100644 index 0000000..e667d5d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/lock_grey.png differ diff --git a/app/src/main/res/drawable-hdpi/mic_grey.png b/app/src/main/res/drawable-hdpi/mic_grey.png new file mode 100644 index 0000000..564a48d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/mic_grey.png differ diff --git a/app/src/main/res/drawable-hdpi/search_grey.png b/app/src/main/res/drawable-hdpi/search_grey.png new file mode 100644 index 0000000..809710f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/search_grey.png differ diff --git a/app/src/main/res/drawable-hdpi/search_white.png b/app/src/main/res/drawable-hdpi/search_white.png new file mode 100644 index 0000000..e273885 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/search_white.png differ diff --git a/app/src/main/res/drawable-hdpi/x_white.png b/app/src/main/res/drawable-hdpi/x_white.png new file mode 100644 index 0000000..5addcdf Binary files /dev/null and b/app/src/main/res/drawable-hdpi/x_white.png differ diff --git a/app/src/main/res/drawable-mdpi/add_participant.png b/app/src/main/res/drawable-mdpi/add_participant.png new file mode 100644 index 0000000..db6f123 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_participant.png differ diff --git a/app/src/main/res/drawable-mdpi/add_to_friend.png b/app/src/main/res/drawable-mdpi/add_to_friend.png new file mode 100644 index 0000000..87985af Binary files /dev/null and b/app/src/main/res/drawable-mdpi/add_to_friend.png differ diff --git a/app/src/main/res/drawable-mdpi/added_to_friend.png b/app/src/main/res/drawable-mdpi/added_to_friend.png new file mode 100644 index 0000000..0d4253f Binary files /dev/null and b/app/src/main/res/drawable-mdpi/added_to_friend.png differ diff --git a/app/src/main/res/drawable-mdpi/block_small.png b/app/src/main/res/drawable-mdpi/block_small.png new file mode 100644 index 0000000..81da9c2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/block_small.png differ diff --git a/app/src/main/res/drawable-mdpi/chat_button_new.png b/app/src/main/res/drawable-mdpi/chat_button_new.png new file mode 100644 index 0000000..1c138a4 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/chat_button_new.png differ diff --git a/app/src/main/res/drawable-mdpi/edit_white.png b/app/src/main/res/drawable-mdpi/edit_white.png new file mode 100644 index 0000000..194cd40 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/edit_white.png differ diff --git a/app/src/main/res/drawable-mdpi/lock.png b/app/src/main/res/drawable-mdpi/lock.png new file mode 100644 index 0000000..9f62b27 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/lock.png differ diff --git a/app/src/main/res/drawable-mdpi/lock_grey.png b/app/src/main/res/drawable-mdpi/lock_grey.png new file mode 100644 index 0000000..6f7b0b5 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/lock_grey.png differ diff --git a/app/src/main/res/drawable-mdpi/mic_grey.png b/app/src/main/res/drawable-mdpi/mic_grey.png new file mode 100644 index 0000000..2e564d9 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/mic_grey.png differ diff --git a/app/src/main/res/drawable-mdpi/search_grey.png b/app/src/main/res/drawable-mdpi/search_grey.png new file mode 100644 index 0000000..80728c6 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/search_grey.png differ diff --git a/app/src/main/res/drawable-mdpi/search_white.png b/app/src/main/res/drawable-mdpi/search_white.png new file mode 100644 index 0000000..3c55e49 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/search_white.png differ diff --git a/app/src/main/res/drawable-mdpi/x_white.png b/app/src/main/res/drawable-mdpi/x_white.png new file mode 100644 index 0000000..1f6f729 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/x_white.png differ diff --git a/app/src/main/res/drawable-v21/add_to_friend_btn_bg.xml b/app/src/main/res/drawable-v21/add_to_friend_btn_bg.xml new file mode 100644 index 0000000..a258116 --- /dev/null +++ b/app/src/main/res/drawable-v21/add_to_friend_btn_bg.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xhdpi/add_participant.png b/app/src/main/res/drawable-xhdpi/add_participant.png new file mode 100644 index 0000000..b09f18f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_participant.png differ diff --git a/app/src/main/res/drawable-xhdpi/add_to_friend.png b/app/src/main/res/drawable-xhdpi/add_to_friend.png new file mode 100644 index 0000000..8d9f794 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/add_to_friend.png differ diff --git a/app/src/main/res/drawable-xhdpi/added_to_friend.png b/app/src/main/res/drawable-xhdpi/added_to_friend.png new file mode 100644 index 0000000..d5f7d48 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/added_to_friend.png differ diff --git a/app/src/main/res/drawable-xhdpi/block_small.png b/app/src/main/res/drawable-xhdpi/block_small.png new file mode 100644 index 0000000..8d54516 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/block_small.png differ diff --git a/app/src/main/res/drawable-xhdpi/chat_button_new.png b/app/src/main/res/drawable-xhdpi/chat_button_new.png new file mode 100644 index 0000000..c489579 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/chat_button_new.png differ diff --git a/app/src/main/res/drawable-xhdpi/edit_white.png b/app/src/main/res/drawable-xhdpi/edit_white.png new file mode 100644 index 0000000..b476224 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/edit_white.png differ diff --git a/app/src/main/res/drawable-xhdpi/friends.png b/app/src/main/res/drawable-xhdpi/friends.png new file mode 100755 index 0000000..4fa3914 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/friends.png differ diff --git a/app/src/main/res/drawable-xhdpi/lock.png b/app/src/main/res/drawable-xhdpi/lock.png new file mode 100644 index 0000000..d069a32 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/lock.png differ diff --git a/app/src/main/res/drawable-xhdpi/lock_grey.png b/app/src/main/res/drawable-xhdpi/lock_grey.png new file mode 100644 index 0000000..59d7a44 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/lock_grey.png differ diff --git a/app/src/main/res/drawable-xhdpi/mic_grey.png b/app/src/main/res/drawable-xhdpi/mic_grey.png new file mode 100644 index 0000000..56211bf Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/mic_grey.png differ diff --git a/app/src/main/res/drawable-xhdpi/search_grey.png b/app/src/main/res/drawable-xhdpi/search_grey.png new file mode 100644 index 0000000..0a6729c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/search_grey.png differ diff --git a/app/src/main/res/drawable-xhdpi/search_white.png b/app/src/main/res/drawable-xhdpi/search_white.png new file mode 100644 index 0000000..460bce0 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/search_white.png differ diff --git a/app/src/main/res/drawable-xhdpi/x_white.png b/app/src/main/res/drawable-xhdpi/x_white.png new file mode 100644 index 0000000..468cc11 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/x_white.png differ diff --git a/app/src/main/res/drawable-xxhdpi/add_participant.png b/app/src/main/res/drawable-xxhdpi/add_participant.png new file mode 100644 index 0000000..716cc65 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_participant.png differ diff --git a/app/src/main/res/drawable-xxhdpi/add_to_friend.png b/app/src/main/res/drawable-xxhdpi/add_to_friend.png new file mode 100644 index 0000000..a62a741 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/add_to_friend.png differ diff --git a/app/src/main/res/drawable-xxhdpi/added_to_friend.png b/app/src/main/res/drawable-xxhdpi/added_to_friend.png new file mode 100644 index 0000000..e746bd6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/added_to_friend.png differ diff --git a/app/src/main/res/drawable-xxhdpi/block_small.png b/app/src/main/res/drawable-xxhdpi/block_small.png new file mode 100644 index 0000000..4db58ef Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/block_small.png differ diff --git a/app/src/main/res/drawable-xxhdpi/chat_button_new.png b/app/src/main/res/drawable-xxhdpi/chat_button_new.png new file mode 100644 index 0000000..11be33b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/chat_button_new.png differ diff --git a/app/src/main/res/drawable-xxhdpi/edit_white.png b/app/src/main/res/drawable-xxhdpi/edit_white.png new file mode 100644 index 0000000..fcb4413 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/edit_white.png differ diff --git a/app/src/main/res/drawable-xxhdpi/friends.png b/app/src/main/res/drawable-xxhdpi/friends.png new file mode 100755 index 0000000..f52051e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/friends.png differ diff --git a/app/src/main/res/drawable-xxhdpi/lock.png b/app/src/main/res/drawable-xxhdpi/lock.png new file mode 100644 index 0000000..d3d6e78 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/lock.png differ diff --git a/app/src/main/res/drawable-xxhdpi/lock_grey.png b/app/src/main/res/drawable-xxhdpi/lock_grey.png new file mode 100644 index 0000000..2a3caaf Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/lock_grey.png differ diff --git a/app/src/main/res/drawable-xxhdpi/message_left_last.9.png b/app/src/main/res/drawable-xxhdpi/message_left_last.9.png index 48be035..458cb87 100644 Binary files a/app/src/main/res/drawable-xxhdpi/message_left_last.9.png and b/app/src/main/res/drawable-xxhdpi/message_left_last.9.png differ diff --git a/app/src/main/res/drawable-xxhdpi/mic_grey.png b/app/src/main/res/drawable-xxhdpi/mic_grey.png new file mode 100644 index 0000000..9d0c444 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/mic_grey.png differ diff --git a/app/src/main/res/drawable-xxhdpi/search_grey.png b/app/src/main/res/drawable-xxhdpi/search_grey.png new file mode 100644 index 0000000..dbd60bf Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/search_grey.png differ diff --git a/app/src/main/res/drawable-xxhdpi/search_white.png b/app/src/main/res/drawable-xxhdpi/search_white.png new file mode 100644 index 0000000..ff50428 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/search_white.png differ diff --git a/app/src/main/res/drawable-xxhdpi/x_white.png b/app/src/main/res/drawable-xxhdpi/x_white.png new file mode 100644 index 0000000..f4b1ee1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/x_white.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/add_participant.png b/app/src/main/res/drawable-xxxhdpi/add_participant.png new file mode 100644 index 0000000..e9dc79e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_participant.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/add_to_friend.png b/app/src/main/res/drawable-xxxhdpi/add_to_friend.png new file mode 100644 index 0000000..5e4695d Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/add_to_friend.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/added_to_friend.png b/app/src/main/res/drawable-xxxhdpi/added_to_friend.png new file mode 100644 index 0000000..78f9fc6 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/added_to_friend.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/block_small.png b/app/src/main/res/drawable-xxxhdpi/block_small.png new file mode 100644 index 0000000..957bdab Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/block_small.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/chat_button_new.png b/app/src/main/res/drawable-xxxhdpi/chat_button_new.png new file mode 100644 index 0000000..d9953c7 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/chat_button_new.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/edit_white.png b/app/src/main/res/drawable-xxxhdpi/edit_white.png new file mode 100644 index 0000000..a56182f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/edit_white.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/friends.png b/app/src/main/res/drawable-xxxhdpi/friends.png new file mode 100755 index 0000000..5c9fadd Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/friends.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/lock.png b/app/src/main/res/drawable-xxxhdpi/lock.png new file mode 100644 index 0000000..a848bff Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/lock.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/lock_grey.png b/app/src/main/res/drawable-xxxhdpi/lock_grey.png new file mode 100644 index 0000000..45af391 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/lock_grey.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/mic_grey.png b/app/src/main/res/drawable-xxxhdpi/mic_grey.png new file mode 100644 index 0000000..4a26a8f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/mic_grey.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/search_grey.png b/app/src/main/res/drawable-xxxhdpi/search_grey.png new file mode 100644 index 0000000..4a2ff53 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/search_grey.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/search_white.png b/app/src/main/res/drawable-xxxhdpi/search_white.png new file mode 100644 index 0000000..7230144 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/search_white.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/x_white.png b/app/src/main/res/drawable-xxxhdpi/x_white.png new file mode 100644 index 0000000..a3d1265 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/x_white.png differ diff --git a/app/src/main/res/drawable/add_to_friend_btn_bg.xml b/app/src/main/res/drawable/add_to_friend_btn_bg.xml new file mode 100644 index 0000000..b3ef8bc --- /dev/null +++ b/app/src/main/res/drawable/add_to_friend_btn_bg.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/edittext_cursor.xml b/app/src/main/res/drawable/edittext_cursor.xml new file mode 100644 index 0000000..5e8e9fe --- /dev/null +++ b/app/src/main/res/drawable/edittext_cursor.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/red_circle.xml b/app/src/main/res/drawable/red_circle.xml new file mode 100644 index 0000000..3c6da80 --- /dev/null +++ b/app/src/main/res/drawable/red_circle.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_checkbox.xml b/app/src/main/res/drawable/rounded_checkbox.xml new file mode 100644 index 0000000..6c49be6 --- /dev/null +++ b/app/src/main/res/drawable/rounded_checkbox.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_checkbox_bg.xml b/app/src/main/res/drawable/rounded_checkbox_bg.xml new file mode 100644 index 0000000..40e7af8 --- /dev/null +++ b/app/src/main/res/drawable/rounded_checkbox_bg.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml index 4302c9d..a100841 100755 --- a/app/src/main/res/layout/activity_chat.xml +++ b/app/src/main/res/layout/activity_chat.xml @@ -64,6 +64,7 @@ android:layout_alignParentRight="true" android:layout_marginRight="16dp" android:scaleType="centerCrop" + android:visibility="invisible" android:src="@drawable/user_placeholder" android:onClick="@{() -> activity.openProfile() }" app:riv_oval="true" /> diff --git a/app/src/main/res/layout/activity_chat_group.xml b/app/src/main/res/layout/activity_chat_group.xml new file mode 100644 index 0000000..e8e91ae --- /dev/null +++ b/app/src/main/res/layout/activity_chat_group.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_create_chat.xml b/app/src/main/res/layout/activity_create_chat.xml new file mode 100644 index 0000000..b60f801 --- /dev/null +++ b/app/src/main/res/layout/activity_create_chat.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit_group.xml b/app/src/main/res/layout/activity_edit_group.xml new file mode 100644 index 0000000..66f22a9 --- /dev/null +++ b/app/src/main/res/layout/activity_edit_group.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_friends.xml b/app/src/main/res/layout/activity_friends.xml new file mode 100644 index 0000000..4aa0313 --- /dev/null +++ b/app/src/main/res/layout/activity_friends.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 66db980..3e17fe3 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -61,6 +61,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:hint="@string/login" + android:inputType="text" android:enabled="@{!activity.isBusy}" /> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 089b982..d769526 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -47,15 +47,36 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + + + + + + + @@ -99,6 +120,12 @@ android:padding="0dp" android:clickable="true"> + + + /> + + + - + diff --git a/app/src/main/res/layout/activity_profilepage.xml b/app/src/main/res/layout/activity_profilepage.xml index 0e2492c..8041357 100644 --- a/app/src/main/res/layout/activity_profilepage.xml +++ b/app/src/main/res/layout/activity_profilepage.xml @@ -48,6 +48,11 @@ android:text="@{profile.hobby,default=UI_UX_DESIGNER}" android:textColor="@color/primary" android:textSize="20sp" + android:layout_marginLeft="15dp" + android:layout_marginStart="15dp" + android:layout_marginEnd="15dp" + android:layout_marginRight="15dp" + android:gravity="center_horizontal" app:layout_gravity="center_horizontal" app:typefaceAsset="Proxima_Nova_Regular.otf" /> @@ -65,6 +70,7 @@ app:typefaceAsset="Proxima_Nova_Regular.otf" /> + + + + + + @@ -165,11 +226,36 @@ app:columnCount="3" app:orientation="horizontal" > - + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/chat_group_message_left.xml b/app/src/main/res/layout/chat_group_message_left.xml new file mode 100644 index 0000000..58864af --- /dev/null +++ b/app/src/main/res/layout/chat_group_message_left.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/chat_group_message_right.xml b/app/src/main/res/layout/chat_group_message_right.xml new file mode 100644 index 0000000..430704f --- /dev/null +++ b/app/src/main/res/layout/chat_group_message_right.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_add_to_friends.xml b/app/src/main/res/layout/dialog_add_to_friends.xml new file mode 100644 index 0000000..744ec9d --- /dev/null +++ b/app/src/main/res/layout/dialog_add_to_friends.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_create_group_or_chat.xml b/app/src/main/res/layout/dialog_create_group_or_chat.xml new file mode 100644 index 0000000..2f79662 --- /dev/null +++ b/app/src/main/res/layout/dialog_create_group_or_chat.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/empty_state_create_chat.xml b/app/src/main/res/layout/empty_state_create_chat.xml new file mode 100644 index 0000000..38c67a4 --- /dev/null +++ b/app/src/main/res/layout/empty_state_create_chat.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/empty_state_friends.xml b/app/src/main/res/layout/empty_state_friends.xml new file mode 100644 index 0000000..9dda290 --- /dev/null +++ b/app/src/main/res/layout/empty_state_friends.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/empty_state_participants.xml b/app/src/main/res/layout/empty_state_participants.xml new file mode 100644 index 0000000..45a4e72 --- /dev/null +++ b/app/src/main/res/layout/empty_state_participants.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_channels.xml b/app/src/main/res/layout/fragment_channels.xml new file mode 100644 index 0000000..ef146bb --- /dev/null +++ b/app/src/main/res/layout/fragment_channels.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_chats.xml b/app/src/main/res/layout/fragment_chats.xml index 6c8cf4d..c40f248 100644 --- a/app/src/main/res/layout/fragment_chats.xml +++ b/app/src/main/res/layout/fragment_chats.xml @@ -1,24 +1,65 @@ - - - + + + + + + + + - + android:layout_alignParentTop="true"> + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_near_by.xml b/app/src/main/res/layout/fragment_near_by.xml index fc961f6..a24fbdb 100644 --- a/app/src/main/res/layout/fragment_near_by.xml +++ b/app/src/main/res/layout/fragment_near_by.xml @@ -17,6 +17,7 @@ android:layout_alignParentTop="true" android:clickable="true" app:layoutManager="LinearLayoutManager" + android:layout_marginBottom="100dp" /> diff --git a/app/src/main/res/layout/giphy_selector.xml b/app/src/main/res/layout/giphy_selector.xml index d564856..dd5c0fa 100644 --- a/app/src/main/res/layout/giphy_selector.xml +++ b/app/src/main/res/layout/giphy_selector.xml @@ -31,6 +31,8 @@ android:background="@drawable/chat_field_bg" android:hint="Search" android:padding="2dp" + android:layout_marginLeft="23dp" + android:layout_marginStart="23dp" android:textColor="@color/title" android:textColorHint="@color/hint" android:textSize="20sp" diff --git a/app/src/main/res/layout/profile_editpage.xml b/app/src/main/res/layout/profile_editpage.xml index 5e8ed2b..fe775a0 100644 --- a/app/src/main/res/layout/profile_editpage.xml +++ b/app/src/main/res/layout/profile_editpage.xml @@ -67,7 +67,8 @@ android:layout_height="wrap_content" android:hint="@string/write_something_about_you" android:inputType="textMultiLine" - app:binding2way="@{activity.about}" /> + app:binding2way="@{activity.about}" + android:maxLines="3"/> diff --git a/app/src/main/res/layout/row_chats.xml b/app/src/main/res/layout/row_chats.xml index 2d27b0d..216537b 100644 --- a/app/src/main/res/layout/row_chats.xml +++ b/app/src/main/res/layout/row_chats.xml @@ -79,14 +79,34 @@ android:textSize="@{username.length > 30 ? 16 : 19 }" style="@style/list_title"/> - + android:orientation="horizontal"> + + + + + + diff --git a/app/src/main/res/layout/row_create_chat_item.xml b/app/src/main/res/layout/row_create_chat_item.xml new file mode 100644 index 0000000..5130ff0 --- /dev/null +++ b/app/src/main/res/layout/row_create_chat_item.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_friends.xml b/app/src/main/res/layout/row_friends.xml new file mode 100644 index 0000000..4110c74 --- /dev/null +++ b/app/src/main/res/layout/row_friends.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_participants.xml b/app/src/main/res/layout/row_participants.xml new file mode 100644 index 0000000..a1baa3e --- /dev/null +++ b/app/src/main/res/layout/row_participants.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_search_user_item.xml b/app/src/main/res/layout/row_search_user_item.xml new file mode 100644 index 0000000..405ba4f --- /dev/null +++ b/app/src/main/res/layout/row_search_user_item.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_selected_avatar.xml b/app/src/main/res/layout/row_selected_avatar.xml new file mode 100644 index 0000000..ecf6bee --- /dev/null +++ b/app/src/main/res/layout/row_selected_avatar.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v19/styles.xml b/app/src/main/res/values-v19/styles.xml index 2eec0d4..8151eb4 100644 --- a/app/src/main/res/values-v19/styles.xml +++ b/app/src/main/res/values-v19/styles.xml @@ -2,6 +2,6 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9fae08e..1eea1ee 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -11,4 +11,6 @@ #E6E6E6 #EFDF67 #87E062 + #CF3715 + @android:color/transparent \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 14a5cb3..31a8d58 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,6 +45,7 @@ Recover Near by Chats + Friends open close @@ -111,10 +112,37 @@ Choose from gallery Send file Please enter any worlds to start search + Remove from friends + Send request + You are about to add + to friends + You are about to remove + from friends + friend request + You have sent a friend request + Accept invite + Reject invite + User + wants to add you to friends list + You have blocked this user + Channels + Chat admin + Add + Sorry, you cannot have more than 3 channels. + Remove + You are not logged in + Something went wrong, please try again later + Add participant + Create chat or group + Done + Search + Channel + Unable connect to server. Please check internet connection + Unable connect to server. Please check your internet connection and try again. Male Female Not set - + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 9798b83..ad6b5e8 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,4 +1,4 @@ - + @@ -100,6 +100,19 @@ Proxima_Nova_Regular.otf + +