mirror of
https://github.com/ChronosX88/Influence-P2P.git
synced 2024-11-21 23:02:18 +00:00
Made offline chat send request
This commit is contained in:
parent
6ee7223fcd
commit
0bca327949
@ -6,10 +6,19 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import net.tomp2p.dht.FutureGet;
|
||||
import net.tomp2p.dht.FuturePut;
|
||||
import net.tomp2p.dht.PeerDHT;
|
||||
import net.tomp2p.futures.FuturePing;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.Number640;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.storage.Data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.github.chronosx88.influence.contracts.observer.NetworkObserver;
|
||||
import io.github.chronosx88.influence.helpers.actions.NetworkActions;
|
||||
@ -19,12 +28,11 @@ import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
|
||||
|
||||
public class NetworkHandler implements NetworkObserver {
|
||||
private final static String LOG_TAG = "NetworkHandler";
|
||||
private Gson gson;
|
||||
private PeerDHT peerDHT;
|
||||
private static Gson gson = new Gson();
|
||||
private static PeerDHT peerDHT = AppHelper.getPeerDHT();
|
||||
private static KeyPairManager keyPairManager = new KeyPairManager();
|
||||
|
||||
public NetworkHandler() {
|
||||
gson = new Gson();
|
||||
peerDHT = AppHelper.getPeerDHT();
|
||||
AppHelper.getObservable().register(this);
|
||||
}
|
||||
|
||||
@ -45,9 +53,11 @@ public class NetworkHandler implements NetworkObserver {
|
||||
case NetworkActions.SUCCESSFULL_CREATE_CHAT: {
|
||||
NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class);
|
||||
createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress());
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("action", UIActions.NEW_CHAT);
|
||||
AppHelper.getObservable().notifyUIObservers(jsonObject);
|
||||
ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_CHAT);
|
||||
peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats"))
|
||||
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -59,7 +69,7 @@ public class NetworkHandler implements NetworkObserver {
|
||||
return jsonObject.get("action").getAsInt();
|
||||
}
|
||||
|
||||
private void createChatEntry(String chatID, String name, PeerAddress peerAddress) {
|
||||
private static void createChatEntry(String chatID, String name, PeerAddress peerAddress) {
|
||||
List<ChatEntity> chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(chatID);
|
||||
if (chatEntities.size() > 0) {
|
||||
Log.e(LOG_TAG, "Failed to create chat " + chatID + " because chat exists!");
|
||||
@ -74,4 +84,96 @@ public class NetworkHandler implements NetworkObserver {
|
||||
newChatRequestMessage.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT);
|
||||
AppHelper.getPeerDHT().peer().sendDirect(chatStarterAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly();
|
||||
}
|
||||
|
||||
public static void handlePendingChats() {
|
||||
FutureGet futureGetPendingChats = peerDHT
|
||||
.get(Number160.createHash(AppHelper.getPeerID() + "_pendingChats"))
|
||||
.all()
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
if(!futureGetPendingChats.isEmpty()) {
|
||||
for(Map.Entry<Number640, Data> entry : futureGetPendingChats.dataMap().entrySet()) {
|
||||
NewChatRequestMessage newChatRequestMessage = null;
|
||||
try {
|
||||
newChatRequestMessage = gson.fromJson((String) entry.getValue().object(), NewChatRequestMessage.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
createChatEntry(
|
||||
newChatRequestMessage.getChatID(),
|
||||
newChatRequestMessage.getSenderID(),
|
||||
newChatRequestMessage.getSenderPeerAddress()
|
||||
);
|
||||
|
||||
FuturePing ping = peerDHT
|
||||
.peer()
|
||||
.ping()
|
||||
.peerAddress(newChatRequestMessage.getSenderPeerAddress())
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
NewChatRequestMessage newChatRequestReply = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress());
|
||||
newChatRequestReply.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT);
|
||||
if(ping.isSuccess()) {
|
||||
peerDHT
|
||||
.peer()
|
||||
.sendDirect(newChatRequestMessage.getSenderPeerAddress())
|
||||
.object(gson.toJson(newChatRequestReply))
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
} else {
|
||||
try {
|
||||
FuturePut put = peerDHT.put(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingAcceptedChats"))
|
||||
.data(Number160.createHash(UUID.randomUUID().toString()), new Data(gson.toJson(newChatRequestReply))
|
||||
.protectEntry(keyPairManager.openMainKeyPair()))
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
if(put.isSuccess()) {
|
||||
Log.i(LOG_TAG, "# Successfully put message SUCCESSFULLY_CREATE_CHAT in " + newChatRequestMessage.getSenderID() + "_pendingAcceptedChats, because receiver is offline.");
|
||||
} else {
|
||||
Log.e(LOG_TAG, "# Failed to put message SUCCESSFULLY_CREATE_CHAT in " + newChatRequestMessage.getSenderID() + "_pendingAcceptedChats. Reason: " + put.failedReason());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
ObservableUtils.notifyUI(UIActions.NEW_CHAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void handlePendingAcceptedChats() {
|
||||
FutureGet futureGetPendingAcceptedChats = peerDHT
|
||||
.get(Number160.createHash(AppHelper.getPeerID() + "_pendingAcceptedChats"))
|
||||
.all()
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
if(!futureGetPendingAcceptedChats.isEmpty()) {
|
||||
for(Map.Entry<Number640, Data> entry : futureGetPendingAcceptedChats.dataMap().entrySet()) {
|
||||
NewChatRequestMessage newChatRequestMessage = null;
|
||||
|
||||
try {
|
||||
newChatRequestMessage = gson.fromJson((String) entry.getValue().object(), NewChatRequestMessage.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats"))
|
||||
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
|
||||
createChatEntry(
|
||||
newChatRequestMessage.getChatID(),
|
||||
newChatRequestMessage.getSenderID(),
|
||||
newChatRequestMessage.getSenderPeerAddress()
|
||||
);
|
||||
ObservableUtils.notifyUI(UIActions.NEW_CHAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package io.github.chronosx88.influence.helpers;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class ObservableUtils {
|
||||
public static void notifyUI(int action) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("action", action);
|
||||
AppHelper.getObservable().notifyUIObservers(jsonObject);
|
||||
}
|
||||
}
|
@ -10,4 +10,5 @@ public class UIActions {
|
||||
public static final int NEW_CHAT = 0x6;
|
||||
public static final int PEER_NOT_EXIST = 0x7;
|
||||
public static final int SUCCESSFULL_CREATE_CHAT = 0x8;
|
||||
public static final int SUCCESSFULL_CREATE_OFFLINE_CHAT = 0x9;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import io.github.chronosx88.influence.contracts.main.MainLogicContract;
|
||||
import io.github.chronosx88.influence.helpers.AppHelper;
|
||||
import io.github.chronosx88.influence.helpers.DSAKey;
|
||||
import io.github.chronosx88.influence.helpers.KeyPairManager;
|
||||
import io.github.chronosx88.influence.helpers.NetworkHandler;
|
||||
import io.github.chronosx88.influence.helpers.StorageMVStore;
|
||||
import io.github.chronosx88.influence.helpers.actions.UIActions;
|
||||
import io.github.chronosx88.influence.models.PublicUserProfile;
|
||||
@ -138,6 +139,8 @@ public class MainLogic implements MainLogicContract {
|
||||
setReceiveHandler();
|
||||
gson = new Gson();
|
||||
publicProfileToDHT();
|
||||
NetworkHandler.handlePendingChats();
|
||||
NetworkHandler.handlePendingAcceptedChats();
|
||||
replication = new AutoReplication(peerDHT.peer()).start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -19,6 +19,7 @@ import java.util.UUID;
|
||||
import io.github.chronosx88.influence.contracts.startchat.StartChatLogicContract;
|
||||
import io.github.chronosx88.influence.helpers.AppHelper;
|
||||
import io.github.chronosx88.influence.helpers.KeyPairManager;
|
||||
import io.github.chronosx88.influence.helpers.ObservableUtils;
|
||||
import io.github.chronosx88.influence.helpers.actions.UIActions;
|
||||
import io.github.chronosx88.influence.models.NewChatRequestMessage;
|
||||
import io.github.chronosx88.influence.models.PublicUserProfile;
|
||||
@ -54,14 +55,17 @@ public class StartChatLogic implements StartChatLogicContract {
|
||||
try {
|
||||
NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress());
|
||||
FuturePut futurePut = peerDHT
|
||||
.put(Number160.createHash(peerID))
|
||||
.data(Number160.createHash(UUID.randomUUID().toString()), new Data(gson.toJson(newChatRequestMessage))
|
||||
.protectEntry(keyPairManager.openMainKeyPair())).start().awaitUninterruptibly();
|
||||
.put(Number160.createHash(peerID + "_pendingChats"))
|
||||
.data(Number160.createHash(newChatRequestMessage.getChatID()), new Data(gson.toJson(newChatRequestMessage))
|
||||
.protectEntry(keyPairManager.openMainKeyPair()))
|
||||
.start()
|
||||
.awaitUninterruptibly();
|
||||
if(futurePut.isSuccess()) {
|
||||
Log.i(LOG_TAG, "# Create new offline chat request is successful! ChatID: " + newChatRequestMessage.getChatID());
|
||||
} else {
|
||||
Log.e(LOG_TAG, "# Failed to create chat: " + futurePut.failedReason());
|
||||
}
|
||||
ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -2,18 +2,18 @@ package io.github.chronosx88.influence.presenters;
|
||||
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.tomp2p.dht.FutureRemove;
|
||||
import net.tomp2p.peers.Number160;
|
||||
|
||||
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.contracts.observer.Observer;
|
||||
import io.github.chronosx88.influence.helpers.AppHelper;
|
||||
import io.github.chronosx88.influence.helpers.ChatListAdapter;
|
||||
import io.github.chronosx88.influence.helpers.actions.UIActions;
|
||||
import io.github.chronosx88.influence.logic.ChatListLogic;
|
||||
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
|
||||
|
||||
public class ChatListPresenter implements ChatListPresenterContract, Observer {
|
||||
public class ChatListPresenter implements ChatListPresenterContract {
|
||||
private ChatListViewContract view;
|
||||
private ChatListLogicContract logic;
|
||||
private ChatListAdapter chatListAdapter;
|
||||
@ -23,7 +23,6 @@ public class ChatListPresenter implements ChatListPresenterContract, Observer {
|
||||
chatListAdapter = new ChatListAdapter();
|
||||
this.logic = new ChatListLogic();
|
||||
this.view.setRecycleAdapter(chatListAdapter);
|
||||
AppHelper.getObservable().register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,19 +40,13 @@ public class ChatListPresenter implements ChatListPresenterContract, Observer {
|
||||
switch(item.getItemId()) {
|
||||
case 0: {
|
||||
if(chatListAdapter.onClickPosition != -1) {
|
||||
AppHelper.getChatDB().chatDao().deleteChat(chatListAdapter.getItem(chatListAdapter.onClickPosition).chatID);
|
||||
view.updateChatList(chatListAdapter, logic.loadAllChats());
|
||||
new Thread(() -> {
|
||||
ChatEntity chat = chatListAdapter.getItem(chatListAdapter.onClickPosition);
|
||||
AppHelper.getChatDB().chatDao().deleteChat(chat.chatID);
|
||||
view.updateChatList(chatListAdapter, logic.loadAllChats());
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(JsonObject object) {
|
||||
switch (object.get("action").getAsInt()) {
|
||||
case UIActions.NEW_CHAT: {
|
||||
updateChatList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ public class StartChatPresenter implements StartChatPresenterContract, Observer
|
||||
|
||||
@Override
|
||||
public void startChatWithPeer(String peerID) {
|
||||
view.showProgressDialog(true);
|
||||
logic.sendStartChatMessage(peerID);
|
||||
}
|
||||
|
||||
@ -39,6 +40,11 @@ public class StartChatPresenter implements StartChatPresenterContract, Observer
|
||||
view.showMessage("Чат успешно создан");
|
||||
break;
|
||||
}
|
||||
case UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT: {
|
||||
view.showProgressDialog(false);
|
||||
view.showMessage("В сеть отправлен запрос на создание чата, так как получатель не в сети.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.chronosx88.influence.views.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -28,11 +29,13 @@ import io.github.chronosx88.influence.presenters.ChatListPresenter;
|
||||
public class ChatListFragment extends Fragment implements ChatListViewContract, Observer {
|
||||
private ChatListPresenterContract presenter;
|
||||
private RecyclerView chatList;
|
||||
private Handler mainThreadHandler;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
AppHelper.getObservable().register(this);
|
||||
this.mainThreadHandler = new Handler(getContext().getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,7 +76,7 @@ public class ChatListFragment extends Fragment implements ChatListViewContract,
|
||||
|
||||
@Override
|
||||
public void updateChatList(ChatListAdapter adapter, List<ChatEntity> chats) {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
mainThreadHandler.post(() -> {
|
||||
adapter.setChatList(chats);
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
|
@ -52,11 +52,14 @@ public class StartChatFragment extends Fragment implements StartChatViewContract
|
||||
|
||||
@Override
|
||||
public void showProgressDialog(boolean enabled) {
|
||||
if(enabled) {
|
||||
progressDialog.show();
|
||||
} else {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
// TODO: make run on mainHandlerThread
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
if(enabled) {
|
||||
progressDialog.show();
|
||||
} else {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: clear text input
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/textInputPeerID"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="346dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:hint="Peer ID"/>
|
||||
|
Loading…
Reference in New Issue
Block a user