diff --git a/app/build.gradle b/app/build.gradle
index 5a1bc9f..c63c3e6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -29,6 +29,7 @@ android {
exclude 'META-INF/io.netty.versions.properties'
exclude 'LICENSE-EPL-1.0.txt'
exclude 'LICENSE-EDL-1.0.txt'
+ exclude 'META-INF/atomicfu.kotlin_module'
}
compileOptions {
@@ -40,20 +41,19 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
implementation "androidx.room:room-runtime:2.1.0-alpha04"
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
implementation 'org.slf4j:slf4j-log4j12:1.7.26'
- implementation group: 'com.h2database', name: 'h2-mvstore', version: '1.4.197'
implementation 'net.tomp2p:tomp2p-all:5.0-Beta8'
implementation 'com.google.android.material:material:1.1.0-alpha04'
implementation 'androidx.preference:preference:1.1.0-alpha03'
implementation 'com.google.code.gson:gson:2.8.5'
- implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: '3.1.0.RELEASE'
implementation 'de.hdodenhof:circleimageview:3.0.0'
- implementation group: 'org.objenesis', name: 'objenesis', version: '2.6'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'com.android.support:multidex:1.0.3'
+ implementation "org.jetbrains.anko:anko:0.10.8"
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0'
+ implementation 'com.esotericsoftware:kryo:5.0.0-RC1'
}
repositories {
mavenCentral()
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 53e778d..ed46495 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,14 +3,16 @@
xmlns:tools="http://schemas.android.com/tools"
package="io.github.chronosx88.influence">
+
+
+ android:theme="@style/AppTheme">
@@ -20,7 +22,7 @@
+ android:theme="@style/NoWindowActionBar" />
-
+
\ No newline at end of file
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
new file mode 100644
index 0000000..998ce6f
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/contracts/CoreContracts.kt
@@ -0,0 +1,91 @@
+package io.github.chronosx88.influence.contracts
+
+import android.content.Intent
+import android.view.MenuItem
+
+import io.github.chronosx88.influence.helpers.ChatListAdapter
+import io.github.chronosx88.influence.models.roomEntities.ChatEntity
+import io.github.chronosx88.influence.models.roomEntities.MessageEntity
+
+interface CoreContracts {
+
+ // -----ChatList-----
+
+ interface IChatListLogicContract {
+ fun loadAllChats(): List
+ }
+
+ interface IChatListPresenterContract {
+ fun updateChatList()
+ fun openChat(chatID: String)
+ fun onContextItemSelected(item: MenuItem)
+ }
+
+ interface IChatListViewContract {
+ fun setRecycleAdapter(adapter: ChatListAdapter)
+ fun startActivity(intent: Intent)
+ 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 {
+ fun initPeer()
+ fun shutdownPeer()
+ }
+
+ interface IMainPresenterContract {
+ fun initPeer()
+ fun onDestroy()
+ }
+
+ interface IMainViewContract//
+
+ // -----ChatActivity-----
+
+ interface IChatLogicContract {
+ fun sendMessage(message: MessageEntity)
+ fun stopTrackingForNewMsgs()
+ }
+
+ interface IChatPresenterContract {
+ fun sendMessage(text: String)
+ fun updateAdapter()
+ fun onDestroy()
+ }
+
+ interface IChatViewContract {
+ fun updateMessageList(message: MessageEntity)
+ fun updateMessageList(messages: List)
+ }
+
+ // -----SettingsFragment-----
+
+ interface ISettingsLogic {
+ fun checkUsernameExists(username: String) : Boolean
+ }
+
+ interface ISettingsPresenter {
+ fun updateUsername(username: String)
+ }
+
+ interface ISettingsView {
+ fun loadingScreen(state: Boolean)
+ fun showMessage(message: String)
+ }
+}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatLogicContract.java
deleted file mode 100644
index e5878fb..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatLogicContract.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatactivity;
-
-import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
-
-public interface IChatLogicContract {
- void sendMessage(MessageEntity message);
- void stopTrackingForNewMsgs();
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatPresenterContract.java
deleted file mode 100644
index 3e77721..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatPresenterContract.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatactivity;
-
-public interface IChatPresenterContract {
- void sendMessage(String text);
- void updateAdapter();
- void onDestroy();
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatViewContract.java
deleted file mode 100644
index 871de0a..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatactivity/IChatViewContract.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatactivity;
-
-import java.util.List;
-
-import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
-
-public interface IChatViewContract {
- void updateMessageList(MessageEntity message);
- void updateMessageList(List messages);
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListLogicContract.java
deleted file mode 100644
index eff7c8b..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListLogicContract.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatlist;
-
-import java.util.List;
-
-import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
-
-public interface IChatListLogicContract {
- List loadAllChats();
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListPresenterContract.java
deleted file mode 100644
index 125a767..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListPresenterContract.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatlist;
-
-import android.view.MenuItem;
-
-public interface IChatListPresenterContract {
- void updateChatList();
- void openChat(String chatID);
- void onContextItemSelected(MenuItem item);
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListViewContract.java
deleted file mode 100644
index 4a7a544..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/chatlist/IChatListViewContract.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.github.chronosx88.influence.contracts.chatlist;
-
-import android.content.Intent;
-
-import java.util.List;
-
-import io.github.chronosx88.influence.helpers.ChatListAdapter;
-import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
-
-public interface IChatListViewContract {
- void setRecycleAdapter(ChatListAdapter adapter);
- void startActivity(Intent intent);
- void updateChatList(ChatListAdapter adapter, List chats);
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainLogicContract.java
deleted file mode 100644
index 65ad0c9..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainLogicContract.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.github.chronosx88.influence.contracts.mainactivity;
-
-public interface IMainLogicContract {
- void initPeer();
- void shutdownPeer();
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainPresenterContract.java
deleted file mode 100644
index 69bd549..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainPresenterContract.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.github.chronosx88.influence.contracts.mainactivity;
-
-public interface IMainPresenterContract {
- void initPeer();
- void onDestroy();
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainViewContract.java
deleted file mode 100644
index ee49885..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/mainactivity/IMainViewContract.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package io.github.chronosx88.influence.contracts.mainactivity;
-
-public interface IMainViewContract {
- //
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatLogicContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatLogicContract.java
deleted file mode 100644
index 59763b3..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatLogicContract.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package io.github.chronosx88.influence.contracts.startchat;
-
-public interface IStartChatLogicContract {
- void sendStartChatMessage(String peerID);
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatPresenterContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatPresenterContract.java
deleted file mode 100644
index de736b8..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatPresenterContract.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package io.github.chronosx88.influence.contracts.startchat;
-
-public interface IStartChatPresenterContract {
- void startChatWithPeer(String peerID);
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatViewContract.java b/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatViewContract.java
deleted file mode 100644
index cdf5bf3..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/contracts/startchat/IStartChatViewContract.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.github.chronosx88.influence.contracts.startchat;
-
-public interface IStartChatViewContract {
- void showMessage(String message);
- void showProgressDialog(boolean enabled);
-}
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 311d511..99def7c 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
@@ -2,6 +2,7 @@ package io.github.chronosx88.influence.helpers;
import android.app.Application;
import android.content.Context;
+import android.content.SharedPreferences;
import net.tomp2p.dht.PeerDHT;
@@ -10,7 +11,7 @@ import androidx.room.Room;
import io.github.chronosx88.influence.observable.MainObservable;
/**
- * Extended Application class which designed for getting various objects from anywhere in the application.
+ * Extended Application class which designed for centralized getting various objects from anywhere in the application.
*/
public class AppHelper extends MultiDexApplication {
@@ -20,6 +21,8 @@ public class AppHelper extends MultiDexApplication {
private static PeerDHT peerDHT;
private static RoomHelper chatDB;
private static NetworkHandler networkHandler;
+ private static String username = "";
+ private static SharedPreferences preferences;
@Override
public void onCreate() {
@@ -29,10 +32,13 @@ public class AppHelper extends MultiDexApplication {
chatDB = Room.databaseBuilder(getApplicationContext(), RoomHelper.class, "chatDB")
.allowMainThreadQueries()
.build();
+ preferences = getApplicationContext().getSharedPreferences("io.github.chronosx88.influence_preferences", MODE_PRIVATE);
}
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() {
@@ -43,9 +49,15 @@ public class AppHelper extends MultiDexApplication {
public static String getPeerID() { return peerID; }
+ public static String getUsername() { return username; }
+
public static PeerDHT getPeerDHT() { return peerDHT; }
public static RoomHelper getChatDB() { return chatDB; }
public static void initNetworkHandler() { networkHandler = new NetworkHandler(); }
+
+ public static SharedPreferences getPreferences() {
+ return preferences;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializerEx.kt b/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt
similarity index 87%
rename from app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializerEx.kt
rename to app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt
index f85eb11..be74217 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializerEx.kt
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/DataSerializer.kt
@@ -7,6 +7,7 @@ import io.netty.buffer.Unpooled
import net.tomp2p.connection.SignatureFactory
import net.tomp2p.storage.AlternativeCompositeByteBuf
import net.tomp2p.storage.Data
+import org.mapdb.DataInput2
import java.io.*
import java.nio.ByteBuffer
import java.security.InvalidKeyException
@@ -27,7 +28,7 @@ class DataSerializerEx(private val signatureFactory: SignatureFactory) : EntryBi
data = Data.decodeHeader(buf, signatureFactory)
}
val len = data.length()
- val me = ByteArray(len)
+ var me = ByteArray(len)
try {
inputStream.read(me)
} catch (e: IOException) {
@@ -39,6 +40,14 @@ class DataSerializerEx(private val signatureFactory: SignatureFactory) : EntryBi
if (!retVal) {
Log.e(LOG_TAG, "# ERROR: Data could not be deserialized!")
}
+ val dataInput = DataInputStream(inputStream)
+ me = ByteArray(signatureFactory.signatureSize())
+ dataInput.readFully(me)
+ buf = Unpooled.wrappedBuffer(me)
+ retVal = data.decodeDone(buf, signatureFactory);
+ if(!retVal) {
+ throw IOException("signature could not be read")
+ }
return data
}
diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/KeyPairManager.java b/app/src/main/java/io/github/chronosx88/influence/helpers/KeyPairManager.java
index 258d4f9..2b7dc80 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/KeyPairManager.java
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/KeyPairManager.java
@@ -25,7 +25,6 @@ public class KeyPairManager {
}
public KeyPair getKeyPair(String keyPairName) {
- KeyPair keyPair = null;
keyPairName = keyPairName + ".kp";
File keyPairFile = new File(keyPairDir, keyPairName);
if (!keyPairFile.exists()) {
@@ -52,7 +51,9 @@ public class KeyPairManager {
KeyPair keyPair = null;
try {
keyPairFile.createNewFile();
- keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(1024);
+ keyPair = keyPairGenerator.generateKeyPair();
FileOutputStream outputStream = new FileOutputStream(keyPairFile);
outputStream.write(serializer.serialize(keyPair));
outputStream.close();
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 4cf0f54..b6d5224 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
@@ -58,7 +58,7 @@ public class NetworkHandler implements INetworkObserver {
LocalDBWrapper.createChatEntry(
newChatRequestMessage.getChatID(),
- newChatRequestMessage.getSenderID(),
+ newChatRequestMessage.getUsername(),
newChatRequestMessage.getChatID() + "_metadata",
newChatRequestMessage.getChatID() + "_members",
newChatRequestMessage.getChunkID()
@@ -67,7 +67,7 @@ public class NetworkHandler implements INetworkObserver {
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.getPeerID(), newChatRequestMessage.getChatID(), System.currentTimeMillis()))).protectEntry(keyPairManager.openMainKeyPair()));
+ 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();
}
@@ -75,6 +75,4 @@ public class NetworkHandler implements INetworkObserver {
}
}
}
-
-
}
\ 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
index 9d4ef52..6ae57fe 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java
@@ -13,34 +13,14 @@ 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 ping(PeerAddress recipientPeerAddress) {
- // For connection opening
- for (int i = 0; i < 5; i++) {
- peerDHT
- .peer()
- .ping()
- .peerAddress(recipientPeerAddress)
- .start()
- .awaitUninterruptibly();
- }
-
- FuturePing ping = peerDHT
- .peer()
- .ping()
- .peerAddress(recipientPeerAddress)
- .start()
- .awaitUninterruptibly();
- return ping.isSuccess();
- }
-
public static boolean put(String locationKey, String contentKey, Data data) {
- data.signed(false);
FuturePut futurePut = peerDHT
.put(Number160.createHash(locationKey))
.data(contentKey == null ? Number160.ZERO : Number160.createHash(contentKey), data)
@@ -49,6 +29,16 @@ public class P2PUtils {
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))
@@ -61,16 +51,6 @@ public class P2PUtils {
return null;
}
- public static boolean send(PeerAddress address, String data) {
- FutureDirect futureDirect = peerDHT
- .peer()
- .sendDirect(address)
- .object(data)
- .start()
- .awaitUninterruptibly();
- return futureDirect.isSuccess();
- }
-
public static boolean remove(String locationKey, String contentKey) {
FutureRemove futureRemove = peerDHT
.remove(Number160.createHash(locationKey))
@@ -79,4 +59,14 @@ public class P2PUtils {
.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/StorageBerkeleyDB.kt b/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt
index 4e1b893..525dc62 100644
--- a/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt
+++ b/app/src/main/java/io/github/chronosx88/influence/helpers/StorageBerkeleyDB.kt
@@ -72,7 +72,7 @@ class StorageBerkeleyDB(peerId: Number160, path : File, signatureFactory: Signat
storageCheckIntervalMillis = 60 * 1000
- dataMap = StoredSortedMap(dataMapDB, Serializer(), DataSerializerEx(signatureFactory), true)
+ 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)
@@ -89,8 +89,8 @@ class StorageBerkeleyDB(peerId: Number160, path : File, signatureFactory: Signat
return dataMap.subMap(from, true, to, true).size
}
- override fun findContentForResponsiblePeerID(peerID: Number160?): MutableSet {
- return responsibilityMapRev[peerID] as MutableSet
+ override fun findContentForResponsiblePeerID(peerID: Number160?): MutableSet? {
+ return responsibilityMapRev[peerID] as MutableSet?
}
override fun findPeerIDsForResponsibleContent(locationKey: Number160?): Number160? {
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
index 208f7c7..152af68 100644
--- 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
@@ -12,4 +12,6 @@ public class UIActions {
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/logic/ChatListLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java
index 0f74550..12eda21 100644
--- a/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java
+++ b/app/src/main/java/io/github/chronosx88/influence/logic/ChatListLogic.java
@@ -2,11 +2,11 @@ package io.github.chronosx88.influence.logic;
import java.util.List;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListLogicContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
-public class ChatListLogic implements IChatListLogicContract {
+public class ChatListLogic implements CoreContracts.IChatListLogicContract {
@Override
public List loadAllChats() {
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 adc2303..09aa5e9 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
@@ -13,7 +13,7 @@ import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
-import io.github.chronosx88.influence.contracts.chatactivity.IChatLogicContract;
+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.LocalDBWrapper;
@@ -27,7 +27,7 @@ import io.github.chronosx88.influence.models.TextMessage;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
-public class ChatLogic implements IChatLogicContract {
+public class ChatLogic implements CoreContracts.IChatLogicContract {
private static Gson gson = new Gson();
private String chatID;
private String newMessage = "";
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 eea2263..d7f8b95 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
@@ -22,6 +22,8 @@ import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.relay.tcp.TCPRelayClientConfig;
import net.tomp2p.replication.AutoReplication;
+import net.tomp2p.replication.IndirectReplication;
+import net.tomp2p.replication.Replication;
import net.tomp2p.storage.Data;
import java.io.IOException;
@@ -34,7 +36,7 @@ import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
-import io.github.chronosx88.influence.contracts.mainactivity.IMainLogicContract;
+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;
@@ -44,8 +46,8 @@ import io.github.chronosx88.influence.helpers.StorageBerkeleyDB;
import io.github.chronosx88.influence.helpers.actions.UIActions;
import io.github.chronosx88.influence.models.PublicUserProfile;
-public class MainLogic implements IMainLogicContract {
- private static final String LOG_TAG = "MainLogic";
+public class MainLogic implements CoreContracts.IMainLogicContract {
+ private static final String LOG_TAG = MainLogic.class.getName();
private SharedPreferences preferences;
private Number160 peerID;
@@ -54,7 +56,7 @@ public class MainLogic implements IMainLogicContract {
private InetAddress bootstrapAddress = null;
private PeerAddress bootstrapPeerAddress = null;
private Gson gson;
- private AutoReplication replication;
+ private IndirectReplication replication;
private KeyPairManager keyPairManager;
private Thread checkNewChatsThread = null;
private StorageBerkeleyDB storage;
@@ -142,11 +144,13 @@ public class MainLogic implements IMainLogicContract {
jsonObject.addProperty("action", UIActions.BOOTSTRAP_SUCCESS);
AppHelper.getObservable().notifyUIObservers(jsonObject);
AppHelper.storePeerID(preferences.getString("peerID", null));
+ AppHelper.updateUsername(preferences.getString("username", null));
AppHelper.storePeerDHT(peerDHT);
AppHelper.initNetworkHandler();
setReceiveHandler();
gson = new Gson();
publicProfileToDHT();
+ SettingsLogic.Companion.publishUsername(AppHelper.getUsername(), AppHelper.getUsername());
NetworkHandler.handlePendingChatRequests();
TimerTask timerTask = new TimerTask() {
@Override
@@ -163,7 +167,7 @@ public class MainLogic implements IMainLogicContract {
};
Timer timer = new Timer();
timer.schedule(timerTask, 1, 5000);
- replication = new AutoReplication(peerDHT.peer()).start();
+ replication = new IndirectReplication(peerDHT).start();
} catch (IOException e) {
e.printStackTrace();
}
@@ -224,7 +228,7 @@ public class MainLogic implements IMainLogicContract {
public void shutdownPeer() {
new Thread(() -> {
if(replication != null) {
- replication.shutdown().start();
+ replication.shutdown();
}
peerDHT.peer().announceShutdown().start().awaitUninterruptibly();
peerDHT.peer().shutdown().awaitUninterruptibly();
@@ -245,7 +249,7 @@ public class MainLogic implements IMainLogicContract {
private void publicProfileToDHT() {
KeyPair mainKeyPair = keyPairManager.openMainKeyPair();
- PublicUserProfile userProfile = new PublicUserProfile(AppHelper.getPeerID(), peerDHT.peerAddress());
+ PublicUserProfile userProfile = new PublicUserProfile(AppHelper.getUsername(), peerDHT.peerAddress());
Data serializedUserProfile = null;
try {
serializedUserProfile = new Data(gson.toJson(userProfile))
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
new file mode 100644
index 0000000..a64a28d
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/logic/SettingsLogic.kt
@@ -0,0 +1,46 @@
+package io.github.chronosx88.influence.logic
+
+import android.util.Log
+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.P2PUtils
+import net.tomp2p.peers.Number640
+import net.tomp2p.storage.Data
+import java.io.IOException
+
+class SettingsLogic : CoreContracts.ISettingsLogic {
+
+ override fun checkUsernameExists(username: String) : Boolean {
+ val usernameMap: MutableMap? = P2PUtils.get(username)
+ usernameMap ?: return false
+ return true
+ }
+
+ companion object {
+ private val LOG_TAG: String = "SettingsLogic"
+ private val keyPairManager = KeyPairManager()
+
+ fun publishUsername(oldUsername: String?, username: String?) {
+ val mainKeyPair = keyPairManager.openMainKeyPair()
+ if(oldUsername != null || !oldUsername.equals("")) {
+ P2PUtils.remove(oldUsername, null, mainKeyPair)
+ }
+
+ if (username.equals("") || username == null) {
+ return
+ }
+ var data: Data? = null
+ try {
+ data = Data(AppHelper.getPeerID())
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ data!!.protectEntry(mainKeyPair)
+
+ val isSuccess = P2PUtils.put(username, null, data, mainKeyPair)
+ Log.i(LOG_TAG, if (isSuccess) "Username $username is published!" else "Username $username isn't published!")
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java
index 0474355..8511a07 100644
--- a/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java
+++ b/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java
@@ -13,7 +13,7 @@ import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
-import io.github.chronosx88.influence.contracts.startchat.IStartChatLogicContract;
+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.LocalDBWrapper;
@@ -24,7 +24,7 @@ import io.github.chronosx88.influence.models.ChatMetadata;
import io.github.chronosx88.influence.models.NewChatRequestMessage;
import io.github.chronosx88.influence.models.PublicUserProfile;
-public class StartChatLogic implements IStartChatLogicContract {
+public class StartChatLogic implements CoreContracts.IStartChatLogicContract {
private PeerDHT peerDHT;
private Gson gson;
private KeyPairManager keyPairManager;
@@ -37,20 +37,25 @@ public class StartChatLogic implements IStartChatLogicContract {
}
@Override
- public void sendStartChatMessage(String peerID) {
+ public void sendStartChatMessage(String username) {
if(peerDHT == null) {
ObservableUtils.notifyUI(UIActions.NODE_IS_OFFLINE);
return;
}
new Thread(() -> {
+ String peerID = getPeerIDByUsername(username);
+ if(peerID == null) {
+ ObservableUtils.notifyUI(UIActions.PEER_NOT_EXIST);
+ return;
+ }
PublicUserProfile recipientPublicProfile = getPublicProfile(peerID);
if(recipientPublicProfile == null) {
ObservableUtils.notifyUI(UIActions.PEER_NOT_EXIST);
return;
}
- NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(UUID.randomUUID().toString(), UUID.randomUUID().toString(), AppHelper.getPeerID(), AppHelper.getPeerID(), System.currentTimeMillis(), 0);
+ NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(UUID.randomUUID().toString(), UUID.randomUUID().toString(), AppHelper.getPeerID(), AppHelper.getUsername(), System.currentTimeMillis(), 0);
try {
if(P2PUtils.put(peerID + "_pendingChats", newChatRequestMessage.getChatID(), new Data(gson.toJson(newChatRequestMessage)))) {
Log.i(LOG_TAG, "# Create new offline chat request is successful! ChatID: " + newChatRequestMessage.getChatID());
@@ -65,13 +70,13 @@ public class StartChatLogic implements IStartChatLogicContract {
admins.add(AppHelper.getPeerID());
Data data = null;
try {
- data = new Data(gson.toJson(new ChatMetadata(peerID, admins, new ArrayList<>())));
+ data = new Data(gson.toJson(new ChatMetadata(username, admins, new ArrayList<>())));
} catch (IOException e) {
e.printStackTrace();
}
data.protectEntry(keyPairManager.openMainKeyPair());
P2PUtils.put(newChatRequestMessage.getChatID() + "_metadata", null, data);
- LocalDBWrapper.createChatEntry(newChatRequestMessage.getChatID(), peerID, newChatRequestMessage.getChatID() + "_metadata", newChatRequestMessage.getChatID() + "_members", 0);
+ LocalDBWrapper.createChatEntry(newChatRequestMessage.getChatID(), username, newChatRequestMessage.getChatID() + "_metadata", newChatRequestMessage.getChatID() + "_members", 0);
ObservableUtils.notifyUI(UIActions.NEW_CHAT);
}).start();
}
@@ -89,4 +94,17 @@ public class StartChatLogic implements IStartChatLogicContract {
}
return null;
}
+
+ private String getPeerIDByUsername(String username) {
+ Map usernameMap = P2PUtils.get(username);
+ if(usernameMap == null) {
+ return null;
+ }
+ try {
+ return (String) usernameMap.values().iterator().next().object();
+ } catch (ClassNotFoundException | IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
}
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
index 5f58903..438cd47 100644
--- a/app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java
+++ b/app/src/main/java/io/github/chronosx88/influence/presenters/ChatListPresenter.java
@@ -3,9 +3,7 @@ package io.github.chronosx88.influence.presenters;
import android.content.Intent;
import android.view.MenuItem;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListLogicContract;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListPresenterContract;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListViewContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.ChatListAdapter;
import io.github.chronosx88.influence.helpers.LocalDBWrapper;
@@ -13,12 +11,12 @@ import io.github.chronosx88.influence.logic.ChatListLogic;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.views.ChatActivity;
-public class ChatListPresenter implements IChatListPresenterContract {
- private IChatListViewContract view;
- private IChatListLogicContract logic;
+public class ChatListPresenter implements CoreContracts.IChatListPresenterContract {
+ private CoreContracts.IChatListViewContract view;
+ private CoreContracts.IChatListLogicContract logic;
private ChatListAdapter chatListAdapter;
- public ChatListPresenter(IChatListViewContract view) {
+ public ChatListPresenter(CoreContracts.IChatListViewContract view) {
this.view = view;
chatListAdapter = new ChatListAdapter((v, p)-> {
openChat(chatListAdapter.getChatEntity(p).chatID);
diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/ChatPresenter.java b/app/src/main/java/io/github/chronosx88/influence/presenters/ChatPresenter.java
index 4c049f8..3031dac 100644
--- a/app/src/main/java/io/github/chronosx88/influence/presenters/ChatPresenter.java
+++ b/app/src/main/java/io/github/chronosx88/influence/presenters/ChatPresenter.java
@@ -10,9 +10,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
-import io.github.chronosx88.influence.contracts.chatactivity.IChatLogicContract;
-import io.github.chronosx88.influence.contracts.chatactivity.IChatPresenterContract;
-import io.github.chronosx88.influence.contracts.chatactivity.IChatViewContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.contracts.observer.IObserver;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.LocalDBWrapper;
@@ -22,14 +20,14 @@ import io.github.chronosx88.influence.logic.ChatLogic;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
-public class ChatPresenter implements IChatPresenterContract, IObserver {
- private IChatLogicContract logic;
- private IChatViewContract view;
+public class ChatPresenter implements CoreContracts.IChatPresenterContract, IObserver {
+ private CoreContracts.IChatLogicContract logic;
+ private CoreContracts.IChatViewContract view;
private ChatEntity chatEntity;
private String chatID;
private Gson gson;
- public ChatPresenter(IChatViewContract view, String chatID) {
+ public ChatPresenter(CoreContracts.IChatViewContract view, String chatID) {
this.logic = new ChatLogic(LocalDBWrapper.getChatByChatID(chatID));
this.view = view;
this.chatID = chatID;
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 9262726..82797d4 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,15 +1,13 @@
package io.github.chronosx88.influence.presenters;
-import io.github.chronosx88.influence.contracts.mainactivity.IMainLogicContract;
-import io.github.chronosx88.influence.contracts.mainactivity.IMainPresenterContract;
-import io.github.chronosx88.influence.contracts.mainactivity.IMainViewContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.logic.MainLogic;
-public class MainPresenter implements IMainPresenterContract {
- private IMainLogicContract logic;
- private IMainViewContract view;
+public class MainPresenter implements CoreContracts.IMainPresenterContract {
+ private CoreContracts.IMainLogicContract logic;
+ private CoreContracts.IMainViewContract view;
- public MainPresenter(IMainViewContract view) {
+ public MainPresenter(CoreContracts.IMainViewContract view) {
this.view = view;
logic = new MainLogic();
}
diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/SettingsPresenter.kt b/app/src/main/java/io/github/chronosx88/influence/presenters/SettingsPresenter.kt
new file mode 100644
index 0000000..c3eb653
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/presenters/SettingsPresenter.kt
@@ -0,0 +1,64 @@
+package io.github.chronosx88.influence.presenters
+
+import android.content.SharedPreferences
+import android.os.Handler
+import com.google.gson.JsonObject
+import io.github.chronosx88.influence.R
+import io.github.chronosx88.influence.contracts.CoreContracts
+import io.github.chronosx88.influence.contracts.observer.IObserver
+import io.github.chronosx88.influence.helpers.AppHelper
+import io.github.chronosx88.influence.helpers.ObservableUtils
+import io.github.chronosx88.influence.helpers.actions.UIActions
+import io.github.chronosx88.influence.logic.SettingsLogic
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+
+class SettingsPresenter(private val view: CoreContracts.ISettingsView) : CoreContracts.ISettingsPresenter, IObserver {
+ private val mainThreadHandler: Handler = Handler(AppHelper.getContext().mainLooper)
+ private val logic: SettingsLogic = SettingsLogic()
+
+ init {
+ AppHelper.getObservable().register(this)
+ }
+
+ override fun updateUsername(username: String) {
+ view.loadingScreen(true)
+ GlobalScope.launch {
+ if(!logic.checkUsernameExists(username)) {
+ // Save username in SharedPreferences
+ val editor: SharedPreferences.Editor = AppHelper.getPreferences().edit()
+ val oldUsername = AppHelper.getPreferences().getString("username", null)
+ if(username.equals("")) {
+ editor.remove("username")
+ } else {
+ editor.putString("username", username)
+ }
+ editor.apply()
+ AppHelper.updateUsername(if (username.equals("")) null else username)
+
+ // Publish username on DHT network
+ SettingsLogic.publishUsername(oldUsername, username)
+
+ ObservableUtils.notifyUI(UIActions.USERNAME_AVAILABLE)
+ } else {
+ ObservableUtils.notifyUI(UIActions.USERNAME_ISNT_AVAILABLE)
+ }
+ }
+ }
+
+ override fun handleEvent(json: JsonObject) {
+ val post = {
+ when (json.get("action").asInt) {
+ UIActions.USERNAME_AVAILABLE -> {
+ view.loadingScreen(false)
+ view.showMessage(AppHelper.getContext().getString(R.string.username_saved))
+ }
+ UIActions.USERNAME_ISNT_AVAILABLE -> {
+ view.loadingScreen(false)
+ view.showMessage(AppHelper.getContext().getString(R.string.username_isnt_saved))
+ }
+ }
+ }
+ mainThreadHandler.post(post)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java b/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java
index 78c1b78..555ad7b 100644
--- a/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java
+++ b/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java
@@ -2,19 +2,17 @@ package io.github.chronosx88.influence.presenters;
import com.google.gson.JsonObject;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.contracts.observer.IObserver;
-import io.github.chronosx88.influence.contracts.startchat.IStartChatLogicContract;
-import io.github.chronosx88.influence.contracts.startchat.IStartChatPresenterContract;
-import io.github.chronosx88.influence.contracts.startchat.IStartChatViewContract;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.actions.UIActions;
import io.github.chronosx88.influence.logic.StartChatLogic;
-public class StartChatPresenter implements IStartChatPresenterContract, IObserver {
- private IStartChatViewContract view;
- private IStartChatLogicContract logic;
+public class StartChatPresenter implements CoreContracts.IStartChatPresenterContract, IObserver {
+ private CoreContracts.IStartChatViewContract view;
+ private CoreContracts.IStartChatLogicContract logic;
- public StartChatPresenter(IStartChatViewContract view) {
+ public StartChatPresenter(CoreContracts.IStartChatViewContract view) {
this.view = view;
this.logic = new StartChatLogic();
AppHelper.getObservable().register(this);
diff --git a/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.java b/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.java
deleted file mode 100644
index cb0cb7b..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package io.github.chronosx88.influence.views;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.MenuItem;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.TextView;
-
-import java.util.List;
-
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import io.github.chronosx88.influence.R;
-import io.github.chronosx88.influence.contracts.chatactivity.IChatViewContract;
-import io.github.chronosx88.influence.helpers.ChatAdapter;
-import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
-import io.github.chronosx88.influence.presenters.ChatPresenter;
-
-public class ChatActivity extends AppCompatActivity implements IChatViewContract {
- private ChatAdapter chatAdapter;
- private RecyclerView messageList;
- private ImageButton sendMessageButton;
- private EditText messageTextEdit;
- private TextView contactUsernameTextView;
- private ChatPresenter presenter;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_chat);
-
- Intent intent = getIntent();
-
- presenter = new ChatPresenter(this, intent.getStringExtra("chatID"));
- Toolbar toolbar = findViewById(R.id.toolbar_chat_activity);
- setSupportActionBar(toolbar);
- getSupportActionBar().setTitle("");
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
- messageList = findViewById(R.id.message_list);
- chatAdapter = new ChatAdapter();
- presenter.updateAdapter();
- messageList.setAdapter(chatAdapter);
- messageList.setLayoutManager(new LinearLayoutManager(this));
- contactUsernameTextView = findViewById(R.id.appbar_username);
- messageTextEdit = findViewById(R.id.message_input);
- sendMessageButton = findViewById(R.id.send_button);
- sendMessageButton.setOnClickListener((v) -> {
- if(messageTextEdit.getText().toString().equals("")) {
- return;
- }
- presenter.sendMessage(messageTextEdit.getText().toString());
- messageTextEdit.setText("");
- messageList.scrollToPosition(chatAdapter.getItemCount()-1);
- });
- contactUsernameTextView.setText(intent.getStringExtra("contactUsername"));
- messageList.scrollToPosition(chatAdapter.getItemCount()-1);
- }
-
- @Override
- public void updateMessageList(MessageEntity message) {
- runOnUiThread(() -> {
- chatAdapter.addMessage(message);
- chatAdapter.notifyDataSetChanged();
- });
- }
-
- @Override
- public void updateMessageList(List messages) {
- runOnUiThread(() -> {
- chatAdapter.addMessages(messages);
- chatAdapter.notifyDataSetChanged();
- });
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch(item.getItemId()) {
- case android.R.id.home:
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- presenter.onDestroy();
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.kt b/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.kt
new file mode 100644
index 0000000..1d0a067
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/views/ChatActivity.kt
@@ -0,0 +1,86 @@
+package io.github.chronosx88.influence.views
+
+import android.os.Bundle
+import android.view.MenuItem
+import android.widget.EditText
+import android.widget.ImageButton
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.Toolbar
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import io.github.chronosx88.influence.R
+import io.github.chronosx88.influence.contracts.CoreContracts
+import io.github.chronosx88.influence.helpers.ChatAdapter
+import io.github.chronosx88.influence.models.roomEntities.MessageEntity
+import io.github.chronosx88.influence.presenters.ChatPresenter
+
+class ChatActivity : AppCompatActivity(), CoreContracts.IChatViewContract {
+ private var chatAdapter: ChatAdapter? = null
+ private var messageList: RecyclerView? = null
+ private var sendMessageButton: ImageButton? = null
+ private var messageTextEdit: EditText? = null
+ private var contactUsernameTextView: TextView? = null
+ private var presenter: ChatPresenter? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_chat)
+
+ val intent = intent
+
+ presenter = ChatPresenter(this, intent.getStringExtra("chatID"))
+ val toolbar = findViewById(R.id.toolbar_chat_activity)
+ setSupportActionBar(toolbar)
+ supportActionBar!!.setTitle("")
+ supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+ supportActionBar!!.setHomeButtonEnabled(true)
+ messageList = findViewById(R.id.message_list)
+ chatAdapter = ChatAdapter()
+ presenter!!.updateAdapter()
+ messageList!!.adapter = chatAdapter
+ messageList!!.layoutManager = LinearLayoutManager(this)
+ contactUsernameTextView = findViewById(R.id.appbar_username)
+ messageTextEdit = findViewById(R.id.message_input)
+ sendMessageButton = findViewById(R.id.send_button)
+ sendMessageButton!!.setOnClickListener sendMessageButton@{
+ if (messageTextEdit!!.text.toString() == "") {
+ return@sendMessageButton
+ }
+ presenter!!.sendMessage(messageTextEdit!!.text.toString())
+ messageTextEdit!!.setText("")
+ messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
+ }
+ contactUsernameTextView!!.text = intent.getStringExtra("contactUsername")
+ messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
+ }
+
+ override fun updateMessageList(message: MessageEntity) {
+ runOnUiThread {
+ chatAdapter!!.addMessage(message)
+ chatAdapter!!.notifyDataSetChanged()
+ }
+ }
+
+ override fun updateMessageList(messages: List) {
+ runOnUiThread {
+ chatAdapter!!.addMessages(messages)
+ chatAdapter!!.notifyDataSetChanged()
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ android.R.id.home -> {
+ finish()
+ return true
+ }
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ presenter!!.onDestroy()
+ }
+}
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 95ef21c..006dfa9 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
@@ -13,8 +13,7 @@ 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.mainactivity.IMainPresenterContract;
-import io.github.chronosx88.influence.contracts.mainactivity.IMainViewContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.contracts.observer.IObserver;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.actions.UIActions;
@@ -23,9 +22,9 @@ import io.github.chronosx88.influence.views.fragments.ChatListFragment;
import io.github.chronosx88.influence.views.fragments.SettingsFragment;
import io.github.chronosx88.influence.views.fragments.StartChatFragment;
-public class MainActivity extends AppCompatActivity implements IObserver, IMainViewContract {
+public class MainActivity extends AppCompatActivity implements IObserver, CoreContracts.IMainViewContract {
- private IMainPresenterContract presenter;
+ private CoreContracts.IMainPresenterContract presenter;
private ProgressDialog progressDialog;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
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
deleted file mode 100644
index 7407b8f..0000000
--- a/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.java
+++ /dev/null
@@ -1,92 +0,0 @@
-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;
-import android.view.ViewGroup;
-
-import com.google.gson.JsonObject;
-
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import io.github.chronosx88.influence.R;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListPresenterContract;
-import io.github.chronosx88.influence.contracts.chatlist.IChatListViewContract;
-import io.github.chronosx88.influence.contracts.observer.IObserver;
-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.models.roomEntities.ChatEntity;
-import io.github.chronosx88.influence.presenters.ChatListPresenter;
-
-public class ChatListFragment extends Fragment implements IChatListViewContract, IObserver {
- private IChatListPresenterContract 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
- 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);
- chatList.setLayoutManager(new LinearLayoutManager(getContext()));
- presenter = new ChatListPresenter(this);
- presenter.updateChatList();
- registerForContextMenu(chatList);
- }
-
- @Override
- public void setRecycleAdapter(ChatListAdapter adapter) {
- chatList.setAdapter(adapter);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- presenter.updateChatList();
- }
-
- @Override
- public void handleEvent(JsonObject object) {
- switch (object.get("action").getAsInt()) {
- case UIActions.SUCCESSFUL_CREATE_CHAT:
- case UIActions.NEW_CHAT: {
- presenter.updateChatList();
- break;
- }
- }
- }
-
- @Override
- public void updateChatList(ChatListAdapter adapter, List chats) {
- mainThreadHandler.post(() -> {
- adapter.setChatList(chats);
- adapter.notifyDataSetChanged();
- });
- }
-
- @Override
- public boolean onContextItemSelected(@NonNull MenuItem item) {
- presenter.onContextItemSelected(item);
- return super.onContextItemSelected(item);
- }
-}
diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.kt b/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.kt
new file mode 100644
index 0000000..433db06
--- /dev/null
+++ b/app/src/main/java/io/github/chronosx88/influence/views/fragments/ChatListFragment.kt
@@ -0,0 +1,76 @@
+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
+import android.view.ViewGroup
+
+import com.google.gson.JsonObject
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import io.github.chronosx88.influence.R
+import io.github.chronosx88.influence.contracts.CoreContracts
+import io.github.chronosx88.influence.contracts.observer.IObserver
+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.models.roomEntities.ChatEntity
+import io.github.chronosx88.influence.presenters.ChatListPresenter
+
+class ChatListFragment : Fragment(), CoreContracts.IChatListViewContract, IObserver {
+ private var presenter: CoreContracts.IChatListPresenterContract? = null
+ private var chatList: RecyclerView? = null
+ private var mainThreadHandler: Handler? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ AppHelper.getObservable().register(this)
+ this.mainThreadHandler = Handler(context!!.mainLooper)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.chatlist_fragment, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ chatList = view.findViewById(R.id.chatlist_container)
+ chatList!!.layoutManager = LinearLayoutManager(context)
+ presenter = ChatListPresenter(this)
+ presenter!!.updateChatList()
+ registerForContextMenu(chatList!!)
+ }
+
+ override fun setRecycleAdapter(adapter: ChatListAdapter) {
+ chatList!!.adapter = adapter
+ }
+
+ override fun onResume() {
+ super.onResume()
+ presenter!!.updateChatList()
+ }
+
+ override fun handleEvent(`object`: JsonObject) {
+ when (`object`.get("action").asInt) {
+ UIActions.SUCCESSFUL_CREATE_CHAT, UIActions.NEW_CHAT -> {
+ presenter!!.updateChatList()
+ }
+ }
+ }
+
+ override fun updateChatList(adapter: ChatListAdapter, chats: List) {
+ mainThreadHandler!!.post {
+ adapter.setChatList(chats)
+ adapter.notifyDataSetChanged()
+ }
+ }
+
+ override fun onContextItemSelected(item: MenuItem): Boolean {
+ presenter!!.onContextItemSelected(item)
+ return super.onContextItemSelected(item)
+ }
+}
diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/SettingsFragment.java b/app/src/main/java/io/github/chronosx88/influence/views/fragments/SettingsFragment.java
index bda3782..3041fbc 100644
--- a/app/src/main/java/io/github/chronosx88/influence/views/fragments/SettingsFragment.java
+++ b/app/src/main/java/io/github/chronosx88/influence/views/fragments/SettingsFragment.java
@@ -1,19 +1,33 @@
package io.github.chronosx88.influence.views.fragments;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.LinearLayout;
import android.widget.Toast;
+import org.jetbrains.annotations.NotNull;
+
import androidx.preference.PreferenceFragmentCompat;
import io.github.chronosx88.influence.R;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.helpers.AppHelper;
+import io.github.chronosx88.influence.presenters.SettingsPresenter;
-public class SettingsFragment extends PreferenceFragmentCompat {
+public class SettingsFragment extends PreferenceFragmentCompat implements CoreContracts.ISettingsView {
+ private ProgressDialog progressDialog;
+ private SettingsPresenter presenter;
@Override
public void onCreatePreferences(Bundle bundle, String s) {
+ progressDialog = new ProgressDialog(getContext(), R.style.AlertDialogTheme);
+ progressDialog.setCancelable(false);
+ progressDialog.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
+ presenter = new SettingsPresenter(this);
// Load the Preferences from the XML file
addPreferencesFromResource(R.xml.main_settings);
getPreferenceScreen().getPreference(0).setSummary(AppHelper.getPeerID());
@@ -24,5 +38,42 @@ public class SettingsFragment extends PreferenceFragmentCompat {
Toast.makeText(AppHelper.getContext(), "Скопировано в буфер обмена!", Toast.LENGTH_SHORT).show();
return false;
}));
+ getPreferenceScreen().getPreference(1).setSummary(AppHelper.getUsername());
+ getPreferenceScreen().getPreference(1).setOnPreferenceClickListener((v) -> {
+ setupUsernameEditDialog().show();
+ return true;
+ });
+ }
+
+ @Override
+ public void loadingScreen(boolean state) {
+ if(state)
+ progressDialog.show();
+ else
+ progressDialog.dismiss();
+ }
+
+ @Override
+ public void showMessage(@NotNull String message) {
+ Toast.makeText(AppHelper.getContext(), message, Toast.LENGTH_LONG).show();
+ }
+
+ private AlertDialog.Builder setupUsernameEditDialog() {
+ AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
+ alertDialog.setTitle(getContext().getString(R.string.username_settings));
+
+ final EditText input = new EditText(getContext());
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT);
+ input.setSingleLine();
+ input.setLayoutParams(lp);
+ alertDialog.setView(input);
+
+ alertDialog.setPositiveButton(getContext().getString(R.string.ok), (dialog, which) -> presenter.updateUsername(input.getText().toString()));
+
+ alertDialog.setNegativeButton(getContext().getString(R.string.cancel), (dialog, which) -> dialog.cancel());
+
+ return alertDialog;
}
}
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 b307167..a75463a 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
@@ -16,10 +16,10 @@ import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment;
import io.github.chronosx88.influence.R;
-import io.github.chronosx88.influence.contracts.startchat.IStartChatViewContract;
+import io.github.chronosx88.influence.contracts.CoreContracts;
import io.github.chronosx88.influence.presenters.StartChatPresenter;
-public class StartChatFragment extends Fragment implements IStartChatViewContract {
+public class StartChatFragment extends Fragment implements CoreContracts.IStartChatViewContract {
private TextInputLayout textInputPeerID;
private ProgressDialog progressDialog;
private Button createChatButton;
diff --git a/app/src/main/res/layout/start_chat_fragment.xml b/app/src/main/res/layout/start_chat_fragment.xml
index 66e2815..326d09a 100644
--- a/app/src/main/res/layout/start_chat_fragment.xml
+++ b/app/src/main/res/layout/start_chat_fragment.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:hint="Peer ID"/>
+ android:hint="@string/username_hint"/>