Sending and receiving works!
This commit is contained in:
parent
9477059b0b
commit
8ceeef70b0
|
@ -4,9 +4,10 @@ import org.mercury_im.messenger.MercuryImApplication;
|
|||
import org.mercury_im.messenger.di.module.AppModule;
|
||||
import org.mercury_im.messenger.di.module.RepositoryModule;
|
||||
import org.mercury_im.messenger.di.module.RoomModule;
|
||||
import org.mercury_im.messenger.handler.RoomPlainMessageHandler;
|
||||
import org.mercury_im.messenger.service.XmppConnectionService;
|
||||
import org.mercury_im.messenger.ui.MainActivity;
|
||||
import org.mercury_im.messenger.ui.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.handler.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.ui.chat.ChatActivity;
|
||||
import org.mercury_im.messenger.ui.chat.ChatInputFragment;
|
||||
import org.mercury_im.messenger.ui.chat.ChatInputViewModel;
|
||||
|
@ -64,4 +65,6 @@ public interface AppComponent {
|
|||
// Connectors
|
||||
|
||||
void inject(RoomRosterHandler roomRosterHandler);
|
||||
|
||||
void inject(RoomPlainMessageHandler messageHandler);
|
||||
}
|
||||
|
|
|
@ -2,16 +2,19 @@ package org.mercury_im.messenger.di.module;
|
|||
|
||||
import org.mercury_im.messenger.persistence.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ChatRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactAndEntityRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.EntityRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.MessageRepository;
|
||||
import org.mercury_im.messenger.persistence.room.dao.AccountDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ChatDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactAndEntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.EntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.MessageDao;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IAccountRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IChatRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IContactAndEntityRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IContactRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IEntityRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IMessageRepository;
|
||||
|
@ -54,4 +57,10 @@ public class RepositoryModule {
|
|||
return new IMessageRepository(dao);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
ContactAndEntityRepository provideContactAndEntityRepository(ContactAndEntityDao dao) {
|
||||
return new IContactAndEntityRepository(dao);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.mercury_im.messenger.di.module;
|
|||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.persistence.room.AppDatabase;
|
||||
import org.mercury_im.messenger.persistence.room.dao.AccountDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactAndEntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.EntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.MessageDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
|
||||
|
@ -56,4 +57,10 @@ public class RoomModule {
|
|||
EntityDao provideEntityDao() {
|
||||
return mAppDatabase.entityDao();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
ContactAndEntityDao provideContactAndEntityDao() {
|
||||
return mAppDatabase.contactAndEntityDao();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package org.mercury_im.messenger.handler;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.jivesoftware.smack.chat2.Chat;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.persistence.model.MessageModel;
|
||||
import org.mercury_im.messenger.persistence.repository.MessageRepository;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomMessageModel;
|
||||
import org.mercury_im.messenger.xmpp_core.PlainMessageHandler;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.mercury_im.messenger.MercuryImApplication.TAG;
|
||||
|
||||
public class RoomPlainMessageHandler implements PlainMessageHandler {
|
||||
|
||||
private final long accountId;
|
||||
|
||||
@Inject
|
||||
MessageRepository messageRepository;
|
||||
|
||||
public RoomPlainMessageHandler(long accountId) {
|
||||
this.accountId = accountId;
|
||||
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
|
||||
MessageModel messageModel = new RoomMessageModel();
|
||||
messageModel.setAccountId(accountId);
|
||||
messageModel.setFrom(chat.getXmppAddressOfChatPartner());
|
||||
messageModel.setTo(message.getTo().asEntityBareJidIfPossible());
|
||||
messageModel.setIncoming(true);
|
||||
messageModel.setBody(message.getBody());
|
||||
long messageId = messageRepository.insertMessage(messageModel);
|
||||
Log.d(TAG, "Inserted incoming message " + messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) {
|
||||
MessageModel messageModel = new RoomMessageModel();
|
||||
messageModel.setAccountId(accountId);
|
||||
messageModel.setFrom(message.getFrom() != null ? message.getFrom().asEntityBareJidIfPossible() : null);
|
||||
messageModel.setTo(chat.getXmppAddressOfChatPartner());
|
||||
messageModel.setIncoming(false);
|
||||
messageModel.setBody(message.getBody());
|
||||
long messageId = messageRepository.insertMessage(messageModel);
|
||||
Log.d(TAG, "Inserted outgoing message " + messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarbonCopyReceived(CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage) {
|
||||
MessageModel messageModel = new RoomMessageModel();
|
||||
messageModel.setAccountId(accountId);
|
||||
messageModel.setFrom(carbonCopy.getFrom() != null ? carbonCopy.getFrom().asEntityBareJidIfPossible() : null);
|
||||
messageModel.setTo(carbonCopy.getTo() != null ? carbonCopy.getTo().asEntityBareJidIfPossible() : null);
|
||||
|
||||
messageModel.setIncoming(direction == CarbonExtension.Direction.received);
|
||||
|
||||
messageModel.setBody(carbonCopy.getBody());
|
||||
long messageId = messageRepository.insertMessage(messageModel);
|
||||
Log.d(TAG, "Inserted carbon message " + messageId);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.mercury_im.messenger.ui;
|
||||
package org.mercury_im.messenger.handler;
|
||||
|
||||
import android.util.Log;
|
||||
|
|
@ -1,16 +1,86 @@
|
|||
package org.mercury_im.messenger.ui.chat;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.persistence.model.AccountModel;
|
||||
import org.mercury_im.messenger.persistence.model.MessageModel;
|
||||
import org.mercury_im.messenger.persistence.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.MessageRepository;
|
||||
import org.mercury_im.messenger.ui.BindingActivity;
|
||||
|
||||
public class ChatActivity extends AppCompatActivity implements ChatInputFragment.OnChatInputActionListener {
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class ChatActivity extends BindingActivity implements ChatInputFragment.OnChatInputActionListener {
|
||||
|
||||
@Inject
|
||||
AccountRepository accountRepository;
|
||||
|
||||
@Inject
|
||||
MessageRepository messageRepository;
|
||||
|
||||
private EntityBareJid jid;
|
||||
|
||||
private long accountId;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_chat);
|
||||
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerView);
|
||||
ChatRecyclerViewAdapter adapter = new ChatRecyclerViewAdapter();
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
savedInstanceState = getIntent().getExtras();
|
||||
}
|
||||
String jidString = savedInstanceState.getString("JID");
|
||||
if (jidString != null) {
|
||||
jid = JidCreate.entityBareFromOrThrowUnchecked(jidString);
|
||||
accountId = savedInstanceState.getLong("ACCOUNT");
|
||||
|
||||
LiveData<AccountModel> accountModel = accountRepository.getAccount(accountId);
|
||||
ChatViewModel viewModel = ViewModelProviders.of(this).get(ChatViewModel.class);
|
||||
|
||||
accountModel.observe(this, new Observer<AccountModel>() {
|
||||
@Override
|
||||
public void onChanged(AccountModel accountModel) {
|
||||
viewModel.init(accountModel, jid);
|
||||
}
|
||||
});
|
||||
|
||||
LiveData<List<MessageModel>> messages = messageRepository.getAllMessagesFrom(accountId, jid);
|
||||
messages.observe(this, new Observer<List<MessageModel>>() {
|
||||
@Override
|
||||
public void onChanged(List<MessageModel> messageModels) {
|
||||
Log.d(MercuryImApplication.TAG, "Updating messages: " + messageModels.size());
|
||||
adapter.updateMessages(messageModels);
|
||||
}
|
||||
});
|
||||
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fab, ChatInputFragment.newInstance())
|
||||
.commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,6 +95,19 @@ public class ChatActivity extends AppCompatActivity implements ChatInputFragment
|
|||
|
||||
@Override
|
||||
public void onComposingBodySend(String body) {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ChatManager.getInstanceFor(connectionService.getConnection(accountId).getConnection())
|
||||
.chatWith(jid).send(body);
|
||||
} catch (SmackException.NotConnectedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import android.os.Bundle;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -17,8 +19,11 @@ import android.widget.Toast;
|
|||
import org.mercury_im.messenger.R;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
import static org.mercury_im.messenger.MercuryImApplication.TAG;
|
||||
|
||||
public class ChatInputFragment extends Fragment implements View.OnClickListener {
|
||||
|
||||
@BindView(R.id.text_body)
|
||||
|
@ -42,7 +47,10 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
|
|||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.content_chat, container, false);
|
||||
Log.d(TAG, "onCreateView");
|
||||
View view = inflater.inflate(R.layout.view_chat_field, container, false);
|
||||
ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,7 +66,7 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
|
|||
* @param viewModel ViewModel
|
||||
*/
|
||||
private void observeViewModel(ChatInputViewModel viewModel) {
|
||||
viewModel.getDraft().observe(ChatInputFragment.this, draft -> textInput.setText(draft));
|
||||
//viewModel.getDraft().observe(ChatInputFragment.this, draft -> textInput.setText(draft));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +96,7 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
|
|||
@Override
|
||||
@OnClick({R.id.btn_send, R.id.btn_media})
|
||||
public void onClick(View view) {
|
||||
Log.d(TAG, "onClick!");
|
||||
switch (view.getId()) {
|
||||
// Add media
|
||||
case R.id.btn_media:
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package org.mercury_im.messenger.ui.chat;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.persistence.model.MessageModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ChatRecyclerViewAdapter extends RecyclerView.Adapter<ChatRecyclerViewAdapter.ChatItemViewHolder> {
|
||||
|
||||
private List<MessageModel> messages = new ArrayList<>();
|
||||
|
||||
public ChatRecyclerViewAdapter() {
|
||||
|
||||
}
|
||||
|
||||
public void updateMessages(List<MessageModel> messages) {
|
||||
this.messages.clear();
|
||||
this.messages.addAll(messages);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ChatItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ChatItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_message_text_in, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ChatItemViewHolder holder, int position) {
|
||||
MessageModel message = messages.get(position);
|
||||
holder.body.setText(message.getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return messages.size();
|
||||
}
|
||||
|
||||
public class ChatItemViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView body;
|
||||
|
||||
public ChatItemViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
body = itemView.findViewById(R.id.msg_body);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,10 +3,7 @@ package org.mercury_im.messenger.ui.login;
|
|||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
@ -27,12 +24,12 @@ import org.jxmpp.jid.impl.JidCreate;
|
|||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.handler.RoomPlainMessageHandler;
|
||||
import org.mercury_im.messenger.persistence.model.AccountModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
|
||||
import org.mercury_im.messenger.persistence.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.service.XmppConnectionService;
|
||||
import org.mercury_im.messenger.ui.BindingActivity;
|
||||
import org.mercury_im.messenger.ui.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.handler.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -156,11 +153,12 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
|
|||
XMPPTCPConnection connection = new XMPPTCPConnection(accountModel.getJid().getLocalpart().asUnescapedString(),
|
||||
accountModel.getPassword(), accountModel.getJid().getDomain().toString());
|
||||
MercuryConnection mercuryConnection = new MercuryConnection(connection, accountModel.getId());
|
||||
connectionService.putConnection(accountModel.getId(), mercuryConnection);
|
||||
mercuryConnection.setRosterHandler(new RoomRosterHandler(accountModel.getId(), Roster.getInstanceFor(connection)));
|
||||
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
|
||||
|
||||
connection.connect().login();
|
||||
if (bound) {
|
||||
connectionService.putConnection(accountModel.getId(), mercuryConnection);
|
||||
}
|
||||
Log.d(MercuryImApplication.TAG, "Logged in for " + accountModel.getJid().toString());
|
||||
} catch (XmppStringprepException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
|
|
|
@ -2,13 +2,19 @@ package org.mercury_im.messenger.ui.roster;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.R;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactAndEntityModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactModel;
|
||||
import org.mercury_im.messenger.ui.chat.ChatActivity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -18,22 +24,22 @@ import butterknife.ButterKnife;
|
|||
public class RosterRecyclerViewAdapter
|
||||
extends RecyclerView.Adapter<RosterRecyclerViewAdapter.RosterItemViewHolder> {
|
||||
|
||||
private List<RoomContactModel> entryModelList;
|
||||
private List<RoomContactAndEntityModel> entryModelList;
|
||||
|
||||
public RosterRecyclerViewAdapter(List<RoomContactModel> entryModelList) {
|
||||
public RosterRecyclerViewAdapter(List<RoomContactAndEntityModel> entryModelList) {
|
||||
this.entryModelList = entryModelList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RosterItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new RosterItemViewHolder(LayoutInflater.from(parent.getContext())
|
||||
return new RosterItemViewHolder(parent.getContext(), LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.recycler_view_item_roster_entry, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RosterItemViewHolder holder, int position) {
|
||||
RoomContactModel model = entryModelList.get(position);
|
||||
RoomContactAndEntityModel model = entryModelList.get(position);
|
||||
holder.bind(model);
|
||||
}
|
||||
|
||||
|
@ -42,7 +48,7 @@ public class RosterRecyclerViewAdapter
|
|||
return entryModelList.size();
|
||||
}
|
||||
|
||||
public void setItems(List<RoomContactModel> rosterEntryModels) {
|
||||
public void setItems(List<RoomContactAndEntityModel> rosterEntryModels) {
|
||||
this.entryModelList = rosterEntryModels;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
@ -55,18 +61,32 @@ public class RosterRecyclerViewAdapter
|
|||
|
||||
TextView nicknameView;
|
||||
|
||||
public RosterItemViewHolder(View itemView) {
|
||||
Context context;
|
||||
|
||||
public RosterItemViewHolder(Context context, View itemView) {
|
||||
super(itemView);
|
||||
this.context = context;
|
||||
this.view = itemView;
|
||||
this.jidView = itemView.findViewById(R.id.roster_entry__jid);
|
||||
this.nicknameView = itemView.findViewById(R.id.roster_entry__nickname);
|
||||
}
|
||||
|
||||
void bind(RoomContactModel contactModel) {
|
||||
// jidView.setText("" + contactModel.getEntityId());
|
||||
String nick = contactModel.getNickname();
|
||||
void bind(RoomContactAndEntityModel contactModel) {
|
||||
String nick = contactModel.getContact().getNickname();
|
||||
nicknameView.setText(nick != null ? nick : "");
|
||||
EntityBareJid jid = contactModel.getEntity().getJid();
|
||||
jidView.setText(jid.toString());
|
||||
|
||||
view.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(context, ChatActivity.class);
|
||||
intent.putExtra("JID", jid.toString());
|
||||
intent.putExtra("ACCOUNT", contactModel.getEntity().getAccountId());
|
||||
|
||||
context.startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import androidx.lifecycle.LiveData;
|
|||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactAndEntityRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactRepository;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactAndEntityModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactModel;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -16,18 +18,18 @@ import javax.inject.Inject;
|
|||
public class RosterViewModel extends AndroidViewModel {
|
||||
|
||||
@Inject
|
||||
ContactRepository contactRepository;
|
||||
ContactAndEntityRepository contactAndEntityRepository;
|
||||
|
||||
private final LiveData<List<RoomContactModel>> rosterEntryList;
|
||||
private final LiveData<List<RoomContactAndEntityModel>> rosterEntryList;
|
||||
|
||||
@Inject
|
||||
public RosterViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
this.rosterEntryList = contactRepository.getAllContacts();
|
||||
this.rosterEntryList = contactAndEntityRepository.getAllContactAndEntities();
|
||||
}
|
||||
|
||||
public LiveData<List<RoomContactModel>> getRosterEntryList() {
|
||||
public LiveData<List<RoomContactAndEntityModel>> getRosterEntryList() {
|
||||
return rosterEntryList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/chat"
|
||||
|
@ -16,7 +15,7 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:listitem="@layout/recycler_view_item_1">
|
||||
tools:listitem="@layout/view_message_text_in">
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/msg_avatar"
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.room.Room;
|
|||
import androidx.room.RoomDatabase;
|
||||
|
||||
import org.mercury_im.messenger.persistence.room.dao.AccountDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactAndEntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.EntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.MessageDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
|
||||
|
@ -42,4 +43,6 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
public abstract AccountDao accountDao();
|
||||
|
||||
public abstract EntityDao entityDao();
|
||||
|
||||
public abstract ContactAndEntityDao contactAndEntityDao();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package org.mercury_im.messenger.persistence.room.dao;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.TypeConverters;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactAndEntityModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
|
||||
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomContactAndEntityModel.PREFIX;
|
||||
|
||||
@Dao
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
public interface ContactAndEntityDao {
|
||||
|
||||
@Query("SELECT contacts.*, " +
|
||||
"entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_ACCOUNT_ID + " AS " + PREFIX + RoomEntityModel.KEY_ACCOUNT_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_JID + " AS " + PREFIX + RoomEntityModel.KEY_JID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
|
||||
"FROM contacts INNER JOIN entities ON contacts.entityId = entities.id " +
|
||||
"WHERE entities.accountId = :accountId AND entities.jid = :bareJid")
|
||||
LiveData<RoomContactAndEntityModel> getContactAndEntity(long accountId, EntityBareJid bareJid);
|
||||
|
||||
@Query("SELECT contacts.*, " +
|
||||
"entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_ACCOUNT_ID + " AS " + PREFIX + RoomEntityModel.KEY_ACCOUNT_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_JID + " AS " + PREFIX + RoomEntityModel.KEY_JID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
|
||||
"FROM contacts INNER JOIN entities ON contacts.entityId = entities.id " +
|
||||
"WHERE entities.accountId = :accountId")
|
||||
LiveData<List<RoomContactAndEntityModel>> getAllContactAndEntities(long accountId);
|
||||
|
||||
@Query("SELECT contacts.*, " +
|
||||
"entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_ACCOUNT_ID + " AS " + PREFIX + RoomEntityModel.KEY_ACCOUNT_ID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_JID + " AS " + PREFIX + RoomEntityModel.KEY_JID + ", " +
|
||||
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
|
||||
"FROM contacts INNER JOIN entities ON contacts.entityId = entities.id")
|
||||
LiveData<List<RoomContactAndEntityModel>> getAllContactAndEntities();
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.mercury_im.messenger.persistence.room.model;
|
||||
|
||||
import androidx.room.Embedded;
|
||||
|
||||
import org.mercury_im.messenger.persistence.model.ContactAndEntityModel;
|
||||
|
||||
public class RoomContactAndEntityModel implements ContactAndEntityModel<RoomContactModel, RoomEntityModel> {
|
||||
|
||||
public static final String PREFIX = "e_";
|
||||
|
||||
@Embedded(prefix = PREFIX)
|
||||
private RoomEntityModel entity;
|
||||
|
||||
@Embedded()
|
||||
private RoomContactModel contact;
|
||||
|
||||
@Override
|
||||
public RoomContactModel getContact() {
|
||||
return contact;
|
||||
}
|
||||
|
||||
public void setContact(RoomContactModel contact) {
|
||||
this.contact = contact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoomEntityModel getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(RoomEntityModel entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.mercury_im.messenger.persistence.room.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactAndEntityRepository;
|
||||
import org.mercury_im.messenger.persistence.room.dao.ContactAndEntityDao;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomContactAndEntityModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class IContactAndEntityRepository implements ContactAndEntityRepository<RoomContactAndEntityModel> {
|
||||
|
||||
private final ContactAndEntityDao dao;
|
||||
|
||||
@Inject
|
||||
public IContactAndEntityRepository(ContactAndEntityDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomContactAndEntityModel> getContactAndEntity(long accountId, EntityBareJid jid) {
|
||||
return dao.getContactAndEntity(accountId, jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<List<RoomContactAndEntityModel>> getAllContactAndEntities(long accountId) {
|
||||
return dao.getAllContactAndEntities(accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<List<RoomContactAndEntityModel>> getAllContactAndEntities() {
|
||||
return dao.getAllContactAndEntities();
|
||||
}
|
||||
}
|
|
@ -8,11 +8,11 @@ public class DateConverter {
|
|||
|
||||
@TypeConverter
|
||||
public static long toLong(Date date) {
|
||||
return date.getTime();
|
||||
return date != null ? date.getTime() : -1;
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static Date toDate(long lon) {
|
||||
return new Date(lon);
|
||||
return lon != -1 ? new Date(lon) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.mercury_im.messenger.persistence.model;
|
||||
|
||||
public interface ContactAndEntityModel<C extends ContactModel, E extends EntityModel> {
|
||||
|
||||
C getContact();
|
||||
|
||||
E getEntity();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.mercury_im.messenger.persistence.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.ContactAndEntityModel;
|
||||
import org.mercury_im.messenger.persistence.model.ContactModel;
|
||||
import org.mercury_im.messenger.persistence.model.EntityModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ContactAndEntityRepository<CE extends ContactAndEntityModel<? extends ContactModel, ? extends EntityModel>> {
|
||||
|
||||
LiveData<CE> getContactAndEntity(long accountId, EntityBareJid jid);
|
||||
|
||||
LiveData<List<CE>> getAllContactAndEntities(long accountId);
|
||||
|
||||
LiveData<List<CE>> getAllContactAndEntities();
|
||||
}
|
|
@ -1,19 +1,32 @@
|
|||
package org.mercury_im.messenger.xmpp_core;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.util.ExceptionCallback;
|
||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||
import org.whispersystems.libsignal.logging.Log;
|
||||
|
||||
public class MercuryConnection {
|
||||
public class MercuryConnection implements ConnectionListener {
|
||||
|
||||
public static final String TAG = "Mercury";
|
||||
|
||||
protected final XMPPConnection connection;
|
||||
protected final long accountId;
|
||||
|
||||
protected final Roster roster;
|
||||
protected final ChatManager chatManager;
|
||||
protected final CarbonManager carbonManager;
|
||||
|
||||
public MercuryConnection(XMPPConnection connection, long accountId) {
|
||||
this.connection = connection;
|
||||
this.accountId = accountId;
|
||||
|
||||
this.roster = Roster.getInstanceFor(connection);
|
||||
this.chatManager = ChatManager.getInstanceFor(connection);
|
||||
this.carbonManager = CarbonManager.getInstanceFor(connection);
|
||||
|
||||
roster.setRosterLoadedAtLogin(true);
|
||||
}
|
||||
|
||||
|
@ -26,6 +39,12 @@ public class MercuryConnection {
|
|||
roster.addRosterLoadedListener(handler);
|
||||
}
|
||||
|
||||
public void setPlainMessageHandler(PlainMessageHandler plainMessageHandler) {
|
||||
carbonManager.addCarbonCopyReceivedListener(plainMessageHandler);
|
||||
chatManager.addIncomingListener(plainMessageHandler);
|
||||
chatManager.addOutgoingListener(plainMessageHandler);
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
@ -33,4 +52,27 @@ public class MercuryConnection {
|
|||
public Roster getRoster() {
|
||||
return roster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(XMPPConnection connection) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||
if (connection == this.connection && !resumed) {
|
||||
carbonManager.enableCarbonsAsync(exception ->
|
||||
Log.e("Mercury", "Could not enable carbons for connection " + accountId + ":", exception));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
Log.i(TAG, "Connection closed.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
Log.e(TAG, "Connection closed on error.", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package org.mercury_im.messenger.xmpp_core;
|
||||
|
||||
import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
|
||||
import org.jivesoftware.smack.chat2.OutgoingChatMessageListener;
|
||||
import org.jivesoftware.smackx.carbons.CarbonCopyReceivedListener;
|
||||
|
||||
public interface PlainMessageHandler extends IncomingChatMessageListener, OutgoingChatMessageListener, CarbonCopyReceivedListener {
|
||||
|
||||
}
|
Loading…
Reference in New Issue