From 055f62bfecafb1e2ef5d9a02c6d9469a0f221e44 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Mon, 18 Mar 2019 20:39:53 +0400 Subject: [PATCH] [WIP] Added start chat fragment template, chat list recycle view (with adapter), handling new chats (in live mode). // TODO: Make starting chat --- .../influence/contracts/MainViewContract.java | 7 -- .../chatlist/ChatListLogicContract.java | 10 +++ .../chatlist/ChatListPresenterContract.java | 6 ++ .../chatlist/ChatListViewContract.java | 7 ++ .../{ => main}/MainLogicContract.java | 2 +- .../{ => main}/MainPresenterContract.java | 2 +- .../contracts/main/MainViewContract.java | 5 ++ .../influence/helpers/ChatListAdapter.java | 50 +++++++++++++ .../influence/helpers/NetworkActions.java | 7 ++ .../influence/helpers/RoomHelper.java | 6 +- .../{MessageActions.java => UIActions.java} | 3 +- .../influence/logic/ChatListLogic.java | 45 ++++++++++++ .../chronosx88/influence/logic/MainLogic.java | 25 ++++--- .../influence/models/daos/ChatDao.java | 8 +-- .../influence/models/daos/MessageDao.java | 8 +-- .../models/roomEntities/ChatEntity.java | 30 ++++++++ .../models/roomEntities/ChatModel.java | 11 --- .../models/roomEntities/MessageEntity.java | 43 +++++++++++ .../models/roomEntities/MessageModel.java | 12 ---- .../presenters/ChatListPresenter.java | 31 ++++++++ .../influence/presenters/MainPresenter.java | 6 +- .../influence/views/MainActivity.java | 29 ++++---- .../views/fragments/ChatFragment.java | 22 ------ .../views/fragments/ChatListFragment.java | 72 +++++++++++++++++++ .../views/fragments/StartChatFragment.java | 8 +++ app/src/main/res/layout/chat_item.xml | 18 +++++ ...hat_fragment.xml => chatlist_fragment.xml} | 9 +-- .../main/res/layout/start_chat_fragment.xml | 16 +++-- 28 files changed, 395 insertions(+), 103 deletions(-) delete mode 100644 app/src/main/java/io/github/chronosx88/influence/contracts/MainViewContract.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListLogicContract.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListPresenterContract.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListViewContract.java rename app/src/main/java/io/github/chronosx88/influence/contracts/{ => main}/MainLogicContract.java (60%) rename app/src/main/java/io/github/chronosx88/influence/contracts/{ => main}/MainPresenterContract.java (61%) create mode 100644 app/src/main/java/io/github/chronosx88/influence/contracts/main/MainViewContract.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/helpers/ChatListAdapter.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/helpers/NetworkActions.java rename app/src/main/java/io/github/chronosx88/influence/helpers/{MessageActions.java => UIActions.java} (84%) create mode 100644 app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatEntity.java delete mode 100644 app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatModel.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageEntity.java delete mode 100644 app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageModel.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java delete mode 100644 app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatFragment.java create mode 100644 app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.java create mode 100644 app/src/main/res/layout/chat_item.xml rename app/src/main/res/layout/{chat_fragment.xml => chatlist_fragment.xml} (57%) diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/MainViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/MainViewContract.java deleted file mode 100644 index 9c44961..0000000 --- a/app/src/main/java/io/github/chronosx88/influence/contracts/MainViewContract.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.chronosx88.influence.contracts; - -import android.content.SharedPreferences; - -public interface MainViewContract { - // -} diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListLogicContract.java new file mode 100644 index 0000000..7a60e99 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListLogicContract.java @@ -0,0 +1,10 @@ +package io.github.chronosx88.influence.contracts.chatlist; + +import java.util.List; + +import io.github.chronosx88.influence.models.roomEntities.ChatEntity; + +public interface ChatListLogicContract { + List loadAllChats(); + void createChatBySender(ChatEntity entity); +} diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListPresenterContract.java new file mode 100644 index 0000000..1abbb27 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListPresenterContract.java @@ -0,0 +1,6 @@ +package io.github.chronosx88.influence.contracts.chatlist; + +public interface ChatListPresenterContract { + void updateChatList(); + void openChat(String chatID); +} diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListViewContract.java new file mode 100644 index 0000000..7572b22 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/ChatListViewContract.java @@ -0,0 +1,7 @@ +package io.github.chronosx88.influence.contracts.chatlist; + +import io.github.chronosx88.influence.helpers.ChatListAdapter; + +public interface ChatListViewContract { + void setRecycleAdapter(ChatListAdapter adapter); +} diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/MainLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainLogicContract.java similarity index 60% rename from app/src/main/java/io/github/chronosx88/influence/contracts/MainLogicContract.java rename to app/src/main/java/io/github/chronosx88/influence/contracts/main/MainLogicContract.java index 3454894..0d9517b 100644 --- a/app/src/main/java/io/github/chronosx88/influence/contracts/MainLogicContract.java +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainLogicContract.java @@ -1,4 +1,4 @@ -package io.github.chronosx88.influence.contracts; +package io.github.chronosx88.influence.contracts.main; public interface MainLogicContract { void initPeer(); diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/MainPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainPresenterContract.java similarity index 61% rename from app/src/main/java/io/github/chronosx88/influence/contracts/MainPresenterContract.java rename to app/src/main/java/io/github/chronosx88/influence/contracts/main/MainPresenterContract.java index cca16f2..3ff5969 100644 --- a/app/src/main/java/io/github/chronosx88/influence/contracts/MainPresenterContract.java +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainPresenterContract.java @@ -1,4 +1,4 @@ -package io.github.chronosx88.influence.contracts; +package io.github.chronosx88.influence.contracts.main; public interface MainPresenterContract { void initPeer(); diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainViewContract.java new file mode 100644 index 0000000..189e9a9 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/contracts/main/MainViewContract.java @@ -0,0 +1,5 @@ +package io.github.chronosx88.influence.contracts.main; + +public interface MainViewContract { + // +} diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/ChatListAdapter.java b/app/src/main/java/io/github/chronosx88/influence/helpers/ChatListAdapter.java new file mode 100644 index 0000000..ec5f243 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/ChatListAdapter.java @@ -0,0 +1,50 @@ +package io.github.chronosx88.influence.helpers; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import io.github.chronosx88.influence.R; +import io.github.chronosx88.influence.models.roomEntities.ChatEntity; + +public class ChatListAdapter extends RecyclerView.Adapter { + List chatList = new ArrayList<>(); + + @NonNull + @Override + public ChatListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.chat_item, parent, false); + return new ChatListViewHolder(view); + } + + public void setChatList(List entities) { + chatList.clear(); + chatList.addAll(entities); + } + + @Override + public void onBindViewHolder(@NonNull ChatListViewHolder holder, int position) { + holder.chatName.setText(chatList.get(position).getName()); + } + + @Override + public int getItemCount() { + return chatList.size(); + } + + class ChatListViewHolder extends RecyclerView.ViewHolder { + TextView chatName; + + public ChatListViewHolder(View itemView) { + super(itemView); + chatName = itemView.findViewById(R.id.chat_name); + } + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkActions.java b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkActions.java new file mode 100644 index 0000000..0093ac2 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkActions.java @@ -0,0 +1,7 @@ +package io.github.chronosx88.influence.helpers; + +public class NetworkActions { + public static final int START_CHAT = 0x0; + public static final int NEW_MESSAGE = 0x1; + public static final int MESSAGE_SENT = 0x2; +} diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/RoomHelper.java b/app/src/main/java/io/github/chronosx88/influence/helpers/RoomHelper.java index 161457c..2beacaa 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/RoomHelper.java +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/RoomHelper.java @@ -2,12 +2,12 @@ package io.github.chronosx88.influence.helpers; import androidx.room.Database; import androidx.room.RoomDatabase; -import io.github.chronosx88.influence.models.roomEntities.ChatModel; -import io.github.chronosx88.influence.models.roomEntities.MessageModel; import io.github.chronosx88.influence.models.daos.ChatDao; import io.github.chronosx88.influence.models.daos.MessageDao; +import io.github.chronosx88.influence.models.roomEntities.ChatEntity; +import io.github.chronosx88.influence.models.roomEntities.MessageEntity; -@Database(entities = { MessageModel.class, ChatModel.class }, version = 1) +@Database(entities = { MessageEntity.class, ChatEntity.class }, version = 1) public abstract class RoomHelper extends RoomDatabase { public abstract ChatDao chatDao(); public abstract MessageDao messageDao(); diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/MessageActions.java b/app/src/main/java/io/github/chronosx88/influence/helpers/UIActions.java similarity index 84% rename from app/src/main/java/io/github/chronosx88/influence/helpers/MessageActions.java rename to app/src/main/java/io/github/chronosx88/influence/helpers/UIActions.java index 636d9fd..1d03247 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/MessageActions.java +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/UIActions.java @@ -1,10 +1,11 @@ package io.github.chronosx88.influence.helpers; -public class MessageActions { +public class UIActions { public static final int BOOTSTRAP_NOT_SPECIFIED = 0x0; public static final int NETWORK_ERROR = 0x1; public static final int BOOTSTRAP_SUCCESS = 0x2; public static final int PORT_FORWARDING_ERROR = 0x3; public static final int RELAY_CONNECTION_ERROR = 0x4; public static final int BOOTSTRAP_ERROR = 0x5; + public static final int NEW_CHAT = 0x6; } diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java new file mode 100644 index 0000000..1c8b4a4 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java @@ -0,0 +1,45 @@ +package io.github.chronosx88.influence.logic; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +import io.github.chronosx88.influence.contracts.chatlist.ChatListLogicContract; +import io.github.chronosx88.influence.contracts.observer.Observer; +import io.github.chronosx88.influence.helpers.AppHelper; +import io.github.chronosx88.influence.helpers.NetworkActions; +import io.github.chronosx88.influence.helpers.UIActions; +import io.github.chronosx88.influence.models.roomEntities.ChatEntity; +import io.github.chronosx88.influence.observable.MainObservable; + +public class ChatListLogic implements ChatListLogicContract, Observer { + public ChatListLogic() { + AppHelper.getObservable().register(this, MainObservable.OTHER_ACTIONS_CHANNEL); + } + + @Override + public List loadAllChats() { + return AppHelper.getChatDB().chatDao().getAllChats(); + } + + @Override + public void handleEvent(JSONObject object) { + try { + switch ((int) object.get("action")) { + case NetworkActions.START_CHAT: { + createChatBySender(new ChatEntity(object.getString("chatID"), object.getString("name"), "")); + AppHelper.getObservable().notifyObservers(new JSONObject().put("action", UIActions.NEW_CHAT), MainObservable.UI_ACTIONS_CHANNEL); + break; + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void createChatBySender(ChatEntity entity) { + AppHelper.getChatDB().chatDao().addChat(entity); + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java index c1c0403..7c58fd0 100644 --- a/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java +++ b/app/src/main/java/io/github/chronosx88/influence/logic/MainLogic.java @@ -25,10 +25,10 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.UUID; -import io.github.chronosx88.influence.contracts.MainLogicContract; +import io.github.chronosx88.influence.contracts.main.MainLogicContract; import io.github.chronosx88.influence.helpers.AppHelper; -import io.github.chronosx88.influence.helpers.MessageActions; import io.github.chronosx88.influence.helpers.StorageMVStore; +import io.github.chronosx88.influence.helpers.UIActions; import io.github.chronosx88.influence.observable.MainObservable; public class MainLogic implements MainLogicContract { @@ -77,7 +77,7 @@ public class MainLogic implements MainLogicContract { } catch (NullPointerException e) { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.BOOTSTRAP_NOT_SPECIFIED), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.BOOTSTRAP_NOT_SPECIFIED), MainObservable.UI_ACTIONS_CHANNEL); peerDHT.shutdown(); return; } catch (JSONException ex) { @@ -86,7 +86,7 @@ public class MainLogic implements MainLogicContract { } catch (UnknownHostException e) { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.NETWORK_ERROR), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.NETWORK_ERROR), MainObservable.UI_ACTIONS_CHANNEL); peerDHT.shutdown(); return; } catch (JSONException ex) { @@ -97,7 +97,7 @@ public class MainLogic implements MainLogicContract { if(!discoverExternalAddress()) { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.PORT_FORWARDING_ERROR), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.PORT_FORWARDING_ERROR), MainObservable.UI_ACTIONS_CHANNEL); } catch (JSONException ex) { ex.printStackTrace(); } @@ -106,7 +106,7 @@ public class MainLogic implements MainLogicContract { if(!setupConnectionToRelay()) { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.RELAY_CONNECTION_ERROR), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.RELAY_CONNECTION_ERROR), MainObservable.UI_ACTIONS_CHANNEL); return; } catch (JSONException ex) { ex.printStackTrace(); @@ -116,7 +116,7 @@ public class MainLogic implements MainLogicContract { if(!bootstrapPeer()) { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.BOOTSTRAP_ERROR), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.BOOTSTRAP_ERROR), MainObservable.UI_ACTIONS_CHANNEL); return; } catch (JSONException ex) { ex.printStackTrace(); @@ -125,12 +125,13 @@ public class MainLogic implements MainLogicContract { try { AppHelper.getObservable().notifyObservers(new JSONObject() - .put("action", MessageActions.BOOTSTRAP_SUCCESS), MainObservable.UI_ACTIONS_CHANNEL); + .put("action", UIActions.BOOTSTRAP_SUCCESS), MainObservable.UI_ACTIONS_CHANNEL); } catch (JSONException ex) { ex.printStackTrace(); } AppHelper.storePeerID(preferences.getString("peerID", null)); AppHelper.storePeerDHT(peerDHT); + setReceiveHandler(); } catch (IOException e) { e.printStackTrace(); } @@ -179,6 +180,14 @@ public class MainLogic implements MainLogicContract { } } + private void setReceiveHandler() { + AppHelper.getPeerDHT().peer().objectDataReply((s, r) -> { + Log.i(LOG_TAG, "# Incoming message: " + r); + AppHelper.getObservable().notifyObservers(new JSONObject((String) r), MainObservable.OTHER_ACTIONS_CHANNEL); + return null; + }); + } + @Override public void shutdownPeer() { peerDHT.shutdown(); diff --git a/app/src/main/java/io/github/chronosx88/influence/models/daos/ChatDao.java b/app/src/main/java/io/github/chronosx88/influence/models/daos/ChatDao.java index dcd92a2..c30a23e 100644 --- a/app/src/main/java/io/github/chronosx88/influence/models/daos/ChatDao.java +++ b/app/src/main/java/io/github/chronosx88/influence/models/daos/ChatDao.java @@ -5,19 +5,19 @@ import java.util.List; import androidx.room.Dao; import androidx.room.Insert; import androidx.room.Query; -import io.github.chronosx88.influence.models.roomEntities.ChatModel; +import io.github.chronosx88.influence.models.roomEntities.ChatEntity; @Dao public interface ChatDao { @Insert - void addChat(ChatModel chatModel); + void addChat(ChatEntity chatEntity); @Query("DELETE FROM chats WHERE id = :chatID") void deleteChat(String chatID); @Query("SELECT * FROM chats") - List getAllChats(); + List getAllChats(); @Query("SELECT * FROM chats WHERE id = :chatID") - List getChatByID(String chatID); + List getChatByID(String chatID); } diff --git a/app/src/main/java/io/github/chronosx88/influence/models/daos/MessageDao.java b/app/src/main/java/io/github/chronosx88/influence/models/daos/MessageDao.java index 4cabd67..a93d7c8 100644 --- a/app/src/main/java/io/github/chronosx88/influence/models/daos/MessageDao.java +++ b/app/src/main/java/io/github/chronosx88/influence/models/daos/MessageDao.java @@ -5,12 +5,12 @@ import java.util.List; import androidx.room.Dao; import androidx.room.Insert; import androidx.room.Query; -import io.github.chronosx88.influence.models.roomEntities.MessageModel; +import io.github.chronosx88.influence.models.roomEntities.MessageEntity; @Dao public interface MessageDao { @Insert - void insertMessage(MessageModel chatModel); + void insertMessage(MessageEntity chatModel); @Query("DELETE FROM messages WHERE id = :msgID") void deleteMessage(String msgID); @@ -19,8 +19,8 @@ public interface MessageDao { void deleteMessagesByChatID(String chatID); @Query("SELECT * FROM messages WHERE chatID = :chatID") - List getMessagesByChatID(String chatID); + List getMessagesByChatID(String chatID); @Query("SELECT * FROM messages WHERE id = :id") - List getMessageByID(String id); + List getMessageByID(String id); } diff --git a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatEntity.java b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatEntity.java new file mode 100644 index 0000000..f55a1a0 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatEntity.java @@ -0,0 +1,30 @@ +package io.github.chronosx88.influence.models.roomEntities; + +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "chats") +public class ChatEntity { + @PrimaryKey String id; + @ColumnInfo String name; + @ColumnInfo String keyPairID; + + public ChatEntity(String id, String name, String keyPairID) { + this.id = id; + this.name = name; + this.keyPairID = keyPairID; + } + + public String getId() { + return id; + } + + public String getKeyPairID() { + return keyPairID; + } + + public String getName() { + return name; + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatModel.java b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatModel.java deleted file mode 100644 index 955fa9e..0000000 --- a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/ChatModel.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.chronosx88.influence.models.roomEntities; - -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Entity(tableName = "chats") -public class ChatModel { - @PrimaryKey String id; - String name; - String keyPairID; -} diff --git a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageEntity.java b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageEntity.java new file mode 100644 index 0000000..eed5e44 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageEntity.java @@ -0,0 +1,43 @@ +package io.github.chronosx88.influence.models.roomEntities; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "messages") +public class MessageEntity { + @PrimaryKey String id; + @ColumnInfo String chatID; + @ColumnInfo String sender; + @ColumnInfo String text; + + public MessageEntity(String id, String chatID, String sender, String text) { + this.id = id; + this.chatID = chatID; + this.sender = sender; + this.text = text; + } + + public String getId() { + return id; + } + + public String getChatID() { + return chatID; + } + + public String getSender() { + return sender; + } + + public String getText() { + return text; + } + + @NonNull + @Override + public String toString() { + return id + "/" + chatID + "/" + sender + "/" + text; + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageModel.java b/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageModel.java deleted file mode 100644 index 96d65b9..0000000 --- a/app/src/main/java/io/github/chronosx88/influence/models/roomEntities/MessageModel.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.chronosx88.influence.models.roomEntities; - -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Entity(tableName = "messages") -public class MessageModel { - @PrimaryKey String id; - String chatID; - String sender; - String text; -} diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java b/app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java new file mode 100644 index 0000000..d1b4158 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java @@ -0,0 +1,31 @@ +package io.github.chronosx88.influence.presenters; + +import io.github.chronosx88.influence.contracts.chatlist.ChatListLogicContract; +import io.github.chronosx88.influence.contracts.chatlist.ChatListPresenterContract; +import io.github.chronosx88.influence.contracts.chatlist.ChatListViewContract; +import io.github.chronosx88.influence.helpers.ChatListAdapter; +import io.github.chronosx88.influence.logic.ChatListLogic; + +public class ChatListPresenter implements ChatListPresenterContract { + private ChatListViewContract view; + private ChatListLogicContract logic; + private ChatListAdapter chatListAdapter; + + public ChatListPresenter(ChatListViewContract view) { + this.view = view; + chatListAdapter = new ChatListAdapter(); + this.view.setRecycleAdapter(chatListAdapter); + this.logic = new ChatListLogic(); + } + + @Override + public void updateChatList() { + chatListAdapter.setChatList(logic.loadAllChats()); + chatListAdapter.notifyDataSetChanged(); + } + + @Override + public void openChat(String chatID) { + // TODO + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/MainPresenter.java b/app/src/main/java/io/github/chronosx88/influence/presenters/MainPresenter.java index 90967dd..c51f552 100644 --- a/app/src/main/java/io/github/chronosx88/influence/presenters/MainPresenter.java +++ b/app/src/main/java/io/github/chronosx88/influence/presenters/MainPresenter.java @@ -1,8 +1,8 @@ package io.github.chronosx88.influence.presenters; -import io.github.chronosx88.influence.contracts.MainLogicContract; -import io.github.chronosx88.influence.contracts.MainPresenterContract; -import io.github.chronosx88.influence.contracts.MainViewContract; +import io.github.chronosx88.influence.contracts.main.MainLogicContract; +import io.github.chronosx88.influence.contracts.main.MainPresenterContract; +import io.github.chronosx88.influence.contracts.main.MainViewContract; import io.github.chronosx88.influence.logic.MainLogic; public class MainPresenter implements MainPresenterContract { diff --git a/app/src/main/java/io/github/chronosx88/influence/views/MainActivity.java b/app/src/main/java/io/github/chronosx88/influence/views/MainActivity.java index 6fd7d59..ea21c26 100644 --- a/app/src/main/java/io/github/chronosx88/influence/views/MainActivity.java +++ b/app/src/main/java/io/github/chronosx88/influence/views/MainActivity.java @@ -15,13 +15,14 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import io.github.chronosx88.influence.R; -import io.github.chronosx88.influence.contracts.MainPresenterContract; -import io.github.chronosx88.influence.contracts.MainViewContract; +import io.github.chronosx88.influence.contracts.main.MainPresenterContract; +import io.github.chronosx88.influence.contracts.main.MainViewContract; import io.github.chronosx88.influence.contracts.observer.Observer; import io.github.chronosx88.influence.helpers.AppHelper; -import io.github.chronosx88.influence.helpers.MessageActions; +import io.github.chronosx88.influence.helpers.UIActions; +import io.github.chronosx88.influence.observable.MainObservable; import io.github.chronosx88.influence.presenters.MainPresenter; -import io.github.chronosx88.influence.views.fragments.ChatFragment; +import io.github.chronosx88.influence.views.fragments.ChatListFragment; import io.github.chronosx88.influence.views.fragments.SettingsFragment; import io.github.chronosx88.influence.views.fragments.StartChatFragment; @@ -39,7 +40,7 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie switch (item.getItemId()) { case R.id.action_chats: - selectedFragment = new ChatFragment(); + selectedFragment = new ChatListFragment(); break; case R.id.action_settings: selectedFragment = new SettingsFragment(); @@ -67,11 +68,11 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie getSupportFragmentManager() .beginTransaction() - .replace(R.id.main_fragment_container, new ChatFragment()) + .replace(R.id.main_fragment_container, new ChatListFragment()) .commit(); presenter = new MainPresenter(this); - AppHelper.getObservable().register(this); + AppHelper.getObservable().register(this, MainObservable.UI_ACTIONS_CHANNEL); progressDialog = new ProgressDialog(MainActivity.this, R.style.AlertDialogTheme); progressDialog.setCancelable(false); @@ -84,48 +85,48 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie protected void onDestroy() { super.onDestroy(); presenter.onDestroy(); - AppHelper.getObservable().unregister(this); + AppHelper.getObservable().unregister(this, MainObservable.UI_ACTIONS_CHANNEL); } @Override public void handleEvent(JSONObject object) { try { switch ((int) object.get("action")) { - case MessageActions.BOOTSTRAP_NOT_SPECIFIED: { + case UIActions.BOOTSTRAP_NOT_SPECIFIED: { runOnUiThread(() -> { progressDialog.dismiss(); Toast.makeText(this, "Bootstrap-нода не указана. Прерываю подключение к сети...", Toast.LENGTH_LONG).show(); }); break; } - case MessageActions.NETWORK_ERROR: { + case UIActions.NETWORK_ERROR: { runOnUiThread(() -> { progressDialog.dismiss(); Toast.makeText(this, "Ошибка сети. Возможно, нода недоступна, или у вас отсутствует Интернет.", Toast.LENGTH_LONG).show(); }); break; } - case MessageActions.BOOTSTRAP_SUCCESS: { + case UIActions.BOOTSTRAP_SUCCESS: { runOnUiThread(() -> { progressDialog.dismiss(); Toast.makeText(this, "Нода успешно запущена!", Toast.LENGTH_LONG).show(); }); break; } - case MessageActions.PORT_FORWARDING_ERROR: { + case UIActions.PORT_FORWARDING_ERROR: { runOnUiThread(() -> { Toast.makeText(this, "Проблемы с пробросом портов. Возможно, у вас не настроен uPnP.", Toast.LENGTH_LONG).show(); }); break; } - case MessageActions.BOOTSTRAP_ERROR: { + case UIActions.BOOTSTRAP_ERROR: { runOnUiThread(() -> { progressDialog.dismiss(); Toast.makeText(this, "Не удалось подключиться к бутстрап-ноде.", Toast.LENGTH_LONG).show(); }); break; } - case MessageActions.RELAY_CONNECTION_ERROR: { + case UIActions.RELAY_CONNECTION_ERROR: { runOnUiThread(() -> { progressDialog.dismiss(); Toast.makeText(this, "Не удалось подключиться к relay-ноде.", Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatFragment.java b/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatFragment.java deleted file mode 100644 index 6d304b5..0000000 --- a/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatFragment.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.chronosx88.influence.views.fragments; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.fragment.app.Fragment; -import io.github.chronosx88.influence.R; - -public class ChatFragment extends Fragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.chat_fragment, container, false); - } -} diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.java b/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.java new file mode 100644 index 0000000..b700ae9 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.java @@ -0,0 +1,72 @@ +package io.github.chronosx88.influence.views.fragments; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.json.JSONException; +import org.json.JSONObject; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; +import io.github.chronosx88.influence.R; +import io.github.chronosx88.influence.contracts.chatlist.ChatListPresenterContract; +import io.github.chronosx88.influence.contracts.chatlist.ChatListViewContract; +import io.github.chronosx88.influence.contracts.observer.Observer; +import io.github.chronosx88.influence.helpers.AppHelper; +import io.github.chronosx88.influence.helpers.ChatListAdapter; +import io.github.chronosx88.influence.helpers.UIActions; +import io.github.chronosx88.influence.observable.MainObservable; +import io.github.chronosx88.influence.presenters.ChatListPresenter; + +public class ChatListFragment extends Fragment implements ChatListViewContract, Observer { + private ChatListPresenterContract presenter; + private RecyclerView chatList; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + presenter = new ChatListPresenter(this); + AppHelper.getObservable().register(this, MainObservable.UI_ACTIONS_CHANNEL); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.chatlist_fragment, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + chatList = view.findViewById(R.id.chatlist_container); + presenter.updateChatList(); + } + + @Override + public void setRecycleAdapter(ChatListAdapter adapter) { + chatList.setAdapter(adapter); + } + + @Override + public void onResume() { + super.onResume(); + presenter.updateChatList(); + } + + @Override + public void handleEvent(JSONObject object) { + try { + switch (object.getInt("action")) { + case UIActions.NEW_CHAT: { + presenter.updateChatList(); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java b/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java index 8d038bf..b629abc 100644 --- a/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java +++ b/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java @@ -5,6 +5,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import io.github.chronosx88.influence.R; @@ -19,4 +21,10 @@ public class StartChatFragment extends Fragment { Bundle savedInstanceState) { return inflater.inflate(R.layout.start_chat_fragment, container, false); } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + // TODO + } } diff --git a/app/src/main/res/layout/chat_item.xml b/app/src/main/res/layout/chat_item.xml new file mode 100644 index 0000000..59e0ebf --- /dev/null +++ b/app/src/main/res/layout/chat_item.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/chat_fragment.xml b/app/src/main/res/layout/chatlist_fragment.xml similarity index 57% rename from app/src/main/res/layout/chat_fragment.xml rename to app/src/main/res/layout/chatlist_fragment.xml index b9416a2..3086578 100644 --- a/app/src/main/res/layout/chat_fragment.xml +++ b/app/src/main/res/layout/chatlist_fragment.xml @@ -3,11 +3,8 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent"/> \ No newline at end of file diff --git a/app/src/main/res/layout/start_chat_fragment.xml b/app/src/main/res/layout/start_chat_fragment.xml index ef5961a..8a58a8a 100644 --- a/app/src/main/res/layout/start_chat_fragment.xml +++ b/app/src/main/res/layout/start_chat_fragment.xml @@ -1,14 +1,18 @@ - + android:hint="Peer ID"/> +