diff --git a/app/build.gradle b/app/build.gradle
index 9e4d154..f309182 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -42,6 +42,7 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
implementation "androidx.room:room-runtime:2.1.0-alpha04"
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
implementation 'org.slf4j:slf4j-log4j12:1.7.26'
implementation('net.tomp2p:tomp2p-all:5.0-Beta8') {
@@ -58,7 +59,12 @@ dependencies {
implementation 'com.esotericsoftware:kryo:5.0.0-RC1'
implementation 'com.github.instacart.truetime-android:library:3.4'
+ implementation 'org.igniterealtime.smack:smack-core:4.3.3'
+ implementation 'org.igniterealtime.smack:smack-tcp:4.3.3'
+ implementation 'org.igniterealtime.smack:smack-android:4.3.3'
+ implementation 'org.igniterealtime.smack:smack-extensions:4.3.3'
+
}
repositories {
mavenCentral()
-}
\ No newline at end of file
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ed46495..9f8ee82 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,6 +13,13 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
+
+
+
+
diff --git a/app/src/main/java/io/github/chronosx88/influence/LoginCredentials.java b/app/src/main/java/io/github/chronosx88/influence/LoginCredentials.java
new file mode 100644
index 0000000..e96f075
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/LoginCredentials.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 ChronosX88
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github.chronosx88.influence;
+
+public class LoginCredentials {
+ String username = "";
+ String password = "";
+ String jabberHost = "";
+}
diff --git a/app/src/main/java/io/github/chronosx88/influence/XMPPConnection.java b/app/src/main/java/io/github/chronosx88/influence/XMPPConnection.java
new file mode 100644
index 0000000..6bad8f7
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/XMPPConnection.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2019 ChronosX88
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github.chronosx88.influence;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import androidx.preference.PreferenceManager;
+
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.ConnectionListener;
+import org.jivesoftware.smack.ReconnectionManager;
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.chat2.Chat;
+import org.jivesoftware.smack.chat2.ChatManager;
+import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
+import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
+import org.jxmpp.jid.EntityBareJid;
+import org.jxmpp.jid.impl.JidCreate;
+import org.jxmpp.stringprep.XmppStringprepException;
+
+import java.io.IOException;
+
+import io.github.chronosx88.influence.helpers.AppHelper;
+import io.github.chronosx88.influence.helpers.NetworkHandler;
+
+public class XMPPConnection implements ConnectionListener {
+ private final static String LOG_TAG = "XMPPConnection";
+ private LoginCredentials credentials = new LoginCredentials();
+ private XMPPTCPConnection connection = null;
+ private SharedPreferences prefs;
+ private NetworkHandler networkHandler;
+ private BroadcastReceiver sendMessageReceiver = null;
+ private Context context;
+
+ public enum ConnectionState {
+ CONNECTED,
+ AUTHENTICATED,
+ CONNECTING,
+ DISCONNECTING,
+ DISCONNECTED
+ }
+
+ public enum SessionState {
+ LOGGED_IN,
+ LOGGED_OUT
+ }
+
+ public XMPPConnection(Context context) {
+ String jid = prefs.getString("jid", null);
+ String password = prefs.getString("pass", null);
+ if(jid != null && password != null) {
+ String username = jid.split("@")[0];
+ String jabberHost = jid.split("@")[1];
+ credentials.username = username;
+ credentials.jabberHost = jabberHost;
+ credentials.password = password;
+ }
+ networkHandler = new NetworkHandler(context);
+ prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ this.context = context;
+ }
+
+ public void connect() throws XMPPException, SmackException, IOException {
+ if(connection == null) {
+ XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
+ .setXmppDomain(credentials.jabberHost)
+ .setHost(credentials.jabberHost)
+ .setResource(AppHelper.APP_NAME)
+ .setKeystoreType(null)
+ .setSecurityMode(ConnectionConfiguration.SecurityMode.required)
+ .setCompressionEnabled(true)
+ .build();
+
+ setupSendMessageReceiver();
+
+ connection = new XMPPTCPConnection(conf);
+ connection.addConnectionListener(this);
+ try {
+ connection.connect();
+ connection.login(credentials.username, credentials.password);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ ChatManager.getInstanceFor(connection).addIncomingListener(networkHandler);
+ ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
+ ReconnectionManager.setEnabledPerDefault(true);
+ reconnectionManager.enableAutomaticReconnection();
+ }
+ }
+
+ public void disconnect() {
+ prefs.edit().putBoolean("logged_in", false).apply();
+ if(connection != null) {
+ connection.disconnect();
+ connection = null;
+ }
+ }
+
+ @Override
+ public void connected(org.jivesoftware.smack.XMPPConnection connection) {
+ XMPPConnectionService.connectionState = ConnectionState.CONNECTED;
+ }
+
+ @Override
+ public void authenticated(org.jivesoftware.smack.XMPPConnection connection, boolean resumed) {
+ XMPPConnectionService.sessionState = SessionState.LOGGED_IN;
+ prefs.edit().putBoolean("logged_in", true).apply();
+ }
+
+ @Override
+ public void connectionClosed() {
+ XMPPConnectionService.connectionState = ConnectionState.DISCONNECTED;
+ XMPPConnectionService.sessionState = SessionState.LOGGED_OUT;
+ prefs.edit().putBoolean("logged_in", false).apply();
+ }
+
+ @Override
+ public void connectionClosedOnError(Exception e) {
+ XMPPConnectionService.connectionState = ConnectionState.DISCONNECTED;
+ XMPPConnectionService.sessionState = SessionState.LOGGED_OUT;
+ prefs.edit().putBoolean("logged_in", false).apply();
+ Log.e(LOG_TAG, "Connection closed, exception occurred");
+ e.printStackTrace();
+ }
+
+ private void setupSendMessageReceiver() {
+ sendMessageReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case XMPPConnectionService.INTENT_SEND_MESSAGE: {
+ String recipientJid = intent.getStringExtra(XMPPConnectionService.MESSAGE_RECIPIENT);
+ String messageText = intent.getStringExtra(XMPPConnectionService.MESSAGE_BODY);
+ sendMessage(recipientJid, messageText);
+ break;
+ }
+ }
+ }
+ };
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(XMPPConnectionService.INTENT_SEND_MESSAGE);
+ context.registerReceiver(sendMessageReceiver, intentFilter);
+ }
+
+ private void sendMessage(String recipientJid, String messageText) {
+ EntityBareJid jid = null;
+ try {
+ jid = JidCreate.entityBareFrom(recipientJid);
+ } catch (XmppStringprepException e) {
+ e.printStackTrace();
+ }
+ Chat chat = ChatManager.getInstanceFor(connection).chatWith(jid);
+ try {
+ Message message = new Message(jid, Message.Type.chat);
+ message.setBody(messageText);
+ chat.send(message);
+ } catch (SmackException.NotConnectedException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public XMPPTCPConnection getConnection() {
+ return connection;
+ }
+}
diff --git a/app/src/main/java/io/github/chronosx88/influence/XMPPConnectionService.java b/app/src/main/java/io/github/chronosx88/influence/XMPPConnectionService.java
new file mode 100644
index 0000000..5e9b00b
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/XMPPConnectionService.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 ChronosX88
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github.chronosx88.influence;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+
+import org.jivesoftware.smack.SmackException;
+import org.jivesoftware.smack.XMPPException;
+
+import java.io.IOException;
+
+public class XMPPConnectionService extends Service {
+ public static final String INTENT_NEW_MESSAGE = "io.github.chronosx88.intents.new_message";
+ public static final String INTENT_SEND_MESSAGE = "io.github.chronosx88.intents.send_message";
+ public static final String INTENT_AUTHENTICATED = "io.github.chronosx88.intents.authenticated";
+ public static final String INTENT_AUTHENTICATION_FAILED = "io.github.chronosx88.intents.authentication_failed";
+
+ public static final String MESSAGE_CHATID = "chat_jid";
+ public static final String MESSAGE_ID = "message_id";
+ public static final String MESSAGE_BODY = "message_body";
+ public static final String MESSAGE_RECIPIENT = "message_recipient";
+
+ public static XMPPConnection.ConnectionState connectionState = XMPPConnection.ConnectionState.DISCONNECTED;
+ public static XMPPConnection.SessionState sessionState = XMPPConnection.SessionState.LOGGED_OUT;
+
+ private Thread thread;
+ private Handler threadHandler;
+ private boolean isThreadAlive = false;
+ private XMPPConnection connection;
+ private Context context;
+
+ public XMPPConnectionService(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) { return null; }
+
+ public void onServiceStart() {
+ if(!isThreadAlive)
+ {
+ isThreadAlive = true;
+ if(thread == null || !thread.isAlive()) {
+ thread = new Thread(() -> {
+ Looper.prepare();
+ threadHandler = new Handler();
+ createConnection();
+ Looper.loop();
+ });
+ thread.start();
+ }
+ }
+ }
+
+ private void onServiceStop() {
+ isThreadAlive = false;
+ threadHandler.post(() -> {
+ if(connection != null) {
+ connection.disconnect();
+ }
+ });
+ }
+
+ private void createConnection() {
+ if(connection == null) {
+ connection = new XMPPConnection(this);
+ }
+ try {
+ connection.connect();
+ } catch (IOException | SmackException | XMPPException e) {
+ Intent intent = new Intent(INTENT_AUTHENTICATION_FAILED);
+
+ e.printStackTrace();
+ //Stop the service all together.
+ stopSelf();
+ }
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ onServiceStart();
+ return Service.START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ onServiceStop();
+ }
+}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/CoreContracts.kt b/app/src/main/java/io/github/chronosx88/influence/contracts/CoreContracts.kt
index 99d3a76..cfef030 100644
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/CoreContracts.kt
+++ b/app/src/main/java/io/github/chronosx88/influence/contracts/CoreContracts.kt
@@ -9,6 +9,10 @@ import io.github.chronosx88.influence.models.roomEntities.MessageEntity
interface CoreContracts {
+ interface ViewWithLoadingScreen {
+ fun loadingScreen(state: Boolean);
+ }
+
// -----ChatList-----
interface IChatListLogicContract {
@@ -27,21 +31,6 @@ interface CoreContracts {
fun updateChatList(adapter: ChatListAdapter, chats: List)
}
- // -----StartChat-----
-
- interface IStartChatLogicContract {
- fun sendStartChatMessage(peerID: String)
- }
-
- interface IStartChatPresenterContract {
- fun startChatWithPeer(peerID: String)
- }
-
- interface IStartChatViewContract {
- fun showMessage(message: String)
- fun showProgressDialog(enabled: Boolean)
- }
-
// -----MainActivity-----
interface IMainLogicContract {
@@ -94,4 +83,7 @@ interface CoreContracts {
fun showMessage(message: String)
fun refreshScreen()
}
+
+ // -----LoginActivity-----
+ interface ILoginViewContract : ViewWithLoadingScreen
}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/AppHelper.java b/app/src/main/java/io/github/chronosx88/influence/helpers/AppHelper.java
index ab6797f..ceb7ea0 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/AppHelper.java
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/AppHelper.java
@@ -3,6 +3,7 @@ package io.github.chronosx88.influence.helpers;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import net.tomp2p.dht.PeerDHT;
@@ -22,11 +23,10 @@ import io.github.chronosx88.influence.observable.MainObservable;
public class AppHelper extends MultiDexApplication {
private static Application instance;
private static MainObservable observable;
- private static String peerID;
- private static PeerDHT peerDHT;
+ public final static String APP_NAME = "Influence";
+
+ private static String jid;
private static RoomHelper chatDB;
- private static NetworkHandler networkHandler;
- private static String username = "";
private static SharedPreferences preferences;
@Override
@@ -37,7 +37,7 @@ public class AppHelper extends MultiDexApplication {
chatDB = Room.databaseBuilder(getApplicationContext(), RoomHelper.class, "chatDB")
.allowMainThreadQueries()
.build();
- preferences = getApplicationContext().getSharedPreferences("io.github.chronosx88.influence_preferences", MODE_PRIVATE);
+ preferences = PreferenceManager.getDefaultSharedPreferences(instance);
new Thread(() -> {
try {
TrueTime.build().initialize();
@@ -47,28 +47,18 @@ public class AppHelper extends MultiDexApplication {
}).start();
}
- public static void storePeerID(String peerID1) { peerID = peerID1; }
-
- public static void updateUsername(String username1) { username = username1; }
-
- public static void storePeerDHT(PeerDHT peerDHT1) { peerDHT = peerDHT1; }
-
public static Context getContext() {
return instance.getApplicationContext();
}
public static MainObservable getObservable() { return observable; }
- public static String getPeerID() { return peerID; }
+ public static String getJid() { return jid; }
- public static String getUsername() { return username; }
-
- public static PeerDHT getPeerDHT() { return peerDHT; }
+ public static void setJid(String jid1) { jid = jid1; }
public static RoomHelper getChatDB() { return chatDB; }
- public static void initNetworkHandler() { networkHandler = new NetworkHandler(); }
-
public static SharedPreferences getPreferences() {
return preferences;
}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt b/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt
deleted file mode 100644
index ef5b4b4..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-package io.github.chronosx88.influence.helpers
-
-import android.util.Log
-import com.sleepycat.bind.EntryBinding
-import com.sleepycat.je.DatabaseEntry
-import io.netty.buffer.Unpooled
-import net.tomp2p.connection.SignatureFactory
-import net.tomp2p.storage.Data
-import java.io.*
-import java.nio.ByteBuffer
-import java.security.InvalidKeyException
-import java.security.SignatureException
-
-
-class DataSerializer(private val signatureFactory: SignatureFactory) : EntryBinding, Serializable {
- private val LOG_TAG = "DataSerializer"
-
- override fun entryToObject(databaseEntry: DatabaseEntry): Data? {
- if (databaseEntry.data == null) {
- return null
- }
- val dataInput = ByteArrayInputStream(databaseEntry.data)
- var buf = Unpooled.buffer()
- var data: Data? = null
- while (data == null) {
- buf.writeByte(dataInput.read())
- data = Data.decodeHeader(buf, signatureFactory)
- }
- val len = data.length()
- var me = ByteArray(len)
- try {
- dataInput.read(me)
- } catch (e: IOException) {
- e.printStackTrace()
- }
-
- buf = Unpooled.wrappedBuffer(me)
- var retVal = data.decodeBuffer(buf)
- if (!retVal) {
- Log.e(LOG_TAG, "# ERROR: Data could not be deserialized!")
- }
- if (data.isSigned) {
- me = ByteArray(signatureFactory.signatureSize())
- dataInput.read(me)
- buf = Unpooled.wrappedBuffer(me)
- }
- retVal = data.decodeDone(buf, signatureFactory);
- if(!retVal) {
- throw IOException("Signature could not be read!")
- }
- return data
- }
-
- override fun objectToEntry(data: Data, databaseEntry: DatabaseEntry) {
- val out = ByteArrayOutputStream()
- val acb = Unpooled.buffer()
- // store data to disk
- // header first
- data.encodeHeader(acb, signatureFactory)
- writeData(out, acb.nioBuffers())
- acb.skipBytes(acb.writerIndex())
- // next data - no need to copy to another buffer, just take the data
- // from memory
- writeData(out, data.toByteBuffers())
- // rest
- try {
- data.encodeDone(acb, signatureFactory)
- writeData(out, acb.nioBuffers())
- } catch (e: InvalidKeyException) {
- throw IOException(e)
- } catch (e: SignatureException) {
- throw IOException(e)
- }
- out.flush()
- databaseEntry.data = out.toByteArray()
- out.close()
- }
-
- @Throws(IOException::class)
- private fun writeData(out: OutputStream, nioBuffers: Array) {
- val length = nioBuffers.size
- for (i in 0 until length) {
- val remaining = nioBuffers[i].remaining()
- if (nioBuffers[i].hasArray()) {
- out.write(nioBuffers[i].array(), nioBuffers[i].arrayOffset(), remaining)
- } else {
- val me = ByteArray(remaining)
- nioBuffers[i].get(me)
- out.write(me)
- }
- }
- }
-
- companion object {
- private const val serialVersionUID = 1428836065493792295L
- }
-}
-
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/JVMShutdownHook.java b/app/src/main/java/io/github/chronosx88/influence/helpers/JVMShutdownHook.java
deleted file mode 100644
index 4e5c7bd..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/JVMShutdownHook.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.github.chronosx88.influence.helpers;
-
-import android.util.Log;
-
-import net.tomp2p.dht.Storage;
-
-public class JVMShutdownHook extends Thread {
-
- Storage storage;
-
- public JVMShutdownHook(Storage storage) {
- this.storage = storage;
- }
-
- @Override
- public void run() {
- super.run();
- Log.d("JVMShutdownHook", "# Closing storage...");
- storage.close();
- Log.d("JVMShutdownHook", "# Storage is closed");
- }
-
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/LocalDBWrapper.java b/app/src/main/java/io/github/chronosx88/influence/helpers/LocalDBWrapper.java
index 8b5a035..1347b63 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/LocalDBWrapper.java
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/LocalDBWrapper.java
@@ -12,39 +12,22 @@ public class LocalDBWrapper {
private static final String LOG_TAG = "LocalDBWrapper";
private static RoomHelper dbInstance = AppHelper.getChatDB();
- /**
- * Create a chat entry in the local database.
- * @param chatID Chat ID
- * @param name Chat name
- * @param metadataRef Reference to general chat metadata (key in DHT)
- * @param membersRef Reference to member list
- */
- public static void createChatEntry(String chatID, String name, String metadataRef, String membersRef, int chunkID) {
- dbInstance.chatDao().addChat(new ChatEntity(chatID, name, metadataRef, membersRef, new ArrayList<>(), chunkID));
+ public static void createChatEntry(String jid, String chatName) {
+ dbInstance.chatDao().addChat(new ChatEntity(jid, chatName));
}
- /**
- * Creating a message entry in the local database
- * @param type Message type
- * @param chatID ID of the chat in which need to create a message
- * @param username Sender username
- * @param senderID Sender peer ID
- * @param timestamp Message timestamp
- * @param text Message text
- * @return New message
- */
- public static MessageEntity createMessageEntry(int type, String messageID, String chatID, String username, String senderID, long timestamp, String text, boolean isSent, boolean isRead) {
- List chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(chatID);
+ public static long createMessageEntry(String jid, String senderJid, long timestamp, String text, boolean isSent, boolean isRead) {
+ List chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(jid);
if(chatEntities.size() < 1) {
- Log.e(LOG_TAG, "Failed to create message entry because chat " + chatID + " doesn't exists!");
- return null;
+ Log.e(LOG_TAG, "Failed to create message entry because chat " + jid + " doesn't exists!");
+ return -1;
}
- MessageEntity message = new MessageEntity(type, messageID, chatID, senderID, username, timestamp, text, isSent, isRead);
- dbInstance.messageDao().insertMessage(message);
- return message;
+ MessageEntity message = new MessageEntity(jid, senderJid, timestamp, text, isSent, isRead);
+ long index = dbInstance.messageDao().insertMessage(message);
+ return index;
}
- public static MessageEntity getMessageByID(String messageID) {
+ public static MessageEntity getMessageByID(long messageID) {
List messages = dbInstance.messageDao().getMessageByID(messageID);
if(messages.isEmpty()) {
return null;
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java
index b6d5224..9512a6f 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java
@@ -1,78 +1,35 @@
package io.github.chronosx88.influence.helpers;
-import com.google.gson.Gson;
+import android.content.Context;
+import android.content.Intent;
-import net.tomp2p.dht.PeerDHT;
-import net.tomp2p.peers.Number640;
-import net.tomp2p.storage.Data;
+import com.instacart.library.truetime.TrueTime;
-import java.io.IOException;
-import java.util.Map;
-import java.util.UUID;
+import org.jivesoftware.smack.chat2.Chat;
+import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
+import org.jivesoftware.smack.packet.Message;
+import org.jxmpp.jid.EntityBareJid;
-import io.github.chronosx88.influence.contracts.observer.INetworkObserver;
-import io.github.chronosx88.influence.helpers.actions.UIActions;
-import io.github.chronosx88.influence.models.ChatMember;
-import io.github.chronosx88.influence.models.JoinChatMessage;
-import io.github.chronosx88.influence.models.NewChatRequestMessage;
+import io.github.chronosx88.influence.XMPPConnectionService;
-public class NetworkHandler implements INetworkObserver {
+public class NetworkHandler implements IncomingChatMessageListener {
private final static String LOG_TAG = "NetworkHandler";
- private static Gson gson = new Gson();
- private static PeerDHT peerDHT = AppHelper.getPeerDHT();
- private static KeyPairManager keyPairManager = new KeyPairManager();
+ private Context context;
- public NetworkHandler() {
- AppHelper.getObservable().register(this);
+ public NetworkHandler(Context context) {
+ this.context = context;
}
@Override
- public void handleEvent(Object object) {
- // Empty
- }
-
-
-
- public static void handlePendingChatRequests() {
- Map pendingChats = P2PUtils.get(AppHelper.getPeerID() + "_pendingChats");
- if (pendingChats != null) {
- for (Map.Entry entry : pendingChats.entrySet()) {
- NewChatRequestMessage newChatRequestMessage = null;
- try {
- newChatRequestMessage = gson.fromJson((String) entry.getValue().object(), NewChatRequestMessage.class);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- ChatMember chatMember = new ChatMember(AppHelper.getPeerID(), AppHelper.getPeerID());
- Data putData = null;
- try {
- putData = new Data(gson.toJson(chatMember)).protectEntry(keyPairManager.openMainKeyPair());
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- P2PUtils.put(newChatRequestMessage.getChatID() + "_members", AppHelper.getPeerID(), putData);
-
- LocalDBWrapper.createChatEntry(
- newChatRequestMessage.getChatID(),
- newChatRequestMessage.getUsername(),
- newChatRequestMessage.getChatID() + "_metadata",
- newChatRequestMessage.getChatID() + "_members",
- newChatRequestMessage.getChunkID()
- );
-
- P2PUtils.remove(AppHelper.getPeerID() + "_pendingChats", newChatRequestMessage.getChatID());
- String messageID = UUID.randomUUID().toString();
- try {
- P2PUtils.put(newChatRequestMessage.getChatID() + "_messages", messageID, new Data(gson.toJson(new JoinChatMessage(AppHelper.getPeerID(), AppHelper.getUsername() == null ? AppHelper.getPeerID() : AppHelper.getUsername(), newChatRequestMessage.getChatID(), System.currentTimeMillis()))).protectEntry(keyPairManager.openMainKeyPair()));
- } catch (IOException e) {
- e.printStackTrace();
- }
- ObservableUtils.notifyUI(UIActions.SUCCESSFUL_CREATE_CHAT);
- }
+ public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
+ if(LocalDBWrapper.getChatByChatID(from.asEntityBareJidString()) == null) {
+ LocalDBWrapper.createChatEntry(chat.getXmppAddressOfChatPartner().asUnescapedString(), chat.getXmppAddressOfChatPartner().asBareJid().asUnescapedString());
}
+ long messageID = LocalDBWrapper.createMessageEntry(chat.getXmppAddressOfChatPartner().asUnescapedString(), from.asUnescapedString(), TrueTime.now().getTime(), message.getBody(), true, false);
+ Intent intent = new Intent(XMPPConnectionService.INTENT_NEW_MESSAGE);
+ intent.setPackage(context.getPackageName());
+ intent.putExtra(XMPPConnectionService.MESSAGE_CHATID, chat.getXmppAddressOfChatPartner().toString());
+ intent.putExtra(XMPPConnectionService.MESSAGE_ID, messageID);
+ context.sendBroadcast(intent);
}
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java b/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java
deleted file mode 100644
index 0d914e1..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package io.github.chronosx88.influence.helpers;
-
-import com.google.gson.Gson;
-
-import net.tomp2p.dht.FutureGet;
-import net.tomp2p.dht.FuturePut;
-import net.tomp2p.dht.FutureRemove;
-import net.tomp2p.dht.PeerDHT;
-import net.tomp2p.futures.FutureDirect;
-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.security.KeyPair;
-import java.util.Map;
-
-public class P2PUtils {
- private static Gson gson = new Gson();
- private static PeerDHT peerDHT = AppHelper.getPeerDHT();
-
- public static boolean put(String locationKey, String contentKey, Data data) {
- FuturePut futurePut = peerDHT
- .put(Number160.createHash(locationKey))
- .data(contentKey == null ? Number160.ZERO : Number160.createHash(contentKey), data)
- .start()
- .awaitUninterruptibly();
- return futurePut.isSuccess();
- }
-
- public static boolean put(String locationKey, String contentKey, Data data, KeyPair keyPair) {
- FuturePut futurePut = peerDHT
- .put(Number160.createHash(locationKey))
- .data(contentKey == null ? Number160.ZERO : Number160.createHash(contentKey), data)
- .keyPair(keyPair)
- .start()
- .awaitUninterruptibly();
- return futurePut.isSuccess();
- }
-
- public static Map get(String locationKey) {
- FutureGet futureGet = peerDHT
- .get(Number160.createHash(locationKey))
- .all()
- .start()
- .awaitUninterruptibly();
- if(futureGet != null) {
- if(!futureGet.isEmpty()) {
- return futureGet.dataMap();
- }
- }
- return null;
- }
-
- public static boolean remove(String locationKey, String contentKey) {
- FutureRemove futureRemove = peerDHT
- .remove(Number160.createHash(locationKey))
- .contentKey(contentKey == null ? null : Number160.createHash(contentKey))
- .start()
- .awaitUninterruptibly();
- return futureRemove.isRemoved();
- }
-
- public static boolean remove(String locationKey, String contentKey, KeyPair keyPair) {
- FutureRemove futureRemove = peerDHT
- .remove(Number160.createHash(locationKey))
- .keyPair(keyPair)
- .contentKey(contentKey == null ? null : Number160.createHash(contentKey))
- .start()
- .awaitUninterruptibly();
- return futureRemove.isRemoved();
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/Serializer.java b/app/src/main/java/io/github/chronosx88/influence/helpers/Serializer.java
deleted file mode 100644
index f5a5aa2..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/Serializer.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package io.github.chronosx88.influence.helpers;
-
-import com.sleepycat.bind.EntryBinding;
-import com.sleepycat.je.DatabaseEntry;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-public class Serializer implements EntryBinding {
- public byte[] serialize(T object) {
- ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
- try {
- ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArray);
- objectOutputStream.writeObject(object);
- objectOutputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return byteArray.toByteArray();
- }
-
- public T deserialize(byte[] serializedObject) {
- if(serializedObject == null)
- return null;
- ByteArrayInputStream inputStream = new ByteArrayInputStream(serializedObject);
- Object object = null;
- try {
- ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
- object = objectInputStream.readObject();
- } catch (ClassNotFoundException | IOException e) {
- e.printStackTrace();
- }
- return (T) object;
- }
-
- @Override
- public T entryToObject(DatabaseEntry databaseEntry) {
- return deserialize(databaseEntry.getData());
- }
-
- @Override
- public void objectToEntry(T object, DatabaseEntry databaseEntry) {
- databaseEntry.setData(serialize(object));
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt b/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt
deleted file mode 100644
index fba5ea8..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt
+++ /dev/null
@@ -1,290 +0,0 @@
-package io.github.chronosx88.influence.helpers
-
-import com.sleepycat.collections.StoredSortedMap
-import com.sleepycat.je.Database
-import com.sleepycat.je.DatabaseConfig
-import com.sleepycat.je.Environment
-import com.sleepycat.je.EnvironmentConfig
-import io.github.chronosx88.influence.helpers.comparators.CompareLong
-import io.github.chronosx88.influence.helpers.comparators.CompareNumber640
-import net.tomp2p.connection.SignatureFactory
-import net.tomp2p.dht.Storage
-import net.tomp2p.peers.Number160
-import net.tomp2p.peers.Number320
-import net.tomp2p.peers.Number480
-import net.tomp2p.peers.Number640
-import net.tomp2p.storage.Data
-import java.io.File
-import java.security.PublicKey
-import java.util.*
-import java.util.concurrent.ConcurrentHashMap
-import kotlin.collections.ArrayList
-import kotlin.collections.HashMap
-
-class StorageBerkeleyDB(peerId: Number160, path : File, signatureFactory: SignatureFactory) : Storage {
- // Core
- private val dataMap: StoredSortedMap
- // Maintenance
- private val timeoutMap: StoredSortedMap
- private val timeoutMapRev: StoredSortedMap>
- // Protection
- private val protectedDomainMap: StoredSortedMap
- private val protectedEntryMap: StoredSortedMap
- // Responsibility
- private val responsibilityMap: StoredSortedMap
- private val responsibilityMapRev: StoredSortedMap>
-
- private val dataMapDB: Database
- private val timeoutMapDB: Database
- private val timeoutMapRevDB: Database
- private val protectedDomainMapDB: Database
- private val protectedEntryMapDB: Database
- private val responsibilityMapDB: Database
- private val responsibilityMapRevDB: Database
-
-
- private val storageCheckIntervalMillis: Int
- private val dbEnvironment: Environment
-
- init {
- val envConfig = EnvironmentConfig()
- envConfig.allowCreate = true
- dbEnvironment = Environment(path, envConfig)
-
- val configMap : HashMap = HashMap()
-
- val compareNumber640 = CompareNumber640()
- val compareLong = CompareLong()
- configMap["dataMapConfig"] = DatabaseConfig().setBtreeComparator(compareNumber640)
- configMap["dataMapConfig"]!!.allowCreate = true
- configMap["timeoutMapRevConfig"] = DatabaseConfig().setBtreeComparator(compareLong)
- configMap["timeoutMapRevConfig"]!!.allowCreate = true
- configMap["other"] = DatabaseConfig()
- configMap["other"]!!.allowCreate = true
-
- dataMapDB = dbEnvironment.openDatabase(null, "dataMap_$peerId", configMap["dataMapConfig"])
- timeoutMapDB = dbEnvironment.openDatabase(null, "timeoutMap_$peerId", configMap["other"])
- timeoutMapRevDB = dbEnvironment.openDatabase(null, "timeoutMapRev_$peerId", configMap["timeoutMapRevConfig"])
- protectedDomainMapDB = dbEnvironment.openDatabase(null, "protectedDomainMap_$peerId", configMap["other"])
- protectedEntryMapDB = dbEnvironment.openDatabase(null, "protectedEntryMap_$peerId", configMap["other"])
- responsibilityMapDB = dbEnvironment.openDatabase(null, "responsibilityMap_$peerId", configMap["other"])
- responsibilityMapRevDB = dbEnvironment.openDatabase(null, "responsibilityMapRev_$peerId", configMap["other"])
-
- storageCheckIntervalMillis = 60 * 1000
-
- dataMap = StoredSortedMap(dataMapDB, Serializer(), DataSerializer(signatureFactory), true)
- timeoutMap = StoredSortedMap(timeoutMapDB, Serializer(), Serializer(), true)
- timeoutMapRev = StoredSortedMap(timeoutMapRevDB, Serializer(), Serializer>(), true)
- protectedDomainMap = StoredSortedMap(protectedDomainMapDB, Serializer(), Serializer(), true)
- protectedEntryMap = StoredSortedMap(protectedEntryMapDB, Serializer(), Serializer(), true)
- responsibilityMap = StoredSortedMap(responsibilityMapDB, Serializer(), Serializer(), true)
- responsibilityMapRev = StoredSortedMap(responsibilityMapRevDB, Serializer(), Serializer>(), true)
- }
-
- override fun contains(key: Number640?): Boolean {
- return dataMap.containsKey(key)
- }
-
- override fun contains(from: Number640?, to: Number640?): Int {
- return dataMap.subMap(from, true, to, true).size
- }
-
- override fun findContentForResponsiblePeerID(peerID: Number160?): MutableSet? {
- return responsibilityMapRev[peerID] as MutableSet?
- }
-
- override fun findPeerIDsForResponsibleContent(locationKey: Number160?): Number160? {
- return responsibilityMap[locationKey]
- }
-
- override fun put(key: Number640?, value: Data?): Data? {
- val oldData = dataMap.put(key, value)
- dbEnvironment.sync()
- return oldData
- }
-
- override fun get(key: Number640?): Data? {
- return dataMap[key]
- }
-
- override fun remove(key: Number640?, returnData: Boolean): Data? {
- val oldData = dataMap.remove(key)
- dbEnvironment.sync()
- return oldData
- }
-
- override fun remove(from: Number640?, to: Number640?): NavigableMap {
- val tmp = dataMap.subMap(from, true, to, true)
- val retVal = TreeMap()
- for(entry : Map.Entry in tmp.entries) {
- retVal[entry.key] = entry.value
- }
- tmp.clear()
- dbEnvironment.sync()
- return retVal
- }
-
- override fun addTimeout(key: Number640, expiration: Long) {
- val oldExpiration = timeoutMap.put(key, expiration)
- putIfAbsent2(expiration, key)
- if (oldExpiration == null) {
- return
- }
- removeRevTimeout(key, oldExpiration)
- dbEnvironment.sync()
- }
-
- private fun putIfAbsent2(expiration: Long, key: Number640) {
- var timeouts = timeoutMapRev[expiration]
- //var timeouts : MutableSet = timeoutMapRev[expiration] as MutableSet
- if (timeouts == null) {
- timeouts = Collections.newSetFromMap(ConcurrentHashMap())
- }
- (timeouts as MutableSet).add(key)
- timeoutMapRev[expiration] = timeouts
- dbEnvironment.sync()
- }
-
- private fun removeRevTimeout(key: Number640, expiration: Long?) {
- val tmp = timeoutMapRev[expiration] as MutableSet?
- if (tmp != null) {
- tmp.remove(key)
- if (tmp.isEmpty()) {
- timeoutMapRev.remove(expiration)
- } else {
- timeoutMapRev[expiration!!] = tmp
- }
- }
- dbEnvironment.sync()
- }
-
- override fun updateResponsibilities(locationKey: Number160, peerId: Number160?): Boolean {
- val oldPeerID = responsibilityMap.put(locationKey, peerId)
- val hasChanged: Boolean
- if (oldPeerID != null) {
- if (oldPeerID == peerId) {
- hasChanged = false
- } else {
- removeRevResponsibility(oldPeerID, locationKey)
- hasChanged = true
- }
- } else {
- hasChanged = true
- }
- var contentIDs: MutableSet? = responsibilityMapRev[peerId] as MutableSet?
- if (contentIDs == null) {
- contentIDs = HashSet()
- }
- contentIDs.add(locationKey)
- responsibilityMapRev[peerId] = contentIDs
- dbEnvironment.sync()
- return hasChanged
- }
-
- private fun removeRevResponsibility(peerId: Number160, locationKey: Number160) {
- val contentIDs = responsibilityMapRev[peerId] as MutableSet
- if (contentIDs != null) {
- contentIDs.remove(locationKey)
- if (contentIDs.isEmpty()) {
- responsibilityMapRev.remove(peerId)
- } else {
- responsibilityMapRev[peerId] = contentIDs
- }
- }
- dbEnvironment.sync()
- }
-
- override fun protectDomain(key: Number320?, publicKey: PublicKey?): Boolean {
- protectedDomainMap[key] = publicKey
- dbEnvironment.sync()
- return true
- }
-
- override fun storageCheckIntervalMillis(): Int {
- return storageCheckIntervalMillis
- }
-
- override fun isDomainProtectedByOthers(key: Number320?, publicKey: PublicKey?): Boolean {
- val other = protectedDomainMap[key] ?: return false
- return other != publicKey
- }
-
- override fun removeTimeout(key: Number640) {
- val expiration = timeoutMap.remove(key) ?: return
- removeRevTimeout(key, expiration)
- timeoutMapDB.sync()
- dbEnvironment.sync()
- }
-
- override fun removeResponsibility(locationKey: Number160) {
- val peerId = responsibilityMap.remove(locationKey)
- if (peerId != null) {
- removeRevResponsibility(peerId, locationKey)
- }
- dbEnvironment.sync()
- }
-
- override fun protectEntry(key: Number480?, publicKey: PublicKey?): Boolean {
- protectedEntryMap[key] = publicKey
- dbEnvironment.sync()
- return true
- }
-
- override fun map(): NavigableMap {
- val retVal = TreeMap()
- for ((key, value) in dataMap) {
- retVal[key] = value
- }
-
- return retVal
- }
-
- override fun isEntryProtectedByOthers(key: Number480?, publicKey: PublicKey?): Boolean {
- val other = protectedEntryMap[key] ?: return false
- return other != publicKey
- }
-
- override fun subMap(from: Number640?, to: Number640?, limit: Int, ascending: Boolean): NavigableMap {
- val tmp = dataMap.subMap(from, true, to, true)
- val descendingMap = TreeMap(tmp).descendingMap()
- val retVal = TreeMap()
- if (limit < 0) {
- for ((key, value) in if (ascending) tmp else descendingMap) {
- retVal[key] = value
- }
- } else {
- val limit1 = Math.min(limit, tmp.size)
- val iterator = if (ascending)
- tmp.entries.iterator()
- else
- descendingMap.entries.iterator()
- var i = 0
- while (iterator.hasNext() && i < limit1) {
- val entry = iterator.next()
- retVal[entry.key] = entry.value
- i++
- }
- }
- return retVal
- }
-
- override fun subMapTimeout(to: Long): MutableCollection {
- val tmp = timeoutMapRev.subMap(0L, to)
- val toRemove = ArrayList()
- for (set in tmp.values) {
- toRemove.addAll(set)
- }
- return toRemove
- }
-
- override fun close() {
- dataMapDB.close()
- timeoutMapDB.close()
- timeoutMapRevDB.close()
- protectedDomainMapDB.close()
- protectedEntryMapDB.close()
- responsibilityMapDB.close()
- responsibilityMapRevDB.close()
- dbEnvironment.close()
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/NetworkActions.java b/app/src/main/java/io/github/chronosx88/influence/helpers/actions/NetworkActions.java
deleted file mode 100644
index d691620..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/NetworkActions.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.chronosx88.influence.helpers.actions;
-
-public class NetworkActions {
- public static final int CREATE_CHAT = 0x0;
- public static final int TEXT_MESSAGE = 0x1;
- public static final int JOIN_CHAT = 0x2;
- public static final int NEXT_CHUNK_REF = 0x3;
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java b/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java
deleted file mode 100644
index 152af68..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package io.github.chronosx88.influence.helpers.actions;
-
-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;
- public static final int PEER_NOT_EXIST = 0x7;
- public static final int SUCCESSFUL_CREATE_CHAT = 0x8;
- public static final int MESSAGE_RECEIVED = 0x9;
- public static final int NODE_IS_OFFLINE = 0x10;
- public static final int USERNAME_ISNT_AVAILABLE = 0x11;
- public static final int USERNAME_AVAILABLE = 0x12;
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareLong.java b/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareLong.java
deleted file mode 100644
index f8e74f0..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareLong.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.github.chronosx88.influence.helpers.comparators;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import io.github.chronosx88.influence.helpers.Serializer;
-
-public class CompareLong implements Comparator, Serializable {
- @Override
- public int compare(byte[] o1, byte[] o2) {
- Serializer serializer = new Serializer<>();
- Long num1 = serializer.deserialize(o1);
- Long num2 = serializer.deserialize(o2);
- return num1.compareTo(num2);
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareNumber640.java b/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareNumber640.java
deleted file mode 100644
index 35a0b5f..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/comparators/CompareNumber640.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package io.github.chronosx88.influence.helpers.comparators;
-
-import net.tomp2p.peers.Number640;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import io.github.chronosx88.influence.helpers.Serializer;
-
-public class CompareNumber640 implements Comparator, Serializable {
- @Override
- public int compare(byte[] o1, byte[] o2) {
- Serializer serializer = new Serializer<>();
- Number640 num1 = serializer.deserialize(o1);
- Number640 num2 = serializer.deserialize(o2);
- return num1.compareTo(num2);
- }
-}
-
-
diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/ChatLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/ChatLogic.java
index 57e8d0f..2d5897e 100644
--- a/app/src/main/java/io/github/chronosx88/influence/logic/ChatLogic.java
+++ b/app/src/main/java/io/github/chronosx88/influence/logic/ChatLogic.java
@@ -18,7 +18,6 @@ import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.KeyPairManager;
import io.github.chronosx88.influence.helpers.LocalDBWrapper;
import io.github.chronosx88.influence.helpers.ObservableUtils;
-import io.github.chronosx88.influence.helpers.P2PUtils;
import io.github.chronosx88.influence.helpers.actions.NetworkActions;
import io.github.chronosx88.influence.helpers.actions.UIActions;
import io.github.chronosx88.influence.models.JoinChatMessage;
@@ -159,9 +158,9 @@ public class ChatLogic implements CoreContracts.IChatLogicContract {
if(messages.size() > 10) {
String messageID = UUID.randomUUID().toString();
try {
- P2PUtils.put(chatEntity.chatID + "_messages" + chunkID, messageID, new Data(gson.toJson(new NextChunkReference(messageID, AppHelper.getPeerID(), AppHelper.getPeerID(), System.currentTimeMillis(), chatEntity.chunkCursor+1))));
+ int nextChunkCursor = chatEntity.chunkCursor + 1;
+ P2PUtils.put(chatEntity.chatID + "_messages" + chunkID, messageID, new Data(gson.toJson(new NextChunkReference(messageID, AppHelper.getPeerID(), AppHelper.getPeerID(), System.currentTimeMillis(), nextChunkCursor))));
P2PUtils.put(chatEntity.chatID + "_newMessage", null, new Data(messageID));
- LocalDBWrapper.updateChatEntity(chatEntity);
} catch (IOException e) {
e.printStackTrace();
}
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 3ddaaeb..219d7b3 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
@@ -45,12 +45,10 @@ import java.util.UUID;
import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.helpers.AppHelper;
-import io.github.chronosx88.influence.helpers.JVMShutdownHook;
import io.github.chronosx88.influence.helpers.KeyPairManager;
import io.github.chronosx88.influence.helpers.LocalDBWrapper;
import io.github.chronosx88.influence.helpers.NetworkHandler;
import io.github.chronosx88.influence.helpers.ObservableUtils;
-import io.github.chronosx88.influence.helpers.P2PUtils;
import io.github.chronosx88.influence.helpers.StorageBerkeleyDB;
import io.github.chronosx88.influence.helpers.actions.UIActions;
import io.github.chronosx88.influence.models.ChatMetadata;
diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt b/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt
index e0a7899..e616a87 100644
--- a/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt
+++ b/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt
@@ -5,7 +5,6 @@ import io.github.chronosx88.influence.contracts.CoreContracts
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.P2PUtils
import io.github.chronosx88.influence.helpers.actions.UIActions
import net.tomp2p.peers.Number640
import net.tomp2p.storage.Data
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/BasicNetworkMessage.java b/app/src/main/java/io/github/chronosx88/influence/models/BasicNetworkMessage.java
deleted file mode 100644
index 1bb934f..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/BasicNetworkMessage.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-
-/**
- * Абстрактный класс-модель для любых сообщений, которые передаются по DHT-сети
- */
-public class BasicNetworkMessage implements Serializable {
- private int action;
- private String messageID;
- private String senderID;
- private String username;
- private long timestamp;
-
- public BasicNetworkMessage() {
- //
- }
-
- public BasicNetworkMessage(int action, String messageID, String senderID, String username, long timestamp) {
- this.action = action;
- this.senderID = senderID;
- this.username = username;
- this.messageID = messageID;
- this.timestamp = timestamp;
- }
-
- public int getAction() {
- return action;
- }
-
- public String getSenderID() {
- return senderID;
- }
-
- public String getUsername() {
- return username;
- }
-
- public String getMessageID() {
- return messageID;
- }
-
- public long getTimestamp() {
- return timestamp;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/ChatMember.java b/app/src/main/java/io/github/chronosx88/influence/models/ChatMember.java
deleted file mode 100644
index 133d584..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/ChatMember.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-
-public class ChatMember implements Serializable {
- private String username;
- private String peerID;
-
- public ChatMember(String username, String peerID) {
- this.username = username;
- this.peerID = peerID;
- }
-
- public String getUsername() {
- return username;
- }
-
- public String getPeerID() {
- return peerID;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/ChatMetadata.java b/app/src/main/java/io/github/chronosx88/influence/models/ChatMetadata.java
deleted file mode 100644
index 54e2141..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/ChatMetadata.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-
-public class ChatMetadata implements Serializable {
- private String name;
- private ArrayList admins;
- private ArrayList banned;
-
- public ChatMetadata(String name, ArrayList admins, ArrayList banned) {
- this.name = name;
- this.admins = admins;
- this.banned = banned;
- }
-
- public String getName() {
- return name;
- }
-
- public ArrayList getAdmins() {
- return admins;
- }
-
- public ArrayList getBanned() {
- return banned;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setAdmins(ArrayList admins) {
- this.admins = admins;
- }
-
- public void setBanned(ArrayList banned) {
- this.banned = banned;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/JoinChatMessage.java b/app/src/main/java/io/github/chronosx88/influence/models/JoinChatMessage.java
deleted file mode 100644
index e12162a..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/JoinChatMessage.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-import java.util.UUID;
-
-import io.github.chronosx88.influence.helpers.actions.NetworkActions;
-
-public class JoinChatMessage extends BasicNetworkMessage implements Serializable {
- private String chatID;
-
- public JoinChatMessage(String senderID, String username, String chatID, long timestamp) {
- super(NetworkActions.JOIN_CHAT, UUID.randomUUID().toString(), senderID, username, timestamp);
- this.chatID = chatID;
- }
-
- public String getChatID() {
- return chatID;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java b/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java
deleted file mode 100644
index f1e17e4..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-
-import io.github.chronosx88.influence.helpers.actions.NetworkActions;
-
-public class NewChatRequestMessage extends BasicNetworkMessage implements Serializable {
- private String chatID;
- private int chunkID;
-
- public NewChatRequestMessage(String messageID, String chatID, String senderID, String username, long timestamp, int chunkID) {
- super(NetworkActions.CREATE_CHAT, messageID, senderID, username, timestamp);
- this.chatID = chatID;
- this.chunkID = chunkID;
- }
-
- public String getChatID() {
- return chatID;
- }
-
- public int getChunkID() {
- return chunkID;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/NextChunkReference.java b/app/src/main/java/io/github/chronosx88/influence/models/NextChunkReference.java
deleted file mode 100644
index 7251de8..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/NextChunkReference.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-
-import io.github.chronosx88.influence.helpers.actions.NetworkActions;
-
-public class NextChunkReference extends BasicNetworkMessage implements Serializable {
- private int nextChunkID;
-
- public NextChunkReference(String messageID, String senderID, String username, long timestamp, int nextChunkID) {
- super(NetworkActions.NEXT_CHUNK_REF, messageID, senderID, username, timestamp);
- this.nextChunkID = nextChunkID;
- }
-
- public int getNextChunkID() {
- return nextChunkID;
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/PublicUserProfile.kt b/app/src/main/java/io/github/chronosx88/influence/models/PublicUserProfile.kt
deleted file mode 100644
index 699a946..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/PublicUserProfile.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.github.chronosx88.influence.models
-
-import net.tomp2p.peers.PeerAddress
-
-import java.io.Serializable
-
-/**
- * Класс-модель публичного профиля для размещения в DHT-сети
- */
-data class PublicUserProfile(var userName: String?, var peerAddress: PeerAddress?) : Serializable
diff --git a/app/src/main/java/io/github/chronosx88/influence/models/TextMessage.java b/app/src/main/java/io/github/chronosx88/influence/models/TextMessage.java
deleted file mode 100644
index 91c7276..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/models/TextMessage.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.github.chronosx88.influence.models;
-
-import java.io.Serializable;
-
-import io.github.chronosx88.influence.helpers.actions.NetworkActions;
-
-public class TextMessage extends BasicNetworkMessage implements Serializable {
- private String chatID; // Chat ID
- private String text; // Message text
- private boolean isRead; // Message Read Indicator
-
- public TextMessage(String senderID, String messageID, String chatID, String username, long timestamp, String text, boolean isRead) {
- super(NetworkActions.TEXT_MESSAGE, messageID, senderID, username, timestamp);
- this.chatID = chatID;
- this.text = text;
- this.isRead = isRead;
- }
-
- public String getChatID() {
- return chatID;
- }
-
- public String getText() {
- return text;
- }
-
- public boolean isRead() {
- return isRead;
- }
-}
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 c9a4f8c..04b3adb 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
@@ -14,14 +14,14 @@ public interface ChatDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void addChat(ChatEntity chatEntity);
- @Query("DELETE FROM chats WHERE chatID = :chatID")
- void deleteChat(String chatID);
+ @Query("DELETE FROM chats WHERE jid = :jid")
+ void deleteChat(String jid);
@Query("SELECT * FROM chats")
List getAllChats();
- @Query("SELECT * FROM chats WHERE chatID = :chatID")
- List getChatByChatID(String chatID);
+ @Query("SELECT * FROM chats WHERE jid = :jid")
+ List getChatByChatID(String jid);
@Update
void updateChat(ChatEntity chat);
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 85afa75..bba41ae 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
@@ -12,19 +12,19 @@ import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
@Dao
public interface MessageDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
- void insertMessage(MessageEntity chatModel);
+ long insertMessage(MessageEntity chatModel);
@Query("DELETE FROM messages WHERE messageID = :messageID")
void deleteMessage(String messageID);
- @Query("DELETE FROM messages WHERE chatID = :chatID")
- void deleteMessagesByChatID(String chatID);
+ @Query("DELETE FROM messages WHERE jid = :jid")
+ void deleteMessagesByChatID(String jid);
- @Query("SELECT * FROM messages WHERE chatID = :chatID")
- List getMessagesByChatID(String chatID);
+ @Query("SELECT * FROM messages WHERE jid = :jid")
+ List getMessagesByChatID(String jid);
@Query("SELECT * FROM messages WHERE messageID = :messageID")
- List getMessageByID(String messageID);
+ List getMessageByID(long messageID);
@Update
void updateMessage(MessageEntity message);
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
index 0315c08..8bf0476 100644
--- 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
@@ -1,7 +1,5 @@
package io.github.chronosx88.influence.models.roomEntities;
-import java.util.ArrayList;
-
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
@@ -9,19 +7,11 @@ import androidx.room.PrimaryKey;
@Entity(tableName = "chats")
public class ChatEntity {
- @PrimaryKey @NonNull public String chatID;
- @ColumnInfo public String name;
- @ColumnInfo public String metadataRef;
- @ColumnInfo public String membersRef;
- @ColumnInfo public ArrayList bannedUsers;
- @ColumnInfo public int chunkCursor;
+ @PrimaryKey @NonNull public String jid;
+ @ColumnInfo public String chatName;
- public ChatEntity(@NonNull String chatID, String name, String metadataRef, String membersRef, ArrayList bannedUsers, int chunkCursor) {
- this.chatID = chatID;
- this.name = name;
- this.metadataRef = metadataRef;
- this.membersRef = membersRef;
- this.bannedUsers = bannedUsers;
- this.chunkCursor = chunkCursor;
+ public ChatEntity(@NonNull String jid, String chatName) {
+ this.jid = jid;
+ this.chatName = chatName;
}
}
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
index bdd8eaa..a152dde 100644
--- 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
@@ -7,22 +7,17 @@ import androidx.room.PrimaryKey;
@Entity(tableName = "messages")
public class MessageEntity {
- @PrimaryKey @NonNull public String messageID; // Global message ID
- @ColumnInfo public int type; // Message type
- @ColumnInfo public String chatID; // Chat ID
- @ColumnInfo public String senderID; // PeerID
- @ColumnInfo public String username; // Username
+ @PrimaryKey(autoGenerate = true) public long messageID; // Global message ID
+ @ColumnInfo public String jid; // Chat ID
+ @ColumnInfo public String senderJid;
@ColumnInfo public long timestamp; // Timestamp
@ColumnInfo public String text; // Message text
@ColumnInfo public boolean isSent; // Send status indicator
@ColumnInfo public boolean isRead; // Message Read Indicator
- public MessageEntity(int type, String messageID, String chatID, String senderID, String username, long timestamp, String text, boolean isSent, boolean isRead) {
- this.type = type;
- this.messageID = messageID;
- this.chatID = chatID;
- this.senderID = senderID;
- this.username = username;
+ public MessageEntity(String jid, String senderJid, long timestamp, String text, boolean isSent, boolean isRead) {
+ this.jid = jid;
+ this.senderJid = senderJid;
this.timestamp = timestamp;
this.text = text;
this.isSent = isSent;
diff --git a/app/src/main/java/io/github/chronosx88/influence/views/LoginActivity.java b/app/src/main/java/io/github/chronosx88/influence/views/LoginActivity.java
new file mode 100644
index 0000000..f07a5eb
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/views/LoginActivity.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 ChronosX88
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package io.github.chronosx88.influence.views;
+
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import io.github.chronosx88.influence.R;
+import io.github.chronosx88.influence.XMPPConnectionService;
+import io.github.chronosx88.influence.contracts.CoreContracts;
+import io.github.chronosx88.influence.helpers.AppHelper;
+
+public class LoginActivity extends AppCompatActivity implements CoreContracts.ILoginViewContract {
+ private EditText jidEditText;
+ private EditText passwordEditText;
+ private Button signInButton;
+ private BroadcastReceiver broadcastReceiver;
+ private ProgressDialog progressDialog;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_login);
+ jidEditText = findViewById(R.id.login_jid);
+ passwordEditText = findViewById(R.id.login_password);
+ signInButton = findViewById(R.id.sign_in_button);
+ progressDialog = new ProgressDialog(LoginActivity.this);
+ signInButton.setOnClickListener((v) -> {
+ if(checkLoginCredentials()) {
+ saveLoginCredentials();
+ doLogin();
+ }
+ });
+ }
+
+ @Override
+ public void loadingScreen(boolean state) {
+ if(state)
+ progressDialog.show();
+ else
+ progressDialog.dismiss();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case XMPPConnectionService.INTENT_AUTHENTICATED: {
+ loadingScreen(false);
+ finish();
+ break;
+ }
+ case XMPPConnectionService.INTENT_AUTHENTICATION_FAILED: {
+ loadingScreen(false);
+ passwordEditText.setError("Invalid JID/Password");
+ break;
+ }
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(XMPPConnectionService.INTENT_AUTHENTICATED);
+ filter.addAction(XMPPConnectionService.INTENT_AUTHENTICATION_FAILED);
+ this.registerReceiver(broadcastReceiver, filter);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ this.unregisterReceiver(broadcastReceiver);
+ }
+
+ private boolean checkLoginCredentials() {
+ jidEditText.setError(null);
+ passwordEditText.setError(null);
+
+ String jid = jidEditText.getText().toString();
+ String password = passwordEditText.getText().toString();
+
+ boolean cancel = false;
+ View focusView = null;
+
+ if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
+ passwordEditText.setError("Invalid password");
+ focusView = passwordEditText;
+ cancel = true;
+ }
+
+ if (TextUtils.isEmpty(jid)) {
+ jidEditText.setError("Field is required!");
+ focusView = jidEditText;
+ cancel = true;
+ } else if (!isEmailValid(jid)) {
+ jidEditText.setError("Invalid JID");
+ focusView = jidEditText;
+ cancel = true;
+ }
+
+ if (cancel) {
+ focusView.requestFocus();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private boolean isEmailValid(String email) {
+ return email.contains("@");
+ }
+
+ private boolean isPasswordValid(String password) {
+ return password.length() > 4;
+ }
+
+ private void saveLoginCredentials() {
+ AppHelper.getPreferences().edit()
+ .putString("jid", jidEditText.getText().toString())
+ .putString("pass", passwordEditText.getText().toString())
+ .putBoolean("logged_in", true)
+ .apply();
+ }
+
+ private void doLogin() {
+ loadingScreen(true);
+ startService(new Intent(this, XMPPConnectionService.class));
+ }
+}
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 4a54544..1d3f72f 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
@@ -32,7 +32,7 @@ import io.github.chronosx88.influence.views.fragments.ChatListFragment;
import io.github.chronosx88.influence.views.fragments.SettingsFragment;
import kotlin.Pair;
-public class MainActivity extends AppCompatActivity implements IObserver, CoreContracts.IMainViewContract {
+public class MainActivity extends AppCompatActivity implements CoreContracts.IMainViewContract {
private CoreContracts.IMainPresenterContract presenter;
private ProgressDialog progressDialog;
@@ -88,7 +88,7 @@ public class MainActivity extends AppCompatActivity implements IObserver, CoreCo
.commit();
presenter = new MainPresenter(this);
- AppHelper.getObservable().register(this);
+
progressDialog = new ProgressDialog(MainActivity.this, R.style.AlertDialogTheme);
progressDialog.setCancelable(false);
@@ -101,54 +101,6 @@ public class MainActivity extends AppCompatActivity implements IObserver, CoreCo
protected void onDestroy() {
super.onDestroy();
presenter.onDestroy();
- AppHelper.getObservable().unregister(this);
- }
-
- @Override
- public void handleEvent(JsonObject object) {
- switch (object.get("action").getAsInt()) {
- case UIActions.BOOTSTRAP_NOT_SPECIFIED: {
- runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(this, "Bootstrap-нода не указана. Прерываю подключение к сети...", Toast.LENGTH_LONG).show();
- });
- break;
- }
- case UIActions.NETWORK_ERROR: {
- runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(this, "Ошибка сети. Возможно, нода недоступна, или у вас отсутствует Интернет.", Toast.LENGTH_LONG).show();
- });
- break;
- }
- case UIActions.BOOTSTRAP_SUCCESS: {
- runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(this, "Нода успешно запущена!", Toast.LENGTH_LONG).show();
- });
- break;
- }
- case UIActions.PORT_FORWARDING_ERROR: {
- runOnUiThread(() -> {
- Toast.makeText(this, "Проблемы с пробросом портов. Возможно, у вас не настроен uPnP.", Toast.LENGTH_LONG).show();
- });
- break;
- }
- case UIActions.BOOTSTRAP_ERROR: {
- runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(this, "Не удалось подключиться к бутстрап-ноде.", Toast.LENGTH_LONG).show();
- });
- break;
- }
- case UIActions.RELAY_CONNECTION_ERROR: {
- runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(this, "Не удалось подключиться к relay-ноде.", Toast.LENGTH_LONG).show();
- });
- break;
- }
- }
}
@Override
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..f3ea72f
--- /dev/null
+++ b/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file