[WIP] Added start chat fragment template, chat list recycle view (with adapter), handling new chats (in live mode). // TODO: Make starting chat

This commit is contained in:
ChronosX88 2019-03-18 20:39:53 +04:00
parent 963acc7172
commit 055f62bfec
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
28 changed files with 395 additions and 103 deletions

View File

@ -1,7 +0,0 @@
package io.github.chronosx88.influence.contracts;
import android.content.SharedPreferences;
public interface MainViewContract {
//
}

View File

@ -0,0 +1,10 @@
package io.github.chronosx88.influence.contracts.chatlist;
import java.util.List;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
public interface ChatListLogicContract {
List<ChatEntity> loadAllChats();
void createChatBySender(ChatEntity entity);
}

View File

@ -0,0 +1,6 @@
package io.github.chronosx88.influence.contracts.chatlist;
public interface ChatListPresenterContract {
void updateChatList();
void openChat(String chatID);
}

View File

@ -0,0 +1,7 @@
package io.github.chronosx88.influence.contracts.chatlist;
import io.github.chronosx88.influence.helpers.ChatListAdapter;
public interface ChatListViewContract {
void setRecycleAdapter(ChatListAdapter adapter);
}

View File

@ -1,4 +1,4 @@
package io.github.chronosx88.influence.contracts; package io.github.chronosx88.influence.contracts.main;
public interface MainLogicContract { public interface MainLogicContract {
void initPeer(); void initPeer();

View File

@ -1,4 +1,4 @@
package io.github.chronosx88.influence.contracts; package io.github.chronosx88.influence.contracts.main;
public interface MainPresenterContract { public interface MainPresenterContract {
void initPeer(); void initPeer();

View File

@ -0,0 +1,5 @@
package io.github.chronosx88.influence.contracts.main;
public interface MainViewContract {
//
}

View File

@ -0,0 +1,50 @@
package io.github.chronosx88.influence.helpers;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import io.github.chronosx88.influence.R;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
public class ChatListAdapter extends RecyclerView.Adapter<ChatListAdapter.ChatListViewHolder> {
List<ChatEntity> chatList = new ArrayList<>();
@NonNull
@Override
public ChatListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item, parent, false);
return new ChatListViewHolder(view);
}
public void setChatList(List<ChatEntity> entities) {
chatList.clear();
chatList.addAll(entities);
}
@Override
public void onBindViewHolder(@NonNull ChatListViewHolder holder, int position) {
holder.chatName.setText(chatList.get(position).getName());
}
@Override
public int getItemCount() {
return chatList.size();
}
class ChatListViewHolder extends RecyclerView.ViewHolder {
TextView chatName;
public ChatListViewHolder(View itemView) {
super(itemView);
chatName = itemView.findViewById(R.id.chat_name);
}
}
}

View File

@ -0,0 +1,7 @@
package io.github.chronosx88.influence.helpers;
public class NetworkActions {
public static final int START_CHAT = 0x0;
public static final int NEW_MESSAGE = 0x1;
public static final int MESSAGE_SENT = 0x2;
}

View File

@ -2,12 +2,12 @@ package io.github.chronosx88.influence.helpers;
import androidx.room.Database; import androidx.room.Database;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
import io.github.chronosx88.influence.models.roomEntities.ChatModel;
import io.github.chronosx88.influence.models.roomEntities.MessageModel;
import io.github.chronosx88.influence.models.daos.ChatDao; import io.github.chronosx88.influence.models.daos.ChatDao;
import io.github.chronosx88.influence.models.daos.MessageDao; import io.github.chronosx88.influence.models.daos.MessageDao;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
@Database(entities = { MessageModel.class, ChatModel.class }, version = 1) @Database(entities = { MessageEntity.class, ChatEntity.class }, version = 1)
public abstract class RoomHelper extends RoomDatabase { public abstract class RoomHelper extends RoomDatabase {
public abstract ChatDao chatDao(); public abstract ChatDao chatDao();
public abstract MessageDao messageDao(); public abstract MessageDao messageDao();

View File

@ -1,10 +1,11 @@
package io.github.chronosx88.influence.helpers; package io.github.chronosx88.influence.helpers;
public class MessageActions { public class UIActions {
public static final int BOOTSTRAP_NOT_SPECIFIED = 0x0; public static final int BOOTSTRAP_NOT_SPECIFIED = 0x0;
public static final int NETWORK_ERROR = 0x1; public static final int NETWORK_ERROR = 0x1;
public static final int BOOTSTRAP_SUCCESS = 0x2; public static final int BOOTSTRAP_SUCCESS = 0x2;
public static final int PORT_FORWARDING_ERROR = 0x3; public static final int PORT_FORWARDING_ERROR = 0x3;
public static final int RELAY_CONNECTION_ERROR = 0x4; public static final int RELAY_CONNECTION_ERROR = 0x4;
public static final int BOOTSTRAP_ERROR = 0x5; public static final int BOOTSTRAP_ERROR = 0x5;
public static final int NEW_CHAT = 0x6;
} }

View File

@ -0,0 +1,45 @@
package io.github.chronosx88.influence.logic;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import io.github.chronosx88.influence.contracts.chatlist.ChatListLogicContract;
import io.github.chronosx88.influence.contracts.observer.Observer;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.NetworkActions;
import io.github.chronosx88.influence.helpers.UIActions;
import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
import io.github.chronosx88.influence.observable.MainObservable;
public class ChatListLogic implements ChatListLogicContract, Observer {
public ChatListLogic() {
AppHelper.getObservable().register(this, MainObservable.OTHER_ACTIONS_CHANNEL);
}
@Override
public List<ChatEntity> loadAllChats() {
return AppHelper.getChatDB().chatDao().getAllChats();
}
@Override
public void handleEvent(JSONObject object) {
try {
switch ((int) object.get("action")) {
case NetworkActions.START_CHAT: {
createChatBySender(new ChatEntity(object.getString("chatID"), object.getString("name"), ""));
AppHelper.getObservable().notifyObservers(new JSONObject().put("action", UIActions.NEW_CHAT), MainObservable.UI_ACTIONS_CHANNEL);
break;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void createChatBySender(ChatEntity entity) {
AppHelper.getChatDB().chatDao().addChat(entity);
}
}

View File

@ -25,10 +25,10 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.UUID; import java.util.UUID;
import io.github.chronosx88.influence.contracts.MainLogicContract; import io.github.chronosx88.influence.contracts.main.MainLogicContract;
import io.github.chronosx88.influence.helpers.AppHelper; import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.MessageActions;
import io.github.chronosx88.influence.helpers.StorageMVStore; import io.github.chronosx88.influence.helpers.StorageMVStore;
import io.github.chronosx88.influence.helpers.UIActions;
import io.github.chronosx88.influence.observable.MainObservable; import io.github.chronosx88.influence.observable.MainObservable;
public class MainLogic implements MainLogicContract { public class MainLogic implements MainLogicContract {
@ -77,7 +77,7 @@ public class MainLogic implements MainLogicContract {
} catch (NullPointerException e) { } catch (NullPointerException e) {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.BOOTSTRAP_NOT_SPECIFIED), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.BOOTSTRAP_NOT_SPECIFIED), MainObservable.UI_ACTIONS_CHANNEL);
peerDHT.shutdown(); peerDHT.shutdown();
return; return;
} catch (JSONException ex) { } catch (JSONException ex) {
@ -86,7 +86,7 @@ public class MainLogic implements MainLogicContract {
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.NETWORK_ERROR), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.NETWORK_ERROR), MainObservable.UI_ACTIONS_CHANNEL);
peerDHT.shutdown(); peerDHT.shutdown();
return; return;
} catch (JSONException ex) { } catch (JSONException ex) {
@ -97,7 +97,7 @@ public class MainLogic implements MainLogicContract {
if(!discoverExternalAddress()) { if(!discoverExternalAddress()) {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.PORT_FORWARDING_ERROR), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.PORT_FORWARDING_ERROR), MainObservable.UI_ACTIONS_CHANNEL);
} catch (JSONException ex) { } catch (JSONException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -106,7 +106,7 @@ public class MainLogic implements MainLogicContract {
if(!setupConnectionToRelay()) { if(!setupConnectionToRelay()) {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.RELAY_CONNECTION_ERROR), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.RELAY_CONNECTION_ERROR), MainObservable.UI_ACTIONS_CHANNEL);
return; return;
} catch (JSONException ex) { } catch (JSONException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -116,7 +116,7 @@ public class MainLogic implements MainLogicContract {
if(!bootstrapPeer()) { if(!bootstrapPeer()) {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.BOOTSTRAP_ERROR), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.BOOTSTRAP_ERROR), MainObservable.UI_ACTIONS_CHANNEL);
return; return;
} catch (JSONException ex) { } catch (JSONException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -125,12 +125,13 @@ public class MainLogic implements MainLogicContract {
try { try {
AppHelper.getObservable().notifyObservers(new JSONObject() AppHelper.getObservable().notifyObservers(new JSONObject()
.put("action", MessageActions.BOOTSTRAP_SUCCESS), MainObservable.UI_ACTIONS_CHANNEL); .put("action", UIActions.BOOTSTRAP_SUCCESS), MainObservable.UI_ACTIONS_CHANNEL);
} catch (JSONException ex) { } catch (JSONException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
AppHelper.storePeerID(preferences.getString("peerID", null)); AppHelper.storePeerID(preferences.getString("peerID", null));
AppHelper.storePeerDHT(peerDHT); AppHelper.storePeerDHT(peerDHT);
setReceiveHandler();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -179,6 +180,14 @@ public class MainLogic implements MainLogicContract {
} }
} }
private void setReceiveHandler() {
AppHelper.getPeerDHT().peer().objectDataReply((s, r) -> {
Log.i(LOG_TAG, "# Incoming message: " + r);
AppHelper.getObservable().notifyObservers(new JSONObject((String) r), MainObservable.OTHER_ACTIONS_CHANNEL);
return null;
});
}
@Override @Override
public void shutdownPeer() { public void shutdownPeer() {
peerDHT.shutdown(); peerDHT.shutdown();

View File

@ -5,19 +5,19 @@ import java.util.List;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
import io.github.chronosx88.influence.models.roomEntities.ChatModel; import io.github.chronosx88.influence.models.roomEntities.ChatEntity;
@Dao @Dao
public interface ChatDao { public interface ChatDao {
@Insert @Insert
void addChat(ChatModel chatModel); void addChat(ChatEntity chatEntity);
@Query("DELETE FROM chats WHERE id = :chatID") @Query("DELETE FROM chats WHERE id = :chatID")
void deleteChat(String chatID); void deleteChat(String chatID);
@Query("SELECT * FROM chats") @Query("SELECT * FROM chats")
List<ChatModel> getAllChats(); List<ChatEntity> getAllChats();
@Query("SELECT * FROM chats WHERE id = :chatID") @Query("SELECT * FROM chats WHERE id = :chatID")
List<ChatModel> getChatByID(String chatID); List<ChatEntity> getChatByID(String chatID);
} }

View File

@ -5,12 +5,12 @@ import java.util.List;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
import io.github.chronosx88.influence.models.roomEntities.MessageModel; import io.github.chronosx88.influence.models.roomEntities.MessageEntity;
@Dao @Dao
public interface MessageDao { public interface MessageDao {
@Insert @Insert
void insertMessage(MessageModel chatModel); void insertMessage(MessageEntity chatModel);
@Query("DELETE FROM messages WHERE id = :msgID") @Query("DELETE FROM messages WHERE id = :msgID")
void deleteMessage(String msgID); void deleteMessage(String msgID);
@ -19,8 +19,8 @@ public interface MessageDao {
void deleteMessagesByChatID(String chatID); void deleteMessagesByChatID(String chatID);
@Query("SELECT * FROM messages WHERE chatID = :chatID") @Query("SELECT * FROM messages WHERE chatID = :chatID")
List<MessageModel> getMessagesByChatID(String chatID); List<MessageEntity> getMessagesByChatID(String chatID);
@Query("SELECT * FROM messages WHERE id = :id") @Query("SELECT * FROM messages WHERE id = :id")
List<MessageModel> getMessageByID(String id); List<MessageEntity> getMessageByID(String id);
} }

View File

@ -0,0 +1,30 @@
package io.github.chronosx88.influence.models.roomEntities;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "chats")
public class ChatEntity {
@PrimaryKey String id;
@ColumnInfo String name;
@ColumnInfo String keyPairID;
public ChatEntity(String id, String name, String keyPairID) {
this.id = id;
this.name = name;
this.keyPairID = keyPairID;
}
public String getId() {
return id;
}
public String getKeyPairID() {
return keyPairID;
}
public String getName() {
return name;
}
}

View File

@ -1,11 +0,0 @@
package io.github.chronosx88.influence.models.roomEntities;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "chats")
public class ChatModel {
@PrimaryKey String id;
String name;
String keyPairID;
}

View File

@ -0,0 +1,43 @@
package io.github.chronosx88.influence.models.roomEntities;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "messages")
public class MessageEntity {
@PrimaryKey String id;
@ColumnInfo String chatID;
@ColumnInfo String sender;
@ColumnInfo String text;
public MessageEntity(String id, String chatID, String sender, String text) {
this.id = id;
this.chatID = chatID;
this.sender = sender;
this.text = text;
}
public String getId() {
return id;
}
public String getChatID() {
return chatID;
}
public String getSender() {
return sender;
}
public String getText() {
return text;
}
@NonNull
@Override
public String toString() {
return id + "/" + chatID + "/" + sender + "/" + text;
}
}

View File

@ -1,12 +0,0 @@
package io.github.chronosx88.influence.models.roomEntities;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "messages")
public class MessageModel {
@PrimaryKey String id;
String chatID;
String sender;
String text;
}

View File

@ -0,0 +1,31 @@
package io.github.chronosx88.influence.presenters;
import io.github.chronosx88.influence.contracts.chatlist.ChatListLogicContract;
import io.github.chronosx88.influence.contracts.chatlist.ChatListPresenterContract;
import io.github.chronosx88.influence.contracts.chatlist.ChatListViewContract;
import io.github.chronosx88.influence.helpers.ChatListAdapter;
import io.github.chronosx88.influence.logic.ChatListLogic;
public class ChatListPresenter implements ChatListPresenterContract {
private ChatListViewContract view;
private ChatListLogicContract logic;
private ChatListAdapter chatListAdapter;
public ChatListPresenter(ChatListViewContract view) {
this.view = view;
chatListAdapter = new ChatListAdapter();
this.view.setRecycleAdapter(chatListAdapter);
this.logic = new ChatListLogic();
}
@Override
public void updateChatList() {
chatListAdapter.setChatList(logic.loadAllChats());
chatListAdapter.notifyDataSetChanged();
}
@Override
public void openChat(String chatID) {
// TODO
}
}

View File

@ -1,8 +1,8 @@
package io.github.chronosx88.influence.presenters; package io.github.chronosx88.influence.presenters;
import io.github.chronosx88.influence.contracts.MainLogicContract; import io.github.chronosx88.influence.contracts.main.MainLogicContract;
import io.github.chronosx88.influence.contracts.MainPresenterContract; import io.github.chronosx88.influence.contracts.main.MainPresenterContract;
import io.github.chronosx88.influence.contracts.MainViewContract; import io.github.chronosx88.influence.contracts.main.MainViewContract;
import io.github.chronosx88.influence.logic.MainLogic; import io.github.chronosx88.influence.logic.MainLogic;
public class MainPresenter implements MainPresenterContract { public class MainPresenter implements MainPresenterContract {

View File

@ -15,13 +15,14 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import io.github.chronosx88.influence.R; import io.github.chronosx88.influence.R;
import io.github.chronosx88.influence.contracts.MainPresenterContract; import io.github.chronosx88.influence.contracts.main.MainPresenterContract;
import io.github.chronosx88.influence.contracts.MainViewContract; import io.github.chronosx88.influence.contracts.main.MainViewContract;
import io.github.chronosx88.influence.contracts.observer.Observer; import io.github.chronosx88.influence.contracts.observer.Observer;
import io.github.chronosx88.influence.helpers.AppHelper; import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.MessageActions; import io.github.chronosx88.influence.helpers.UIActions;
import io.github.chronosx88.influence.observable.MainObservable;
import io.github.chronosx88.influence.presenters.MainPresenter; import io.github.chronosx88.influence.presenters.MainPresenter;
import io.github.chronosx88.influence.views.fragments.ChatFragment; import io.github.chronosx88.influence.views.fragments.ChatListFragment;
import io.github.chronosx88.influence.views.fragments.SettingsFragment; import io.github.chronosx88.influence.views.fragments.SettingsFragment;
import io.github.chronosx88.influence.views.fragments.StartChatFragment; import io.github.chronosx88.influence.views.fragments.StartChatFragment;
@ -39,7 +40,7 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_chats: case R.id.action_chats:
selectedFragment = new ChatFragment(); selectedFragment = new ChatListFragment();
break; break;
case R.id.action_settings: case R.id.action_settings:
selectedFragment = new SettingsFragment(); selectedFragment = new SettingsFragment();
@ -67,11 +68,11 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie
getSupportFragmentManager() getSupportFragmentManager()
.beginTransaction() .beginTransaction()
.replace(R.id.main_fragment_container, new ChatFragment()) .replace(R.id.main_fragment_container, new ChatListFragment())
.commit(); .commit();
presenter = new MainPresenter(this); presenter = new MainPresenter(this);
AppHelper.getObservable().register(this); AppHelper.getObservable().register(this, MainObservable.UI_ACTIONS_CHANNEL);
progressDialog = new ProgressDialog(MainActivity.this, R.style.AlertDialogTheme); progressDialog = new ProgressDialog(MainActivity.this, R.style.AlertDialogTheme);
progressDialog.setCancelable(false); progressDialog.setCancelable(false);
@ -84,48 +85,48 @@ public class MainActivity extends AppCompatActivity implements Observer, MainVie
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
presenter.onDestroy(); presenter.onDestroy();
AppHelper.getObservable().unregister(this); AppHelper.getObservable().unregister(this, MainObservable.UI_ACTIONS_CHANNEL);
} }
@Override @Override
public void handleEvent(JSONObject object) { public void handleEvent(JSONObject object) {
try { try {
switch ((int) object.get("action")) { switch ((int) object.get("action")) {
case MessageActions.BOOTSTRAP_NOT_SPECIFIED: { case UIActions.BOOTSTRAP_NOT_SPECIFIED: {
runOnUiThread(() -> { runOnUiThread(() -> {
progressDialog.dismiss(); progressDialog.dismiss();
Toast.makeText(this, "Bootstrap-нода не указана. Прерываю подключение к сети...", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Bootstrap-нода не указана. Прерываю подключение к сети...", Toast.LENGTH_LONG).show();
}); });
break; break;
} }
case MessageActions.NETWORK_ERROR: { case UIActions.NETWORK_ERROR: {
runOnUiThread(() -> { runOnUiThread(() -> {
progressDialog.dismiss(); progressDialog.dismiss();
Toast.makeText(this, "Ошибка сети. Возможно, нода недоступна, или у вас отсутствует Интернет.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Ошибка сети. Возможно, нода недоступна, или у вас отсутствует Интернет.", Toast.LENGTH_LONG).show();
}); });
break; break;
} }
case MessageActions.BOOTSTRAP_SUCCESS: { case UIActions.BOOTSTRAP_SUCCESS: {
runOnUiThread(() -> { runOnUiThread(() -> {
progressDialog.dismiss(); progressDialog.dismiss();
Toast.makeText(this, "Нода успешно запущена!", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Нода успешно запущена!", Toast.LENGTH_LONG).show();
}); });
break; break;
} }
case MessageActions.PORT_FORWARDING_ERROR: { case UIActions.PORT_FORWARDING_ERROR: {
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(this, "Проблемы с пробросом портов. Возможно, у вас не настроен uPnP.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Проблемы с пробросом портов. Возможно, у вас не настроен uPnP.", Toast.LENGTH_LONG).show();
}); });
break; break;
} }
case MessageActions.BOOTSTRAP_ERROR: { case UIActions.BOOTSTRAP_ERROR: {
runOnUiThread(() -> { runOnUiThread(() -> {
progressDialog.dismiss(); progressDialog.dismiss();
Toast.makeText(this, "Не удалось подключиться к бутстрап-ноде.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Не удалось подключиться к бутстрап-ноде.", Toast.LENGTH_LONG).show();
}); });
break; break;
} }
case MessageActions.RELAY_CONNECTION_ERROR: { case UIActions.RELAY_CONNECTION_ERROR: {
runOnUiThread(() -> { runOnUiThread(() -> {
progressDialog.dismiss(); progressDialog.dismiss();
Toast.makeText(this, "Не удалось подключиться к relay-ноде.", Toast.LENGTH_LONG).show(); Toast.makeText(this, "Не удалось подключиться к relay-ноде.", Toast.LENGTH_LONG).show();

View File

@ -1,22 +0,0 @@
package io.github.chronosx88.influence.views.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import io.github.chronosx88.influence.R;
public class ChatFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.chat_fragment, container, false);
}
}

View File

@ -0,0 +1,72 @@
package io.github.chronosx88.influence.views.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.json.JSONException;
import org.json.JSONObject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import io.github.chronosx88.influence.R;
import io.github.chronosx88.influence.contracts.chatlist.ChatListPresenterContract;
import io.github.chronosx88.influence.contracts.chatlist.ChatListViewContract;
import io.github.chronosx88.influence.contracts.observer.Observer;
import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.ChatListAdapter;
import io.github.chronosx88.influence.helpers.UIActions;
import io.github.chronosx88.influence.observable.MainObservable;
import io.github.chronosx88.influence.presenters.ChatListPresenter;
public class ChatListFragment extends Fragment implements ChatListViewContract, Observer {
private ChatListPresenterContract presenter;
private RecyclerView chatList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new ChatListPresenter(this);
AppHelper.getObservable().register(this, MainObservable.UI_ACTIONS_CHANNEL);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.chatlist_fragment, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
chatList = view.findViewById(R.id.chatlist_container);
presenter.updateChatList();
}
@Override
public void setRecycleAdapter(ChatListAdapter adapter) {
chatList.setAdapter(adapter);
}
@Override
public void onResume() {
super.onResume();
presenter.updateChatList();
}
@Override
public void handleEvent(JSONObject object) {
try {
switch (object.getInt("action")) {
case UIActions.NEW_CHAT: {
presenter.updateChatList();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}

View File

@ -5,6 +5,8 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import io.github.chronosx88.influence.R; import io.github.chronosx88.influence.R;
@ -19,4 +21,10 @@ public class StartChatFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
return inflater.inflate(R.layout.start_chat_fragment, container, false); return inflater.inflate(R.layout.start_chat_fragment, container, false);
} }
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// TODO
}
} }

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="55dp"
android:gravity="center_vertical"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/chat_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="null"
android:textSize="19sp"
android:layout_marginStart="15dp"
android:textColor="@android:color/black"/>
</LinearLayout>

View File

@ -3,11 +3,8 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/chatlist_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"/>
android:layout_gravity="center"
android:gravity="center"
android:text="Temporary placeholder #1"
android:textSize="34sp"/>
</LinearLayout> </LinearLayout>

View File

@ -1,14 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView
android:layout_width="match_parent" <EditText
android:layout_height="match_parent" android:layout_width="346dp"
android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center" android:hint="Peer ID"/>
android:text="Temporary placeholder #3" <Button
android:textSize="34sp"/> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Создать чат"/>
</LinearLayout> </LinearLayout>