Fixed issue with time and message sorting in the chats

This commit is contained in:
ChronosX88 2019-04-27 19:57:29 +04:00
parent 686dc82d8c
commit d062ba54b9
8 changed files with 103 additions and 83 deletions

View File

@ -65,6 +65,8 @@ dependencies {
} }
implementation 'net.jpountz.lz4:lz4:1.3.0' implementation 'net.jpountz.lz4:lz4:1.3.0'
implementation 'org.mapdb:elsa:3.0.0-M5' implementation 'org.mapdb:elsa:3.0.0-M5'
implementation 'com.github.instacart.truetime-android:library:3.4'
} }
repositories { repositories {
mavenCentral() mavenCentral()

View File

@ -8,6 +8,11 @@ import net.tomp2p.dht.PeerDHT;
import androidx.multidex.MultiDexApplication; import androidx.multidex.MultiDexApplication;
import androidx.room.Room; import androidx.room.Room;
import com.instacart.library.truetime.TrueTime;
import java.io.IOException;
import io.github.chronosx88.influence.observable.MainObservable; import io.github.chronosx88.influence.observable.MainObservable;
/** /**
@ -33,6 +38,13 @@ public class AppHelper extends MultiDexApplication {
.allowMainThreadQueries() .allowMainThreadQueries()
.build(); .build();
preferences = getApplicationContext().getSharedPreferences("io.github.chronosx88.influence_preferences", MODE_PRIVATE); preferences = getApplicationContext().getSharedPreferences("io.github.chronosx88.influence_preferences", MODE_PRIVATE);
new Thread(() -> {
try {
TrueTime.build().initialize();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} }
public static void storePeerID(String peerID1) { peerID = peerID1; } public static void storePeerID(String peerID1) { peerID = peerID1; }

View File

@ -6,11 +6,18 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeSet; import java.util.TreeSet;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -26,6 +33,7 @@ public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
private final Context context = AppHelper.getContext(); private final Context context = AppHelper.getContext();
private ArrayList<MessageEntity> messages = new ArrayList<>(); private ArrayList<MessageEntity> messages = new ArrayList<>();
private static Comparator<MessageEntity> comparator = ((o1, o2) -> Long.compare(o1.timestamp, o2.timestamp));
@NonNull @NonNull
@Override @Override
@ -45,11 +53,13 @@ public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
} }
} }
messages.add(message); messages.add(message);
Collections.sort(messages, comparator);
} }
} }
public void addMessages(List<MessageEntity> messages) { public void addMessages(List<MessageEntity> messages) {
this.messages.addAll(messages); this.messages.addAll(messages);
Collections.sort(messages, comparator);
} }
@Override @Override
@ -58,9 +68,9 @@ public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
holder.messageText.setText(messages.get(position).text); holder.messageText.setText(messages.get(position).text);
// Setting message time (HOUR:MINUTE) // Setting message time (HOUR:MINUTE)
Calendar calendar = Calendar.getInstance(); DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
calendar.setTime(new Date(messages.get(position).timestamp)); dateFormat.setTimeZone(TimeZone.getDefault());
String time = calendar.get(Calendar.HOUR) + ":" + calendar.get(Calendar.MINUTE); String time = dateFormat.format(new Date(messages.get(position).timestamp));
holder.messageTime.setText(time); holder.messageTime.setText(time);
} }
@ -90,4 +100,6 @@ public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
messageTime = itemView.findViewById(R.id.message_time); messageTime = itemView.findViewById(R.id.message_time);
} }
} }
} }

View File

@ -39,7 +39,7 @@ class DataSerializerMapDB(private val signatureFactory: SignatureFactory) : Grou
val acb = Unpooled.buffer() val acb = Unpooled.buffer()
// store data to disk // store data to disk
// header first // header first
if(value.publicKey().equals(PeerBuilder.EMPTY_PUBLIC_KEY)) { if(value.publicKey()!= null && value.publicKey().equals(PeerBuilder.EMPTY_PUBLIC_KEY)) {
value.publicKey(null) value.publicKey(null)
} }
value.encodeHeader(acb, signatureFactory) value.encodeHeader(acb, signatureFactory)

View File

@ -49,7 +49,7 @@ class StorageMapDB(peerId: Number160, path : File, signatureFactory: SignatureFa
private val responsibilityMap: BTreeMap<Number160, Number160> private val responsibilityMap: BTreeMap<Number160, Number160>
private val responsibilityMapRev: BTreeMap<Number160, Set<Number160>> private val responsibilityMapRev: BTreeMap<Number160, Set<Number160>>
private val db: DB = DBMaker.fileDB(path).closeOnJvmShutdown().make() private val db: DB = DBMaker.fileDB(path).transactionEnable().closeOnJvmShutdown().make()
private val storageCheckIntervalMillis: Int = 60 * 1000 private val storageCheckIntervalMillis: Int = 60 * 1000
init { init {

View File

@ -1,77 +0,0 @@
package io.github.chronosx88.influence.presenters;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
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;
import io.github.chronosx88.influence.helpers.actions.NetworkActions;
import io.github.chronosx88.influence.helpers.actions.UIActions;
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 CoreContracts.IChatPresenterContract, IObserver {
private CoreContracts.IChatLogicContract logic;
private CoreContracts.IChatViewContract view;
private ChatEntity chatEntity;
private String chatID;
private Gson gson;
public ChatPresenter(CoreContracts.IChatViewContract view, String chatID) {
this.logic = new ChatLogic(LocalDBWrapper.getChatByChatID(chatID));
this.view = view;
this.chatID = chatID;
this.chatEntity = LocalDBWrapper.getChatByChatID(chatID);
AppHelper.getObservable().register(this);
gson = new Gson();
}
@Override
public void sendMessage(String text) {
MessageEntity message = LocalDBWrapper.createMessageEntry(NetworkActions.TEXT_MESSAGE, UUID.randomUUID().toString(), chatID, AppHelper.getPeerID(), AppHelper.getPeerID(), System.currentTimeMillis(), text, false, false);
logic.sendMessage(message);
view.updateMessageList(message);
}
@Override
public void handleEvent(JsonObject object) {
switch (object.get("action").getAsInt()) {
case UIActions.MESSAGE_RECEIVED: {
JsonArray jsonArray = object.getAsJsonArray("additional");
if(!jsonArray.get(0).getAsString().equals(chatID)) {
return;
}
MessageEntity messageEntity = LocalDBWrapper.getMessageByID(jsonArray.get(1).getAsString());
view.updateMessageList(messageEntity);
break;
}
case UIActions.NODE_IS_OFFLINE: {
Toast.makeText(AppHelper.getContext(), "Нода не запущена!", Toast.LENGTH_SHORT).show();
break;
}
}
}
@Override
public void updateAdapter() {
List<MessageEntity> entities = LocalDBWrapper.getMessagesByChatID(chatID);
view.updateMessageList(entities == null ? new ArrayList<>() : entities);
}
@Override
public void onDestroy() {
logic.stopTrackingForNewMsgs();
}
}

View File

@ -0,0 +1,70 @@
package io.github.chronosx88.influence.presenters
import android.widget.Toast
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.instacart.library.truetime.TrueTime
import java.io.IOException
import java.util.ArrayList
import java.util.UUID
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
import io.github.chronosx88.influence.helpers.actions.NetworkActions
import io.github.chronosx88.influence.helpers.actions.UIActions
import io.github.chronosx88.influence.logic.ChatLogic
import io.github.chronosx88.influence.models.roomEntities.ChatEntity
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.doAsyncResult
class ChatPresenter(private val view: CoreContracts.IChatViewContract, private val chatID: String) : CoreContracts.IChatPresenterContract, IObserver {
private val logic: CoreContracts.IChatLogicContract
private val chatEntity: ChatEntity?
private val gson: Gson
init {
this.logic = ChatLogic(LocalDBWrapper.getChatByChatID(chatID)!!)
this.chatEntity = LocalDBWrapper.getChatByChatID(chatID)
AppHelper.getObservable().register(this)
gson = Gson()
}
override fun sendMessage(text: String) {
doAsync {
val message = LocalDBWrapper.createMessageEntry(NetworkActions.TEXT_MESSAGE, UUID.randomUUID().toString(), chatID, AppHelper.getPeerID(), AppHelper.getPeerID(), TrueTime.now().time, text, false, false)
logic.sendMessage(message!!)
view.updateMessageList(message)
}
}
override fun handleEvent(obj: JsonObject) {
when (obj.get("action").asInt) {
UIActions.MESSAGE_RECEIVED -> {
val jsonArray = obj.getAsJsonArray("additional")
if (jsonArray.get(0).asString != chatID) {
return
}
val messageEntity = LocalDBWrapper.getMessageByID(jsonArray.get(1).asString)
view.updateMessageList(messageEntity!!)
}
UIActions.NODE_IS_OFFLINE -> {
Toast.makeText(AppHelper.getContext(), "Нода не запущена!", Toast.LENGTH_SHORT).show()
}
}
}
override fun updateAdapter() {
val entities = LocalDBWrapper.getMessagesByChatID(chatID)
view.updateMessageList(entities ?: ArrayList())
}
override fun onDestroy() {
logic.stopTrackingForNewMsgs()
}
}

View File

@ -49,7 +49,6 @@ class ChatActivity : AppCompatActivity(), CoreContracts.IChatViewContract {
} }
presenter!!.sendMessage(messageTextEdit!!.text.toString()) presenter!!.sendMessage(messageTextEdit!!.text.toString())
messageTextEdit!!.setText("") messageTextEdit!!.setText("")
messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
} }
contactUsernameTextView!!.text = intent.getStringExtra("contactUsername") contactUsernameTextView!!.text = intent.getStringExtra("contactUsername")
messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1) messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
@ -58,6 +57,7 @@ class ChatActivity : AppCompatActivity(), CoreContracts.IChatViewContract {
override fun updateMessageList(message: MessageEntity) { override fun updateMessageList(message: MessageEntity) {
runOnUiThread { runOnUiThread {
chatAdapter!!.addMessage(message) chatAdapter!!.addMessage(message)
messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
chatAdapter!!.notifyDataSetChanged() chatAdapter!!.notifyDataSetChanged()
} }
} }
@ -65,6 +65,7 @@ class ChatActivity : AppCompatActivity(), CoreContracts.IChatViewContract {
override fun updateMessageList(messages: List<MessageEntity>) { override fun updateMessageList(messages: List<MessageEntity>) {
runOnUiThread { runOnUiThread {
chatAdapter!!.addMessages(messages) chatAdapter!!.addMessages(messages)
messageList!!.scrollToPosition(chatAdapter!!.itemCount - 1)
chatAdapter!!.notifyDataSetChanged() chatAdapter!!.notifyDataSetChanged()
} }
} }