Added picture loading and adding user to userlist in chat entity

This commit is contained in:
ChronosX88 2019-05-26 18:00:27 +04:00
parent 6936c0127e
commit 5400aeea88
13 changed files with 111 additions and 47 deletions

View File

@ -84,6 +84,8 @@ dependencies {
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.0' implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.0'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'org.igniterealtime.smack:smack-experimental:4.3.3' implementation 'org.igniterealtime.smack:smack-experimental:4.3.3'
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
} }
repositories { repositories {
mavenCentral() mavenCentral()

View File

@ -16,9 +16,11 @@
package io.github.chronosx88.influence.contracts package io.github.chronosx88.influence.contracts
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.view.MenuItem import android.view.MenuItem
import androidx.fragment.app.Fragment
import com.stfalcon.chatkit.dialogs.DialogsListAdapter import com.stfalcon.chatkit.dialogs.DialogsListAdapter
import com.stfalcon.chatkit.messages.MessagesListAdapter import com.stfalcon.chatkit.messages.MessagesListAdapter
import io.github.chronosx88.influence.models.GenericDialog import io.github.chronosx88.influence.models.GenericDialog
@ -49,10 +51,11 @@ interface CoreContracts {
fun loadRemoteContactList() fun loadRemoteContactList()
} }
interface IChatListViewContract { interface IDialogListViewContract {
fun setDialogAdapter(adapter: DialogsListAdapter<GenericDialog>) fun setDialogAdapter(adapter: DialogsListAdapter<GenericDialog>)
fun startActivity(intent: Intent) fun startActivity(intent: Intent)
fun getActivityContext(): Context? fun getActivityContext(): Context?
fun getFragmentObject(): Fragment
} }
// -----MainActivity----- // -----MainActivity-----
@ -99,6 +102,7 @@ interface CoreContracts {
interface IChatViewContract { interface IChatViewContract {
fun setAdapter(adapter: MessagesListAdapter<GenericMessage>) fun setAdapter(adapter: MessagesListAdapter<GenericMessage>)
fun setUserStatus(status: String) fun setUserStatus(status: String)
fun getActivityObject(): Activity
} }
// -----SettingsFragment----- // -----SettingsFragment-----

View File

@ -16,26 +16,43 @@
package io.github.chronosx88.influence.helpers; package io.github.chronosx88.influence.helpers;
import android.app.Activity;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.TextDrawable;
import com.amulyakhare.textdrawable.util.ColorGenerator; import com.amulyakhare.textdrawable.util.ColorGenerator;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.stfalcon.chatkit.commons.ImageLoader; import com.stfalcon.chatkit.commons.ImageLoader;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException; import org.jxmpp.stringprep.XmppStringprepException;
import io.github.chronosx88.influence.R;
import java9.util.concurrent.CompletableFuture; import java9.util.concurrent.CompletableFuture;
public class AvatarImageLoader implements ImageLoader { public class AvatarImageLoader implements ImageLoader {
private Fragment fragment = null;
private Activity activity = null;
public AvatarImageLoader(Fragment fragment) {
this.fragment = fragment;
}
public AvatarImageLoader(Activity activity) {
this.activity = activity;
}
@Override @Override
public void loadImage(ImageView imageView, @Nullable String url, @Nullable Object payload) { public void loadImage(ImageView imageView, @Nullable String url, @Nullable Object payload) {
if(url.length() != 0) { if(url.length() != 0) {
if(!url.contains("http")) {
if(AppHelper.avatarsCache.containsKey(url)) { if(AppHelper.avatarsCache.containsKey(url)) {
byte[] avatarBytes = AppHelper.avatarsCache.get(url); byte[] avatarBytes = AppHelper.avatarsCache.get(url);
Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length); Bitmap avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
@ -68,6 +85,16 @@ public class AvatarImageLoader implements ImageLoader {
} }
}); });
}); });
} else {
RequestOptions requestOptions = new RequestOptions()
.placeholder(R.drawable.no_image_picture)
.error(R.drawable.no_image_picture);
if(fragment != null) {
Glide.with(fragment).setDefaultRequestOptions(requestOptions).load(url).into(imageView);
} else if(activity != null) {
Glide.with(activity).setDefaultRequestOptions(requestOptions).load(url).into(imageView);
}
}
} }
} }
} }

View File

@ -21,6 +21,7 @@ import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import io.github.chronosx88.influence.models.GenericUser;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity; import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.models.roomEntities.MessageEntity; import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
@ -28,8 +29,8 @@ public class LocalDBWrapper {
private static final String LOG_TAG = "LocalDBWrapper"; private static final String LOG_TAG = "LocalDBWrapper";
private static RoomHelper dbInstance = AppHelper.getChatDB(); private static RoomHelper dbInstance = AppHelper.getChatDB();
public static void createChatEntry(String jid, String chatName) { public static void createChatEntry(String jid, String chatName, ArrayList<GenericUser> users) {
dbInstance.chatDao().addChat(new ChatEntity(jid, chatName, new ArrayList<>(), 0, "")); dbInstance.chatDao().addChat(new ChatEntity(jid, chatName, users, 0, ""));
} }
public static long createMessageEntry(String chatID, String messageUid, String senderJid, long timestamp, String text, boolean isSent, boolean isRead) { public static long createMessageEntry(String chatID, String messageUid, String senderJid, long timestamp, String text, boolean isSent, boolean isRead) {

View File

@ -45,11 +45,13 @@ import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException; import org.jxmpp.stringprep.XmppStringprepException;
import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import io.github.chronosx88.influence.R; import io.github.chronosx88.influence.R;
import io.github.chronosx88.influence.models.GenericMessage; import io.github.chronosx88.influence.models.GenericMessage;
import io.github.chronosx88.influence.models.GenericUser;
import io.github.chronosx88.influence.models.appEvents.LastMessageEvent; import io.github.chronosx88.influence.models.appEvents.LastMessageEvent;
import io.github.chronosx88.influence.models.appEvents.NewMessageEvent; import io.github.chronosx88.influence.models.appEvents.NewMessageEvent;
import io.github.chronosx88.influence.models.appEvents.UserPresenceChangedEvent; import io.github.chronosx88.influence.models.appEvents.UserPresenceChangedEvent;
@ -69,7 +71,10 @@ public class NetworkHandler implements IncomingChatMessageListener, PresenceEven
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) { public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
String chatID = chat.getXmppAddressOfChatPartner().asUnescapedString(); String chatID = chat.getXmppAddressOfChatPartner().asUnescapedString();
if(LocalDBWrapper.getChatByChatID(from.asEntityBareJidString()) == null) { if(LocalDBWrapper.getChatByChatID(from.asEntityBareJidString()) == null) {
LocalDBWrapper.createChatEntry(chatID, chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString().split("@")[0]); ArrayList<GenericUser> users = new ArrayList<>();
users.add(new GenericUser(AppHelper.getJid(), AppHelper.getJid().split("@")[0], AppHelper.getJid()));
users.add(new GenericUser(chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString(), chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString().split("@")[0], chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString()));
LocalDBWrapper.createChatEntry(chatID, chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString().split("@")[0], users);
} }
long messageID = LocalDBWrapper.createMessageEntry(chatID, message.getStanzaId(), from.asUnescapedString(), TrueTime.now().getTime(), message.getBody(), true, false); long messageID = LocalDBWrapper.createMessageEntry(chatID, message.getStanzaId(), from.asUnescapedString(), TrueTime.now().getTime(), message.getBody(), true, false);
int newUnreadMessagesCount = LocalDBWrapper.getChatByChatID(chatID).unreadMessagesCount + 1; int newUnreadMessagesCount = LocalDBWrapper.getChatByChatID(chatID).unreadMessagesCount + 1;

View File

@ -30,7 +30,7 @@ public class RoomTypeConverter {
@TypeConverter @TypeConverter
public static ArrayList<GenericUser> fromString(String value) { public static ArrayList<GenericUser> fromString(String value) {
Type listType = new TypeToken<ArrayList<String>>() {}.getType(); Type listType = new TypeToken<ArrayList<GenericUser>>() {}.getType();
return new Gson().fromJson(value, listType); return new Gson().fromJson(value, listType);
} }

View File

@ -16,26 +16,31 @@
package io.github.chronosx88.influence.models; package io.github.chronosx88.influence.models;
import androidx.annotation.Nullable;
import com.stfalcon.chatkit.commons.models.IMessage; import com.stfalcon.chatkit.commons.models.IMessage;
import com.stfalcon.chatkit.commons.models.IUser; import com.stfalcon.chatkit.commons.models.IUser;
import com.stfalcon.chatkit.commons.models.MessageContentType;
import java.util.Date; import java.util.Date;
import io.github.chronosx88.influence.models.roomEntities.MessageEntity; import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
public class GenericMessage implements IMessage { public class GenericMessage implements IMessage, MessageContentType.Image {
private long messageID; private long messageID;
private String messageUid;
private IUser author; private IUser author;
private long timestamp; private long timestamp;
private String text; private String text;
private String imageUrl;
public GenericMessage(MessageEntity messageEntity) { public GenericMessage(MessageEntity messageEntity) {
this.messageID = messageEntity.messageID; this.messageID = messageEntity.messageID;
this.messageUid = messageEntity.messageUid;
this.author = new GenericUser(messageEntity.senderJid, messageEntity.senderJid, messageEntity.senderJid); this.author = new GenericUser(messageEntity.senderJid, messageEntity.senderJid, messageEntity.senderJid);
this.timestamp = messageEntity.timestamp; this.timestamp = messageEntity.timestamp;
this.text = messageEntity.text; this.text = messageEntity.text;
if(messageEntity.text.contains("http") && messageEntity.text.contains(".jpg")) {
imageUrl = messageEntity.text;
}
} }
@Override @Override
@ -58,7 +63,9 @@ public class GenericMessage implements IMessage {
return new Date(timestamp); return new Date(timestamp);
} }
public String getMessageUid() { @Nullable
return messageUid; @Override
public String getImageUrl() {
return imageUrl;
} }
} }

View File

@ -55,7 +55,7 @@ class ChatPresenter(private val view: CoreContracts.IChatViewContract, private v
gson = Gson() gson = Gson()
val holdersConfig = MessageHolders() val holdersConfig = MessageHolders()
holdersConfig.setIncomingTextLayout(R.layout.item_incoming_text_message_custom) holdersConfig.setIncomingTextLayout(R.layout.item_incoming_text_message_custom)
chatAdapter = MessagesListAdapter(AppHelper.getJid(), holdersConfig, AvatarImageLoader()) chatAdapter = MessagesListAdapter(AppHelper.getJid(), holdersConfig, AvatarImageLoader(view.getActivityObject()))
chatAdapter.setLoadMoreListener { page, _ -> loadMoreMessages() } chatAdapter.setLoadMoreListener { page, _ -> loadMoreMessages() }
view.setAdapter(chatAdapter) view.setAdapter(chatAdapter)
getUserStatus() getUserStatus()

View File

@ -38,6 +38,7 @@ import io.github.chronosx88.influence.helpers.LocalDBWrapper;
import io.github.chronosx88.influence.logic.DialogListLogic; import io.github.chronosx88.influence.logic.DialogListLogic;
import io.github.chronosx88.influence.models.GenericDialog; import io.github.chronosx88.influence.models.GenericDialog;
import io.github.chronosx88.influence.models.GenericMessage; import io.github.chronosx88.influence.models.GenericMessage;
import io.github.chronosx88.influence.models.GenericUser;
import io.github.chronosx88.influence.models.appEvents.AuthenticationStatusEvent; import io.github.chronosx88.influence.models.appEvents.AuthenticationStatusEvent;
import io.github.chronosx88.influence.models.appEvents.LastMessageEvent; import io.github.chronosx88.influence.models.appEvents.LastMessageEvent;
import io.github.chronosx88.influence.models.appEvents.NewChatEvent; import io.github.chronosx88.influence.models.appEvents.NewChatEvent;
@ -48,10 +49,9 @@ import java8.util.stream.StreamSupport;
import java9.util.concurrent.CompletableFuture; import java9.util.concurrent.CompletableFuture;
public class DialogListPresenter implements CoreContracts.IDialogListPresenterContract { public class DialogListPresenter implements CoreContracts.IDialogListPresenterContract {
private ConcurrentHashMap<String, byte[]> avatarsMap = new ConcurrentHashMap<>(); private CoreContracts.IDialogListViewContract view;
private CoreContracts.IChatListViewContract view;
private CoreContracts.IDialogListLogicContract logic; private CoreContracts.IDialogListLogicContract logic;
private DialogsListAdapter<GenericDialog> dialogListAdapter = new DialogsListAdapter<>(R.layout.item_dialog_custom, new AvatarImageLoader()); private DialogsListAdapter<GenericDialog> dialogListAdapter;
private Comparator<GenericDialog> dialogComparator = (dialog1, dialog2) -> { private Comparator<GenericDialog> dialogComparator = (dialog1, dialog2) -> {
if(dialog2.getLastMessage() != null && dialog1.getLastMessage() != null) { if(dialog2.getLastMessage() != null && dialog1.getLastMessage() != null) {
return Long.compare(dialog2.getLastMessage().getCreatedAt().getTime(), dialog1.getLastMessage().getCreatedAt().getTime()); return Long.compare(dialog2.getLastMessage().getCreatedAt().getTime(), dialog1.getLastMessage().getCreatedAt().getTime());
@ -64,8 +64,9 @@ public class DialogListPresenter implements CoreContracts.IDialogListPresenterCo
return 0; return 0;
}; };
public DialogListPresenter(CoreContracts.IChatListViewContract view) { public DialogListPresenter(CoreContracts.IDialogListViewContract view) {
this.view = view; this.view = view;
dialogListAdapter = new DialogsListAdapter<>(R.layout.item_dialog_custom, new AvatarImageLoader(view.getFragmentObject()));
dialogListAdapter.setOnDialogClickListener(dialog -> openChat(dialog.getId())); dialogListAdapter.setOnDialogClickListener(dialog -> openChat(dialog.getId()));
dialogListAdapter.setOnDialogLongClickListener(dialog -> { dialogListAdapter.setOnDialogLongClickListener(dialog -> {
AlertDialog.Builder builder = new AlertDialog.Builder(view.getActivityContext()); AlertDialog.Builder builder = new AlertDialog.Builder(view.getActivityContext());
@ -147,7 +148,10 @@ public class DialogListPresenter implements CoreContracts.IDialogListPresenterCo
if(contacts != null) { if(contacts != null) {
StreamSupport.stream(contacts).forEach(contact -> { StreamSupport.stream(contacts).forEach(contact -> {
String chatID = contact.getJid().asUnescapedString(); String chatID = contact.getJid().asUnescapedString();
LocalDBWrapper.createChatEntry(chatID, contact.getName() == null ? contact.getJid().asUnescapedString().split("@")[0] : contact.getName()); ArrayList<GenericUser> users = new ArrayList<>();
users.add(new GenericUser(AppHelper.getJid(), AppHelper.getJid().split("@")[0], AppHelper.getJid()));
users.add(new GenericUser(chatID, contact.getName() == null ? contact.getJid().asUnescapedString().split("@")[0] : contact.getName(), chatID));
LocalDBWrapper.createChatEntry(chatID, contact.getName() == null ? contact.getJid().asUnescapedString().split("@")[0] : contact.getName(), users);
GenericDialog dialog = new GenericDialog(LocalDBWrapper.getChatByChatID(chatID)); GenericDialog dialog = new GenericDialog(LocalDBWrapper.getChatByChatID(chatID));
MessageEntity messageEntity = LocalDBWrapper.getLastMessage(chatID); MessageEntity messageEntity = LocalDBWrapper.getLastMessage(chatID);
if(messageEntity != null) { if(messageEntity != null) {

View File

@ -23,6 +23,7 @@ import io.github.chronosx88.influence.contracts.CoreContracts
import io.github.chronosx88.influence.helpers.AppHelper import io.github.chronosx88.influence.helpers.AppHelper
import io.github.chronosx88.influence.helpers.LocalDBWrapper import io.github.chronosx88.influence.helpers.LocalDBWrapper
import io.github.chronosx88.influence.logic.MainLogic import io.github.chronosx88.influence.logic.MainLogic
import io.github.chronosx88.influence.models.GenericUser
import io.github.chronosx88.influence.models.appEvents.AuthenticationStatusEvent import io.github.chronosx88.influence.models.appEvents.AuthenticationStatusEvent
import io.github.chronosx88.influence.models.appEvents.NewChatEvent import io.github.chronosx88.influence.models.appEvents.NewChatEvent
import io.github.chronosx88.influence.views.LoginActivity import io.github.chronosx88.influence.views.LoginActivity
@ -47,7 +48,10 @@ class MainPresenter(private val view: CoreContracts.IMainViewContract) : CoreCon
view.showSnackbar(AppHelper.getContext().getString(R.string.invalid_jid_error)) view.showSnackbar(AppHelper.getContext().getString(R.string.invalid_jid_error))
return return
} }
LocalDBWrapper.createChatEntry(username, username.split("@")[0]) val users = ArrayList<GenericUser>()
users.add(GenericUser(AppHelper.getJid(), AppHelper.getJid().split("@")[0], AppHelper.getJid()))
users.add(GenericUser(username, username.split("@")[0], AppHelper.getJid()))
LocalDBWrapper.createChatEntry(username, username.split("@")[0], users)
EventBus.getDefault().post(NewChatEvent(username)) EventBus.getDefault().post(NewChatEvent(username))
} }

View File

@ -16,6 +16,7 @@
package io.github.chronosx88.influence.views package io.github.chronosx88.influence.views
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Bundle import android.os.Bundle
@ -122,4 +123,8 @@ class ChatActivity : AppCompatActivity(), CoreContracts.IChatViewContract {
super.onResume() super.onResume()
presenter!!.loadRecentPageMessages() presenter!!.loadRecentPageMessages()
} }
override fun getActivityObject(): Activity {
return this
}
} }

View File

@ -16,6 +16,7 @@
package io.github.chronosx88.influence.views.fragments package io.github.chronosx88.influence.views.fragments
import android.app.Activity
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -30,7 +31,7 @@ import io.github.chronosx88.influence.models.GenericDialog
import io.github.chronosx88.influence.presenters.DialogListPresenter import io.github.chronosx88.influence.presenters.DialogListPresenter
class DialogListFragment : Fragment(), CoreContracts.IChatListViewContract { class DialogListFragment : Fragment(), CoreContracts.IDialogListViewContract {
private lateinit var presenter: CoreContracts.IDialogListPresenterContract private lateinit var presenter: CoreContracts.IDialogListPresenterContract
private lateinit var dialogList: DialogsList private lateinit var dialogList: DialogsList
@ -62,4 +63,8 @@ class DialogListFragment : Fragment(), CoreContracts.IChatListViewContract {
presenter.onStop() presenter.onStop()
super.onStop() super.onStop()
} }
override fun getFragmentObject(): Fragment {
return this
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B