RxJava'ify

This commit is contained in:
Paul Schaub 2019-08-03 19:05:50 +02:00
parent 1e238e2b32
commit 817d6a2940
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
54 changed files with 479 additions and 426 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@
/.idea/modules.xml /.idea/modules.xml
/.idea/workspace.xml /.idea/workspace.xml
/.idea/caches/ /.idea/caches/
/.idea
.DS_Store .DS_Store
/build /build
/captures /captures

View File

@ -73,12 +73,10 @@ check.configure {
dependencies { dependencies {
// Depend on the core project for XMPP related stuff // Depend on the core project for XMPP related stuff
implementation(project(':xmpp_core')) implementation project(':core')
// Plug a Room based implementation into the persistence api // Plug a Room based implementation into the persistence api
implementation(project(':persistence-room')) { implementation project(':persistence-room')
transitive = true
}
// Dagger 2 for dependency injection // Dagger 2 for dependency injection
implementation "com.google.dagger:dagger:$daggerVersion" implementation "com.google.dagger:dagger:$daggerVersion"
@ -93,7 +91,7 @@ dependencies {
annotationProcessor "com.jakewharton:butterknife-compiler:$butterKnifeVersion" annotationProcessor "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
// support libraries // support libraries
implementation 'androidx.appcompat:appcompat:1.1.0-beta01' implementation "androidx.appcompat:appcompat:$appCompatVersion"
implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.0.1' implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
@ -108,7 +106,7 @@ dependencies {
implementation "org.igniterealtime.smack:smack-android-extensions:$smackAndroidExtensionsVersion" implementation "org.igniterealtime.smack:smack-android-extensions:$smackAndroidExtensionsVersion"
// Testing - as if... // Testing - as if...
testImplementation 'junit:junit:4.12' testImplementation "junit:junit:$junitVersion"
androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation "androidx.test:runner:$andxTestRunnerVersion"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' androidTestImplementation "androidx.test.espresso:espresso-core:$andxTestEspressoVersion"
} }

View File

@ -10,8 +10,8 @@ import android.os.Build;
import org.mercury_im.messenger.di.component.AppComponent; import org.mercury_im.messenger.di.component.AppComponent;
import org.mercury_im.messenger.di.component.DaggerAppComponent; import org.mercury_im.messenger.di.component.DaggerAppComponent;
import org.mercury_im.messenger.di.module.AppModule; import org.mercury_im.messenger.di.module.AppModule;
import org.mercury_im.messenger.di.module.RepositoryModule; import org.mercury_im.messenger.persistence.room.RoomModule;
import org.mercury_im.messenger.di.module.RoomModule; import org.mercury_im.messenger.persistence.room.RoomRepositoryModule;
import org.mercury_im.messenger.service.XmppConnectionService; import org.mercury_im.messenger.service.XmppConnectionService;
public class MercuryImApplication extends Application { public class MercuryImApplication extends Application {
@ -30,13 +30,9 @@ public class MercuryImApplication extends Application {
super.onCreate(); super.onCreate();
INSTANCE = this; INSTANCE = this;
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.roomModule(new RoomModule(this))
.repositoryModule(new RepositoryModule())
.build();
appComponent.inject(this); appComponent = createAppComponent();
initializeNotificationChannels(this); initializeNotificationChannels(this);
Intent serviceIntent = new Intent(getApplicationContext(), XmppConnectionService.class); Intent serviceIntent = new Intent(getApplicationContext(), XmppConnectionService.class);
@ -49,6 +45,22 @@ public class MercuryImApplication extends Application {
} }
} }
/**
* Create the Dependency Injection graph.
* For testing, overwrite this method with custom modules.
*/
public AppComponent createAppComponent() {
AppComponent appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.roomModule(new RoomModule(this))
.roomRepositoryModule(new RoomRepositoryModule())
.build();
appComponent.inject(this);
return appComponent;
}
public void initializeNotificationChannels(Context context) { public void initializeNotificationChannels(Context context) {
// Only necessary on Android O and upwards. // Only necessary on Android O and upwards.
if (Build.VERSION.SDK_INT < 26) { if (Build.VERSION.SDK_INT < 26) {

View File

@ -2,10 +2,9 @@ package org.mercury_im.messenger.di.component;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.di.module.AppModule; 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.handler.RoomPlainMessageHandler;
import org.mercury_im.messenger.handler.RoomRosterHandler; import org.mercury_im.messenger.handler.RoomRosterHandler;
import org.mercury_im.messenger.persistence.room.RoomModule;
import org.mercury_im.messenger.service.XmppConnectionService; import org.mercury_im.messenger.service.XmppConnectionService;
import org.mercury_im.messenger.ui.MainActivity; import org.mercury_im.messenger.ui.MainActivity;
import org.mercury_im.messenger.ui.chat.ChatActivity; import org.mercury_im.messenger.ui.chat.ChatActivity;
@ -23,7 +22,7 @@ import javax.inject.Singleton;
import dagger.Component; import dagger.Component;
@Singleton @Singleton
@Component(modules = {AppModule.class, RoomModule.class, RepositoryModule.class}) @Component(modules = {AppModule.class, RoomModule.class})
public interface AppComponent { public interface AppComponent {
// Application // Application

View File

@ -1,5 +1,7 @@
package org.mercury_im.messenger.di.module; package org.mercury_im.messenger.di.module;
import android.app.Application;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -18,7 +20,7 @@ public class AppModule {
@Provides @Provides
@Singleton @Singleton
MercuryImApplication provideApplication() { Application provideApplication() {
return mApplication; return mApplication;
} }
} }

View File

@ -10,12 +10,14 @@ import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.persistence.model.MessageModel; import org.mercury_im.messenger.persistence.model.MessageModel;
import org.mercury_im.messenger.persistence.repository.MessageRepository; import org.mercury_im.messenger.persistence.repository.MessageRepository;
import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; import org.mercury_im.messenger.persistence.room.model.RoomMessageModel;
import org.mercury_im.messenger.xmpp_core.PlainMessageHandler; import org.mercury_im.messenger.core.PlainMessageHandler;
import java.util.Date; import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Single;
import static org.mercury_im.messenger.MercuryImApplication.TAG; import static org.mercury_im.messenger.MercuryImApplication.TAG;
public class RoomPlainMessageHandler implements PlainMessageHandler { public class RoomPlainMessageHandler implements PlainMessageHandler {
@ -43,8 +45,9 @@ public class RoomPlainMessageHandler implements PlainMessageHandler {
messageModel.setIncoming(true); messageModel.setIncoming(true);
messageModel.setBody(message.getBody()); messageModel.setBody(message.getBody());
messageModel.setSendDate(new Date()); messageModel.setSendDate(new Date());
long messageId = messageRepository.insertMessage(messageModel); Single<Long> messageId = messageRepository.insertMessage(messageModel);
Log.d(TAG, "Inserted incoming message " + messageId);
Log.d(TAG, "Inserted incoming message " + messageId.blockingGet());
} }
@Override @Override
@ -56,8 +59,8 @@ public class RoomPlainMessageHandler implements PlainMessageHandler {
messageModel.setIncoming(false); messageModel.setIncoming(false);
messageModel.setBody(message.getBody()); messageModel.setBody(message.getBody());
messageModel.setSendDate(new Date()); messageModel.setSendDate(new Date());
long messageId = messageRepository.insertMessage(messageModel); Single<Long> messageId = messageRepository.insertMessage(messageModel);
Log.d(TAG, "Inserted outgoing message " + messageId); Log.d(TAG, "Inserted outgoing message " + messageId.blockingGet());
} }
@Override @Override
@ -75,7 +78,7 @@ public class RoomPlainMessageHandler implements PlainMessageHandler {
messageModel.setBody(carbonCopy.getBody()); messageModel.setBody(carbonCopy.getBody());
messageModel.setSendDate(new Date()); messageModel.setSendDate(new Date());
long messageId = messageRepository.insertMessage(messageModel); Single<Long> messageId = messageRepository.insertMessage(messageModel);
Log.d(TAG, "Inserted carbon message " + messageId); Log.d(TAG, "Inserted carbon message " + messageId.blockingGet());
} }
} }

View File

@ -15,8 +15,8 @@ import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao;
import org.mercury_im.messenger.persistence.room.dao.EntityDao; import org.mercury_im.messenger.persistence.room.dao.EntityDao;
import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes; import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes;
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel; import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
import org.mercury_im.messenger.xmpp_core.MercuryConnection; import org.mercury_im.messenger.core.MercuryConnection;
import org.mercury_im.messenger.xmpp_core.RosterHandler; import org.mercury_im.messenger.core.RosterHandler;
import java.util.Collection; import java.util.Collection;

View File

@ -1,55 +0,0 @@
package org.mercury_im.messenger.ui;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import androidx.appcompat.app.AppCompatActivity;
import org.mercury_im.messenger.service.XmppConnectionService;
public abstract class BindingActivity extends AppCompatActivity {
protected XmppConnectionService connectionService;
protected boolean bound;
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, XmppConnectionService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(serviceConnection);
bound = false;
}
protected void onServiceBound() {
}
protected void onServiceUnbound() {
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
XmppConnectionService.Binder binder = (XmppConnectionService.Binder) iBinder;
connectionService = binder.getService();
bound = true;
onServiceBound();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
bound = false;
onServiceUnbound();
}
};
}

View File

@ -6,6 +6,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@ -24,14 +25,7 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
public class MainActivity extends BindingActivity { public class MainActivity extends AppCompatActivity {
@Inject
public AccountRepository accountRepository;
@Inject
public ContactAttributesRepository contactAttributesRepository;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -43,15 +37,6 @@ public class MainActivity extends BindingActivity {
MercuryImApplication.getApplication().getAppComponent().inject(this); MercuryImApplication.getApplication().getAppComponent().inject(this);
FloatingActionButton fab = findViewById(R.id.fab); FloatingActionButton fab = findViewById(R.id.fab);
accountRepository.getAllAccountsLive().observe(this, new Observer<List<AccountModel>>() {
@Override
public void onChanged(@Nullable List<AccountModel> accountModels) {
if (accountModels == null || accountModels.isEmpty()) {
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
}
}
});
} }
@Override @Override

View File

@ -11,8 +11,6 @@ import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; 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.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
@ -21,7 +19,6 @@ import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.model.MessageModel; import org.mercury_im.messenger.persistence.model.MessageModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.persistence.repository.MessageRepository; import org.mercury_im.messenger.persistence.repository.MessageRepository;
import org.mercury_im.messenger.ui.BindingActivity;
import java.util.List; import java.util.List;

View File

@ -6,21 +6,14 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import androidx.fragment.app.FragmentActivity; import androidx.appcompat.app.AppCompatActivity;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R; import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.service.XmppConnectionService;
import org.mercury_im.messenger.ui.BindingActivity;
import javax.inject.Inject; public class AccountsActivity extends AppCompatActivity
implements AccountsFragment.OnListFragmentInteractionListener {
public class AccountsActivity extends BindingActivity implements AccountsFragment.OnListFragmentInteractionListener {
@Inject
AccountRepository accountRepository;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -44,13 +37,4 @@ public class AccountsActivity extends BindingActivity implements AccountsFragmen
}); });
builder.create().show(); builder.create().show();
} }
@Override
protected void onServiceBound() {
super.onServiceBound();
}
public XmppConnectionService getConnectionService() {
return connectionService;
}
} }

View File

@ -3,13 +3,11 @@ package org.mercury_im.messenger.ui.login;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.util.LongSparseArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -17,8 +15,6 @@ import androidx.recyclerview.widget.RecyclerView;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.R; import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.service.XmppConnectionService;
import org.mercury_im.messenger.xmpp_core.ConnectionState;
/** /**
* A fragment representing a list of Items. * A fragment representing a list of Items.

View File

@ -22,7 +22,7 @@ public class AccountsViewModel extends ViewModel {
public AccountsViewModel() { public AccountsViewModel() {
super(); super();
MercuryImApplication.getApplication().getAppComponent().inject(this); MercuryImApplication.getApplication().getAppComponent().inject(this);
accounts = repository.getAllAccountsLive(); accounts = repository.getAllAccounts();
} }
public LiveData<List<RoomAccountModel>> getAccounts() { public LiveData<List<RoomAccountModel>> getAccounts() {

View File

@ -9,6 +9,7 @@ import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
@ -28,8 +29,7 @@ import org.mercury_im.messenger.handler.RoomRosterHandler;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.ui.BindingActivity; import org.mercury_im.messenger.core.MercuryConnection;
import org.mercury_im.messenger.xmpp_core.MercuryConnection;
import java.io.IOException; import java.io.IOException;
@ -37,11 +37,17 @@ import javax.inject.Inject;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/** /**
* A login screen that offers login via email/password. * A login screen that offers login via email/password.
*/ */
public class LoginActivity extends BindingActivity implements TextView.OnEditorActionListener { public class LoginActivity extends AppCompatActivity implements TextView.OnEditorActionListener {
@Inject @Inject
AccountRepository accountRepository; AccountRepository accountRepository;
@ -83,18 +89,6 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
mSignInView.setEnabled(false); mSignInView.setEnabled(false);
} }
@Override
protected void onServiceBound() {
super.onServiceBound();
mSignInView.setEnabled(true);
}
@Override
protected void onServiceUnbound() {
super.onServiceUnbound();
mSignInView.setEnabled(false);
}
private void displayCredentials(LiveData<? extends AccountModel> account) { private void displayCredentials(LiveData<? extends AccountModel> account) {
account.observe(this, accountModel -> { account.observe(this, accountModel -> {
if (accountModel == null) { if (accountModel == null) {
@ -137,7 +131,25 @@ public class LoginActivity extends BindingActivity implements TextView.OnEditorA
accountModel.setEnabled(true); accountModel.setEnabled(true);
accountModel.setJid(jid); accountModel.setJid(jid);
accountModel.setPassword(password); accountModel.setPassword(password);
long id = accountRepository.insertAccount(accountModel); Single<Long> id = accountRepository.insertAccount(accountModel);
id.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(Long aLong) {
}
@Override
public void onError(Throwable e) {
}
});
accountModel.setId(id); accountModel.setId(id);
Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted."); Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted.");
attemptLogin(accountModel); attemptLogin(accountModel);

View File

@ -1,10 +1,8 @@
package org.mercury_im.messenger.ui.roster; package org.mercury_im.messenger.ui.roster;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.persistence.repository.ContactRepository; import org.mercury_im.messenger.persistence.repository.ContactRepository;
@ -14,18 +12,34 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
public class RosterViewModel extends AndroidViewModel { import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
public class RosterViewModel extends ViewModel {
@Inject @Inject
ContactRepository contactRepository; ContactRepository<RoomContactModel> contactRepository;
private final LiveData<List<RoomContactModel>> rosterEntryList; private final MutableLiveData<List<RoomContactModel>> rosterEntryList = new MutableLiveData<>();
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
@Inject public RosterViewModel() {
public RosterViewModel(@NonNull Application application) { super();
super(application);
MercuryImApplication.getApplication().getAppComponent().inject(this); MercuryImApplication.getApplication().getAppComponent().inject(this);
this.rosterEntryList = contactRepository.getAllContacts();
// Subscribe to changes to the contacts table and update the LiveData object for the UI.
compositeDisposable.add(contactRepository.getAllContacts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(rosterEntryList::setValue));
}
@Override
protected void onCleared() {
super.onCleared();
compositeDisposable.clear();
} }
public LiveData<List<RoomContactModel>> getRosterEntryList() { public LiveData<List<RoomContactModel>> getRosterEntryList() {

View File

@ -2,6 +2,8 @@ apply plugin: 'java-library'
dependencies { dependencies {
api project(":persistence")
// Smack // Smack
// Not all of those are needed, but it may be a good idea to define those versions explicitly // Not all of those are needed, but it may be a good idea to define those versions explicitly
api "org.igniterealtime.smack:smack-core:$smackCoreVersion" api "org.igniterealtime.smack:smack-core:$smackCoreVersion"
@ -18,6 +20,8 @@ dependencies {
// Dagger 2 for dependency injection // Dagger 2 for dependency injection
implementation "com.google.dagger:dagger:$daggerVersion" implementation "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
testImplementation "junit:junit:$junitVersion"
} }
sourceCompatibility = "8" sourceCompatibility = "8"

View File

@ -1,8 +1,11 @@
package org.mercury_im.messenger.xmpp_core; package org.mercury_im.messenger.core;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.inject.Singleton;
@Singleton
public class ConnectionCenter { public class ConnectionCenter {
private static ConnectionCenter INSTANCE; private static ConnectionCenter INSTANCE;
@ -20,6 +23,8 @@ public class ConnectionCenter {
return INSTANCE; return INSTANCE;
} }
public MercuryConnection getConnection(long accountId) { public MercuryConnection getConnection(long accountId) {
return connectionMap.get(accountId); return connectionMap.get(accountId);
} }

View File

@ -1,4 +1,4 @@
package org.mercury_im.messenger.xmpp_core; package org.mercury_im.messenger.core;
/** /**
* {@link MercuryConnection} modeled as a finite state machine. * {@link MercuryConnection} modeled as a finite state machine.

View File

@ -0,0 +1,84 @@
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import java.util.Collection;
import java.util.List;
public class IRosterHandler implements RosterHandler {
@Override
public void presenceAvailable(FullJid address, Presence availablePresence) {
}
@Override
public void presenceUnavailable(FullJid address, Presence presence) {
}
@Override
public void presenceError(Jid address, Presence errorPresence) {
}
@Override
public void presenceSubscribed(BareJid address, Presence subscribedPresence) {
}
@Override
public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
}
@Override
public void onRosterLoaded(Roster roster) {
}
@Override
public void onRosterLoadingFailed(Exception exception) {
}
@Override
public List<RosterPacket.Item> getEntries() {
return null;
}
@Override
public RosterPacket.Item getEntry(Jid bareJid) {
return null;
}
@Override
public String getRosterVersion() {
return null;
}
@Override
public boolean addEntry(RosterPacket.Item item, String version) {
return false;
}
@Override
public boolean resetEntries(Collection<RosterPacket.Item> items, String version) {
return false;
}
@Override
public boolean removeEntry(Jid bareJid, String version) {
return false;
}
@Override
public void resetStore() {
}
}

View File

@ -1,27 +1,20 @@
package org.mercury_im.messenger.xmpp_core; package org.mercury_im.messenger.core;
import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.ReconnectionListener;
import org.jivesoftware.smack.ReconnectionManager; import org.jivesoftware.smack.ReconnectionManager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.ChatManager; import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler; import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler; import org.jivesoftware.smack.iqrequest.IQRequestHandler;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.sm.packet.StreamManagement;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smackx.carbons.CarbonManager; import org.jivesoftware.smackx.carbons.CarbonManager;
import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.iqversion.packet.Version; import org.jivesoftware.smackx.iqversion.packet.Version;
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager; import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
public class MercuryConnection implements ConnectionListener { public class MercuryConnection implements ConnectionListener {
@ -70,11 +63,6 @@ public class MercuryConnection implements ConnectionListener {
return connection; return connection;
} }
public void setRosterHandler(RosterHandler handler) {
roster.addRosterListener(handler);
roster.addRosterLoadedListener(handler);
}
public void setPlainMessageHandler(PlainMessageHandler plainMessageHandler) { public void setPlainMessageHandler(PlainMessageHandler plainMessageHandler) {
carbonManager.addCarbonCopyReceivedListener(plainMessageHandler); carbonManager.addCarbonCopyReceivedListener(plainMessageHandler);
chatManager.addIncomingListener(plainMessageHandler); chatManager.addIncomingListener(plainMessageHandler);

View File

@ -1,4 +1,4 @@
package org.mercury_im.messenger.xmpp_core; package org.mercury_im.messenger.core;
import org.jivesoftware.smack.chat2.IncomingChatMessageListener; import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
import org.jivesoftware.smack.chat2.OutgoingChatMessageListener; import org.jivesoftware.smack.chat2.OutgoingChatMessageListener;

View File

@ -0,0 +1,9 @@
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.roster.PresenceEventListener;
import org.jivesoftware.smack.roster.RosterLoadedListener;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
public interface RosterHandler extends RosterStore, RosterLoadedListener, PresenceEventListener {
}

View File

@ -0,0 +1,20 @@
package org.mercury_im.messenger.core.di;
import org.mercury_im.messenger.core.ConnectionCenter;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class CenterModule {
@Singleton
@Provides
static ConnectionCenter provideConnectionCenter() {
return ConnectionCenter.get();
}
}

View File

@ -0,0 +1,16 @@
package org.mercury_im.messenger.core.di;
import org.mercury_im.messenger.core.IRosterHandler;
import org.mercury_im.messenger.core.RosterHandler;
import dagger.Module;
import dagger.Provides;
@Module
public class HandlerModule {
@Provides
RosterHandler provideRosterHandler() {
return new IRosterHandler();
}
}

View File

@ -0,0 +1,11 @@
package org.mercury_im.messenger.core.di;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = CenterModule.class)
public interface XmppComponent {
}

View File

@ -36,16 +36,15 @@ dependencies {
implementation "com.google.dagger:dagger:$daggerVersion" implementation "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test:runner:$andxTestRunnerVersion"
implementation 'androidx.appcompat:appcompat:1.0.2' androidTestImplementation "androidx.test.espresso:espresso-core:$andxTestEspressoVersion"
testImplementation 'junit:junit:4.12' androidTestImplementation "androidx.test:core:$andxTestCoreVersion"
androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation "androidx.test.ext:junit:$andxTestJunitVersion"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
// Room // Room
api "androidx.room:room-runtime:$roomVersion" api "androidx.room:room-runtime:$roomVersion"
annotationProcessor "androidx.room:room-compiler:$roomVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion"
implementation "androidx.room:room-rxjava2:$roomRxJavaVersion"
api "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
} }

View File

@ -1,14 +1,15 @@
package org.mercury_im.messenger.persistence.room; package org.mercury_im.messenger.persistence.room;
import android.content.Context; import android.content.Context;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.persistence.room.repository.IAccountRepository; import org.mercury_im.messenger.persistence.room.repository.IAccountRepository;
import org.mercury_im.messenger.persistence.room.repository.IContactAttributesRepository; import org.mercury_im.messenger.persistence.room.repository.IContactAttributesRepository;
@ -16,7 +17,13 @@ import org.mercury_im.messenger.persistence.room.repository.IMessageRepository;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertNull; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Predicate;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;
import static org.junit.Assert.assertEquals;
/** /**
* Instrumented test, which will execute on an Android device. * Instrumented test, which will execute on an Android device.
@ -37,13 +44,20 @@ public class ExampleInstrumentedTest {
IContactAttributesRepository rosterRepository = new IContactAttributesRepository(appDatabase.rosterEntryDao()); IContactAttributesRepository rosterRepository = new IContactAttributesRepository(appDatabase.rosterEntryDao());
IMessageRepository messageRepository = new IMessageRepository(appDatabase.messageDao()); IMessageRepository messageRepository = new IMessageRepository(appDatabase.messageDao());
LiveData<List<RoomAccountModel>> accounts = accountRepository.getAllAccountsLive(); Observable<List<RoomAccountModel>> accounts = accountRepository.getAllAccounts();
assertNull(accounts.getValue());
RoomAccountModel a1 = new RoomAccountModel(); final RoomAccountModel a1 = new RoomAccountModel();
a1.setJid(JidCreate.entityBareFromOrThrowUnchecked("alice@wonderland.lit")); a1.setJid(JidCreate.entityBareFromOrThrowUnchecked("alice@wonderland.lit"));
a1.setPassword("5w0rdf1sh"); a1.setPassword("5w0rdf1sh");
a1.setEnabled(false); a1.setEnabled(false);
accountRepository.insertAccount(a1); accountRepository.insertAccount(a1);
accounts.test()
.assertValue(new Predicate<List<RoomAccountModel>>() {
@Override
public boolean test(List<RoomAccountModel> roomAccountModels) throws Exception {
return roomAccountModels.size() == 1;
}
});
} }
} }

View File

@ -1,7 +1,7 @@
package org.mercury_im.messenger.di.module; package org.mercury_im.messenger.persistence.room;
import android.app.Application;
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.AccountDao;
import org.mercury_im.messenger.persistence.room.dao.ChatDao; import org.mercury_im.messenger.persistence.room.dao.ChatDao;
import org.mercury_im.messenger.persistence.room.dao.ContactDao; import org.mercury_im.messenger.persistence.room.dao.ContactDao;
@ -18,13 +18,13 @@ import dagger.Provides;
/** /**
* Provides the {@link AppDatabase}, DAOs and Repositories. * Provides the {@link AppDatabase}, DAOs and Repositories.
*/ */
@Module @Module(includes = RoomRepositoryModule.class)
public class RoomModule { public class RoomModule {
private AppDatabase mAppDatabase; private AppDatabase mAppDatabase;
@Inject @Inject
public RoomModule(MercuryImApplication application) { public RoomModule(Application application) {
mAppDatabase = AppDatabase.getDatabase(application); mAppDatabase = AppDatabase.getDatabase(application);
} }

View File

@ -1,4 +1,4 @@
package org.mercury_im.messenger.di.module; package org.mercury_im.messenger.persistence.room;
import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.persistence.repository.ChatRepository; import org.mercury_im.messenger.persistence.repository.ChatRepository;
@ -25,7 +25,7 @@ import dagger.Module;
import dagger.Provides; import dagger.Provides;
@Module @Module
public class RepositoryModule { public class RoomRepositoryModule {
@Singleton @Singleton
@Provides @Provides

View File

@ -1,40 +1,33 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.annotation.WorkerThread; import androidx.annotation.WorkerThread;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.Transaction;
import androidx.room.TypeConverters; import androidx.room.TypeConverters;
import androidx.room.Update;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
import java.util.List; import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
@Dao @Dao
@TypeConverters(EntityBareJidConverter.class) @TypeConverters(EntityBareJidConverter.class)
@WorkerThread @WorkerThread
public interface AccountDao extends BaseDao<RoomAccountModel> { public interface AccountDao extends BaseDao<RoomAccountModel> {
/** /**
* Return a {@link LiveData} wrapping a {@link List} which contains all * Return an {@link Observable} wrapping a {@link List} which contains all
* {@link RoomAccountModel Accounts} which are currently stored in the database. * {@link RoomAccountModel Accounts} which are currently stored in the database.
* *
* @return live updating account list * @return live updating account list
*/ */
@Query("select * from accounts") @Query("select * from accounts")
LiveData<List<RoomAccountModel>> getAllAccountsLive(); Observable<List<RoomAccountModel>> getAllAccounts();
@Query("select * from accounts")
List<RoomAccountModel> getAllAccounts();
/** /**
* Return the {@link RoomAccountModel Account} which is identified by the given id. * Return the {@link RoomAccountModel Account} which is identified by the given id.
@ -43,11 +36,11 @@ public interface AccountDao extends BaseDao<RoomAccountModel> {
* @return account or null * @return account or null
*/ */
@Query("select * from accounts where pk_account_id = :id") @Query("select * from accounts where pk_account_id = :id")
LiveData<RoomAccountModel> getAccountById(long id); Maybe<RoomAccountModel> getAccountById(long id);
@Query("select * from accounts where jid = :jid") @Query("select * from accounts where jid = :jid")
LiveData<RoomAccountModel> getAccountByJid(EntityBareJid jid); Maybe<RoomAccountModel> getAccountByJid(EntityBareJid jid);
@Query("update accounts set state = :state where pk_account_id = :accountId") @Query("update accounts set state = :state where pk_account_id = :accountId")
void updateConnectionState(long accountId, String state); Completable updateConnectionState(long accountId, String state);
} }

View File

@ -4,20 +4,23 @@ import androidx.room.Delete;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Update; import androidx.room.Update;
import io.reactivex.Completable;
import io.reactivex.Single;
public interface BaseDao<T> { public interface BaseDao<T> {
@Insert @Insert
long insert(T entity); Single<Long> insert(T entity);
@Update @Update
void update(T entity); Completable update(T entity);
@Update @Update
void update(T[] entities); Completable update(T[] entities);
@Delete @Delete
void delete(T entity); Completable delete(T entity);
@Delete @Delete
void delete(T[] entities); Completable delete(T[] entities);
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.TypeConverters; import androidx.room.TypeConverters;
@ -11,22 +10,25 @@ import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidCon
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
@Dao @Dao
@TypeConverters(EntityBareJidConverter.class) @TypeConverters(EntityBareJidConverter.class)
public interface ChatDao extends BaseDao<RoomChatModel> { public interface ChatDao extends BaseDao<RoomChatModel> {
@Query("SELECT * FROM chats") @Query("SELECT * FROM chats")
LiveData<List<RoomChatModel>> getAllChats(); Observable<List<RoomChatModel>> getAllChats();
@Query("SELECT chats.* FROM chats JOIN entities WHERE fk_account_id = :accountId") @Query("SELECT chats.* FROM chats JOIN entities WHERE fk_account_id = :accountId")
LiveData<List<RoomChatModel>> getAllChatsOf(long accountId); Observable<List<RoomChatModel>> getAllChatsOf(long accountId);
@Query("SELECT * FROM chats WHERE fk_entity_id = :entityId") @Query("SELECT * FROM chats WHERE fk_entity_id = :entityId")
LiveData<RoomChatModel> getChatWithIdentity(long entityId); Maybe<RoomChatModel> getChatWithIdentity(long entityId);
@Query("SELECT chats.* FROM chats JOIN entities WHERE fk_account_id = :accountId AND jid = :jid") @Query("SELECT chats.* FROM chats JOIN entities WHERE fk_account_id = :accountId AND jid = :jid")
LiveData<RoomChatModel> getChatWithJid(long accountId, EntityBareJid jid); Maybe<RoomChatModel> getChatWithJid(long accountId, EntityBareJid jid);
@Query("SELECT chats.* FROM chats JOIN contacts WHERE contacts.pk_contact_id = :contactId") @Query("SELECT chats.* FROM chats JOIN contacts WHERE contacts.pk_contact_id = :contactId")
LiveData<RoomChatModel> getChatWithContact(long contactId); Maybe<RoomChatModel> getChatWithContact(long contactId);
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
@ -12,6 +11,10 @@ import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidCon
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import static androidx.room.OnConflictStrategy.REPLACE; import static androidx.room.OnConflictStrategy.REPLACE;
@Dao @Dao
@ -20,33 +23,27 @@ public interface ContactAttributesDao extends BaseDao<RoomContactAttributes> {
@Override @Override
@Insert(onConflict = REPLACE) @Insert(onConflict = REPLACE)
long insert(RoomContactAttributes entity); Single<Long> insert(RoomContactAttributes entity);
@Query("SELECT * FROM contacts WHERE pk_contact_id = :id") @Query("SELECT * FROM contacts WHERE pk_contact_id = :id")
LiveData<RoomContactAttributes> getContact(long id); Maybe<RoomContactAttributes> getContact(long id);
@Query("SELECT * FROM contacts WHERE pk_contact_id = :id")
RoomContactAttributes syncGetContact(long id);
@Query("SELECT * FROM contacts WHERE fk_entity_id = :entityId") @Query("SELECT * FROM contacts WHERE fk_entity_id = :entityId")
LiveData<RoomContactAttributes> getContactForEntityId(long entityId); Maybe<RoomContactAttributes> getContactForEntityId(long entityId);
@Query("SELECT * FROM contacts WHERE fk_entity_id = :entityId")
RoomContactAttributes syncGetContactForEntityId(long entityId);
/** /**
* Return a {@link LiveData} wrapping a {@link List} of all {@link RoomContactAttributes RosterEntries} * Return a {@link Observable} wrapping a {@link List} of all {@link RoomContactAttributes RosterEntries}
* which are currently found in the database. * which are currently found in the database.
* *
* @return * @return
*/ */
@Query("SELECT * FROM contacts") @Query("SELECT * FROM contacts")
LiveData<List<RoomContactAttributes>> getAllContacts(); Observable<List<RoomContactAttributes>> getAllContacts();
@Query("SELECT contacts.* FROM contacts JOIN entities " + @Query("SELECT contacts.* FROM contacts JOIN entities " +
"WHERE contacts.fk_account_id = :accountId AND jid = :jid") "WHERE contacts.fk_account_id = :accountId AND jid = :jid")
RoomContactAttributes getContactByJid(long accountId, EntityBareJid jid); Maybe<RoomContactAttributes> getContactByJid(long accountId, EntityBareJid jid);
@Query("SELECT * FROM contacts WHERE fk_account_id = :accountId") @Query("SELECT * FROM contacts WHERE fk_account_id = :accountId")
LiveData<List<RoomContactAttributes>> getContactsForAccount(long accountId); Observable<List<RoomContactAttributes>> getContactsForAccount(long accountId);
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.TypeConverters; import androidx.room.TypeConverters;
@ -12,6 +11,9 @@ import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidCon
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.PREFIX; import static org.mercury_im.messenger.persistence.room.model.RoomContactModel.PREFIX;
@Dao @Dao
@ -25,7 +27,7 @@ public interface ContactDao {
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " + "entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
"FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id " + "FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id " +
"WHERE entities.fk_account_id = :accountId AND entities.jid = :bareJid") "WHERE entities.fk_account_id = :accountId AND entities.jid = :bareJid")
LiveData<RoomContactModel> getContactAndEntity(long accountId, EntityBareJid bareJid); Maybe<RoomContactModel> getContactAndEntity(long accountId, EntityBareJid bareJid);
@Query("SELECT contacts.*, " + @Query("SELECT contacts.*, " +
"entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " + "entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " +
@ -34,7 +36,7 @@ public interface ContactDao {
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " + "entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
"FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id " + "FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id " +
"WHERE entities.fk_account_id = :accountId") "WHERE entities.fk_account_id = :accountId")
LiveData<List<RoomContactModel>> getAllContactAndEntities(long accountId); Observable<List<RoomContactModel>> getAllContactAndEntities(long accountId);
@Query("SELECT contacts.*, " + @Query("SELECT contacts.*, " +
"entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " + "entities." + RoomEntityModel.KEY_ID + " AS " + PREFIX + RoomEntityModel.KEY_ID + ", " +
@ -42,5 +44,5 @@ public interface ContactDao {
"entities." + RoomEntityModel.KEY_JID + " AS " + PREFIX + RoomEntityModel.KEY_JID + ", " + "entities." + RoomEntityModel.KEY_JID + " AS " + PREFIX + RoomEntityModel.KEY_JID + ", " +
"entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " + "entities." + RoomEntityModel.KEY_AVATAR + " AS " + PREFIX + RoomEntityModel.KEY_AVATAR + " " +
"FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id") "FROM contacts INNER JOIN entities ON contacts.fk_entity_id = entities.pk_entity_id")
LiveData<List<RoomContactModel>> getAllContactAndEntities(); Observable<List<RoomContactModel>> getAllContactAndEntities();
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.Query; import androidx.room.Query;
@ -10,6 +9,9 @@ import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel; import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter; import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
import io.reactivex.Maybe;
import io.reactivex.Single;
import static androidx.room.OnConflictStrategy.REPLACE; import static androidx.room.OnConflictStrategy.REPLACE;
@Dao @Dao
@ -18,18 +20,11 @@ public interface EntityDao extends BaseDao<RoomEntityModel> {
@Override @Override
@Insert(onConflict = REPLACE) @Insert(onConflict = REPLACE)
long insert(RoomEntityModel entity); Single<Long> insert(RoomEntityModel entity);
@Query("SELECT * FROM entities WHERE pk_entity_id = :id") @Query("SELECT * FROM entities WHERE pk_entity_id = :id")
LiveData<RoomEntityModel> getEntity(long id); Maybe<RoomEntityModel> getEntity(long id);
@Query("SELECT * FROM entities WHERE pk_entity_id = :id")
RoomEntityModel getEntitySync(long id);
@Query("SELECT * FROM entities WHERE fk_account_id = :accountId AND jid = :jid") @Query("SELECT * FROM entities WHERE fk_account_id = :accountId AND jid = :jid")
LiveData<RoomEntityModel> getEntityFor(long accountId, EntityBareJid jid); Maybe<RoomEntityModel> getEntityFor(long accountId, EntityBareJid jid);
@Query("SELECT * FROM entities WHERE fk_account_id = :accountId AND jid = :jid")
RoomEntityModel getEntityForSync(long accountId, EntityBareJid jid);
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.room.dao; package org.mercury_im.messenger.persistence.room.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.TypeConverters; import androidx.room.TypeConverters;
@ -11,17 +10,19 @@ import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidCon
import java.util.List; import java.util.List;
import io.reactivex.Observable;
@Dao @Dao
@TypeConverters(EntityBareJidConverter.class) @TypeConverters(EntityBareJidConverter.class)
public interface MessageDao extends BaseDao<RoomMessageModel> { public interface MessageDao extends BaseDao<RoomMessageModel> {
@Query("SELECT * FROM messages WHERE fk_account_id = :accountId ORDER BY send_date ASC") @Query("SELECT * FROM messages WHERE fk_account_id = :accountId ORDER BY send_date ASC")
LiveData<List<RoomMessageModel>> getAllMessagesOf(long accountId); Observable<List<RoomMessageModel>> getAllMessagesOf(long accountId);
@Query("SELECT * FROM messages WHERE fk_account_id = :accountId AND `from` = :sender ORDER BY send_date ASC") @Query("SELECT * FROM messages WHERE fk_account_id = :accountId AND `from` = :sender ORDER BY send_date ASC")
LiveData<List<RoomMessageModel>> getAllMessagesFrom(long accountId, EntityBareJid sender); Observable<List<RoomMessageModel>> getAllMessagesFrom(long accountId, EntityBareJid sender);
@Query("SELECT * FROM messages WHERE fk_account_id = :accountId AND (`from` = :peer OR `to` = :peer) ORDER BY send_date ASC") @Query("SELECT * FROM messages WHERE fk_account_id = :accountId AND (`from` = :peer OR `to` = :peer) ORDER BY send_date ASC")
LiveData<List<RoomMessageModel>> getAllMessagesInConversation(long accountId, EntityBareJid peer); Observable<List<RoomMessageModel>> getAllMessagesInConversation(long accountId, EntityBareJid peer);
} }

View File

@ -1,19 +1,18 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import androidx.room.Transaction;
import org.mercury_im.messenger.persistence.repository.AccountRepository; import org.mercury_im.messenger.persistence.repository.AccountRepository;
import org.mercury_im.messenger.persistence.room.dao.AccountDao; import org.mercury_im.messenger.persistence.room.dao.AccountDao;
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel; import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public class IAccountRepository implements AccountRepository<RoomAccountModel> { public class IAccountRepository implements AccountRepository<RoomAccountModel> {
private final AccountDao accountDao; private final AccountDao accountDao;
@ -24,67 +23,23 @@ public class IAccountRepository implements AccountRepository<RoomAccountModel> {
} }
@Override @Override
public LiveData<RoomAccountModel> getAccount(long accountId) { public Maybe<RoomAccountModel> getAccount(long accountId) {
return accountDao.getAccountById(accountId); return accountDao.getAccountById(accountId);
} }
@Override @Override
public LiveData<List<RoomAccountModel>> getAllAccountsLive() { public Observable<List<RoomAccountModel>> getAllAccounts() {
return accountDao.getAllAccountsLive();
}
@Override
public List<RoomAccountModel> getAllAccounts() {
return accountDao.getAllAccounts(); return accountDao.getAllAccounts();
} }
@Override @Override
public long insertAccount(RoomAccountModel accountModel) { public Single<Long> insertAccount(RoomAccountModel accountModel) {
InsertAsyncTask task = new InsertAsyncTask(accountDao); return accountDao.insert(accountModel);
try {
return task.execute(accountModel).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return -1;
} }
@Override @Override
public void updateState(long accountId, String state) { public Completable updateState(long accountId, String state) {
accountDao.updateConnectionState(accountId, state); return accountDao.updateConnectionState(accountId, state);
}
private static class InsertAsyncTask extends AsyncTask<RoomAccountModel, Void, Long> {
private final AccountDao accountDao;
private InsertAsyncTask(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
protected Long doInBackground(RoomAccountModel... accountModels) {
for (RoomAccountModel accountModel : accountModels) {
return accountDao.insert(accountModel);
}
return null;
}
}
private static class QueryAsyncTask extends AsyncTask<Long, Void, LiveData<RoomAccountModel>> {
private final AccountDao accountDao;
private QueryAsyncTask(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
protected LiveData<RoomAccountModel> doInBackground(Long... longs) {
return accountDao.getAccountById(longs[0]);
}
} }
} }

View File

@ -1,10 +1,9 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
import org.mercury_im.messenger.persistence.model.ContactModel;
import org.mercury_im.messenger.persistence.model.EntityModel; import org.mercury_im.messenger.persistence.model.EntityModel;
import org.mercury_im.messenger.persistence.repository.ChatRepository; import org.mercury_im.messenger.persistence.repository.ChatRepository;
import org.mercury_im.messenger.persistence.room.dao.ChatDao; import org.mercury_im.messenger.persistence.room.dao.ChatDao;
@ -14,6 +13,10 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
public class IChatRepository implements ChatRepository<RoomChatModel> { public class IChatRepository implements ChatRepository<RoomChatModel> {
private final ChatDao chatDao; private final ChatDao chatDao;
@ -24,32 +27,37 @@ public class IChatRepository implements ChatRepository<RoomChatModel> {
} }
@Override @Override
public LiveData<List<RoomChatModel>> getAllChats() { public Observable<List<RoomChatModel>> getAllChats() {
return chatDao.getAllChats(); return chatDao.getAllChats();
} }
@Override @Override
public LiveData<List<RoomChatModel>> getAllChatsOf(AccountModel accountModel) { public Observable<List<RoomChatModel>> getAllChatsOf(AccountModel accountModel) {
return chatDao.getAllChatsOf(accountModel.getId()); return chatDao.getAllChatsOf(accountModel.getId());
} }
@Override @Override
public LiveData<RoomChatModel> getChatWith(EntityModel identity) { public Maybe<RoomChatModel> getChatWith(EntityModel identity) {
return chatDao.getChatWithIdentity(identity.getId()); return chatDao.getChatWithIdentity(identity.getId());
} }
@Override @Override
public LiveData<RoomChatModel> getChatWith(AccountModel account, EntityBareJid jid) { public Maybe<RoomChatModel> getChatWith(AccountModel account, EntityBareJid jid) {
return chatDao.getChatWithJid(account.getId(), jid); return chatDao.getChatWithJid(account.getId(), jid);
} }
@Override @Override
public LiveData<RoomChatModel> getChatWith(ContactAttributes contact) { public Maybe<RoomChatModel> getChatWith(ContactAttributes contact) {
return chatDao.getChatWithContact(contact.getId()); return chatDao.getChatWithContact(contact.getId());
} }
@Override @Override
public void closeChat(RoomChatModel chat) { public Maybe<RoomChatModel> getChatWith(ContactModel contact) {
chatDao.delete(chat); return getChatWith(contact.getContact());
}
@Override
public Completable closeChat(RoomChatModel chat) {
return chatDao.delete(chat);
} }
} }

View File

@ -1,13 +1,15 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.lifecycle.LiveData;
import org.mercury_im.messenger.persistence.repository.ContactAttributesRepository; import org.mercury_im.messenger.persistence.repository.ContactAttributesRepository;
import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao; import org.mercury_im.messenger.persistence.room.dao.ContactAttributesDao;
import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes; import org.mercury_im.messenger.persistence.room.model.RoomContactAttributes;
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public class IContactAttributesRepository implements ContactAttributesRepository<RoomContactAttributes> { public class IContactAttributesRepository implements ContactAttributesRepository<RoomContactAttributes> {
private final ContactAttributesDao contactAttributesDao; private final ContactAttributesDao contactAttributesDao;
@ -17,22 +19,22 @@ public class IContactAttributesRepository implements ContactAttributesRepository
} }
@Override @Override
public LiveData<List<RoomContactAttributes>> getAllContactAttributes() { public Observable<List<RoomContactAttributes>> getAllContactAttributes() {
return contactAttributesDao.getAllContacts(); return contactAttributesDao.getAllContacts();
} }
@Override @Override
public void updateOrInsertContactAttributes(RoomContactAttributes attributes) { public Single<Long> updateOrInsertContactAttributes(RoomContactAttributes attributes) {
contactAttributesDao.insert(attributes); return contactAttributesDao.insert(attributes);
} }
@Override @Override
public LiveData<RoomContactAttributes> getContactAttributes(long id) { public Maybe<RoomContactAttributes> getContactAttributes(long id) {
return contactAttributesDao.getContact(id); return contactAttributesDao.getContact(id);
} }
@Override @Override
public LiveData<RoomContactAttributes> getContactAttributesForEntity(long entityId) { public Maybe<RoomContactAttributes> getContactAttributesForEntity(long entityId) {
return contactAttributesDao.getContactForEntityId(entityId); return contactAttributesDao.getContactForEntityId(entityId);
} }

View File

@ -1,7 +1,5 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.EntityModel; import org.mercury_im.messenger.persistence.model.EntityModel;
import org.mercury_im.messenger.persistence.repository.ContactRepository; import org.mercury_im.messenger.persistence.repository.ContactRepository;
@ -12,6 +10,9 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Maybe;
import io.reactivex.Observable;
public class IContactRepository implements ContactRepository<RoomContactModel> { public class IContactRepository implements ContactRepository<RoomContactModel> {
private final ContactDao dao; private final ContactDao dao;
@ -22,22 +23,22 @@ public class IContactRepository implements ContactRepository<RoomContactModel> {
} }
@Override @Override
public LiveData<RoomContactModel> getContact(long accountId, EntityBareJid jid) { public Maybe<RoomContactModel> getContact(long accountId, EntityBareJid jid) {
return dao.getContactAndEntity(accountId, jid); return dao.getContactAndEntity(accountId, jid);
} }
@Override @Override
public LiveData<RoomContactModel> getContactForEntity(EntityModel entityModel) { public Maybe<RoomContactModel> getContactForEntity(EntityModel entityModel) {
return getContact(entityModel.getAccountId(), entityModel.getJid()); return getContact(entityModel.getAccountId(), entityModel.getJid());
} }
@Override @Override
public LiveData<List<RoomContactModel>> getAllContacts(long accountId) { public Observable<List<RoomContactModel>> getAllContactsOfAccount(long accountId) {
return dao.getAllContactAndEntities(accountId); return dao.getAllContactAndEntities(accountId);
} }
@Override @Override
public LiveData<List<RoomContactModel>> getAllContacts() { public Observable<List<RoomContactModel>> getAllContacts() {
return dao.getAllContactAndEntities(); return dao.getAllContactAndEntities();
} }
} }

View File

@ -1,7 +1,5 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
import org.mercury_im.messenger.persistence.repository.EntityRepository; import org.mercury_im.messenger.persistence.repository.EntityRepository;
@ -10,6 +8,8 @@ import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
import javax.inject.Inject; import javax.inject.Inject;
import io.reactivex.Maybe;
public class IEntityRepository implements EntityRepository<RoomEntityModel> { public class IEntityRepository implements EntityRepository<RoomEntityModel> {
private final EntityDao dao; private final EntityDao dao;
@ -20,12 +20,12 @@ public class IEntityRepository implements EntityRepository<RoomEntityModel> {
} }
@Override @Override
public <C extends ContactAttributes> LiveData<RoomEntityModel> getEntity(C contact) { public <C extends ContactAttributes> Maybe<RoomEntityModel> getEntity(C contact) {
return dao.getEntity(contact.getId()); return dao.getEntity(contact.getId());
} }
@Override @Override
public LiveData<RoomEntityModel> getEntity(long accountId, EntityBareJid jid) { public Maybe<RoomEntityModel> getEntity(long accountId, EntityBareJid jid) {
return dao.getEntityFor(accountId, jid); return dao.getEntityFor(accountId, jid);
} }
} }

View File

@ -1,15 +1,16 @@
package org.mercury_im.messenger.persistence.room.repository; package org.mercury_im.messenger.persistence.room.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.EntityFullJid;
import org.mercury_im.messenger.persistence.repository.MessageRepository; import org.mercury_im.messenger.persistence.repository.MessageRepository;
import org.mercury_im.messenger.persistence.room.dao.MessageDao; import org.mercury_im.messenger.persistence.room.dao.MessageDao;
import org.mercury_im.messenger.persistence.room.model.RoomMessageModel; import org.mercury_im.messenger.persistence.room.model.RoomMessageModel;
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public class IMessageRepository implements MessageRepository<RoomMessageModel> { public class IMessageRepository implements MessageRepository<RoomMessageModel> {
private final MessageDao messageDao; private final MessageDao messageDao;
@ -19,27 +20,32 @@ public class IMessageRepository implements MessageRepository<RoomMessageModel> {
} }
@Override @Override
public long insertMessage(RoomMessageModel message) { public Maybe<RoomMessageModel> getMessage(long accountId, long chatId, long messageId) {
return null;
}
@Override
public Single<Long> insertMessage(RoomMessageModel message) {
return messageDao.insert(message); return messageDao.insert(message);
} }
@Override @Override
public LiveData<List<RoomMessageModel>> getAllMessagesOf(long accountId) { public Observable<List<RoomMessageModel>> getAllMessagesOf(long accountId) {
return messageDao.getAllMessagesOf(accountId); return messageDao.getAllMessagesOf(accountId);
} }
@Override @Override
public LiveData<List<RoomMessageModel>> getAllMessagesFrom(long accountId, EntityBareJid contact) { public Observable<List<RoomMessageModel>> getAllMessagesFrom(long accountId, EntityBareJid contact) {
return messageDao.getAllMessagesFrom(accountId, contact); return messageDao.getAllMessagesFrom(accountId, contact);
} }
@Override @Override
public LiveData<List<RoomMessageModel>> getAllMessagesOfChat(long accountId, EntityBareJid peer) { public Observable<List<RoomMessageModel>> getAllMessagesOfChat(long accountId, EntityBareJid peer) {
return messageDao.getAllMessagesInConversation(accountId, peer); return messageDao.getAllMessagesInConversation(accountId, peer);
} }
@Override @Override
public LiveData<List<RoomMessageModel>> findMessageByQuery(String query) { public Observable<List<RoomMessageModel>> findMessageByQuery(String query) {
return null; return null;
} }
} }

View File

@ -1,27 +1,4 @@
apply plugin: 'com.android.library' apply plugin: 'java-library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies { dependencies {
@ -31,11 +8,8 @@ dependencies {
} }
} }
implementation fileTree(dir: 'libs', include: ['*.jar']) // RxJava2
implementation "io.reactivex.rxjava2:rxjava:$rxJava2Version"
implementation 'androidx.appcompat:appcompat:1.0.2' testImplementation "junit:junit:$junitVersion"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
api "androidx.paging:paging-runtime:$pagingVersion"
} }

View File

@ -1,6 +1,5 @@
package org.mercury_im.messenger.persistence.model; package org.mercury_im.messenger.persistence.model;
import androidx.annotation.NonNull;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
@ -17,7 +16,6 @@ public interface EntityModel {
void setId(long id); void setId(long id);
@NonNull
EntityBareJid getJid(); EntityBareJid getJid();
void setJid(EntityBareJid jid); void setJid(EntityBareJid jid);

View File

@ -1,20 +1,21 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import java.util.List; import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public interface AccountRepository<E extends AccountModel> { public interface AccountRepository<E extends AccountModel> {
LiveData<E> getAccount(long accountId); Maybe<E> getAccount(long accountId);
LiveData<List<E>> getAllAccountsLive(); Observable<List<E>> getAllAccounts();
List<E> getAllAccounts(); Single<Long> insertAccount(E accountModel);
long insertAccount(E accountModel); Completable updateState(long accountId, String state);
void updateState(long accountId, String state);
} }

View File

@ -1,26 +1,31 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.AccountModel; import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.model.ChatModel; import org.mercury_im.messenger.persistence.model.ChatModel;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
import org.mercury_im.messenger.persistence.model.ContactModel;
import org.mercury_im.messenger.persistence.model.EntityModel; import org.mercury_im.messenger.persistence.model.EntityModel;
import java.util.List; import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
public interface ChatRepository<E extends ChatModel> { public interface ChatRepository<E extends ChatModel> {
LiveData<List<E>> getAllChats(); Observable<List<E>> getAllChats();
LiveData<List<E>> getAllChatsOf(AccountModel account); Observable<List<E>> getAllChatsOf(AccountModel account);
LiveData<E> getChatWith(AccountModel account, EntityBareJid jid); Maybe<E> getChatWith(AccountModel account, EntityBareJid jid);
LiveData<E> getChatWith(EntityModel identity); Maybe<E> getChatWith(EntityModel identity);
LiveData<E> getChatWith(ContactAttributes contact); Maybe<E> getChatWith(ContactAttributes contact);
void closeChat(E chat); Maybe<E> getChatWith(ContactModel contact);
Completable closeChat(E chat);
} }

View File

@ -1,18 +1,20 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public interface ContactAttributesRepository<E extends ContactAttributes> { public interface ContactAttributesRepository<E extends ContactAttributes> {
LiveData<List<E>> getAllContactAttributes(); Observable<List<E>> getAllContactAttributes();
void updateOrInsertContactAttributes(E attributes); Single<Long> updateOrInsertContactAttributes(E attributes);
LiveData<E> getContactAttributes(long id); Maybe<E> getContactAttributes(long id);
LiveData<E> getContactAttributesForEntity(long entityId); Maybe<E> getContactAttributesForEntity(long entityId);
} }

View File

@ -1,7 +1,5 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.ContactModel; import org.mercury_im.messenger.persistence.model.ContactModel;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
@ -9,13 +7,16 @@ import org.mercury_im.messenger.persistence.model.EntityModel;
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
public interface ContactRepository<CE extends ContactModel<? extends ContactAttributes, ? extends EntityModel>> { public interface ContactRepository<CE extends ContactModel<? extends ContactAttributes, ? extends EntityModel>> {
LiveData<CE> getContact(long accountId, EntityBareJid jid); Maybe<CE> getContact(long accountId, EntityBareJid jid);
LiveData<CE> getContactForEntity(EntityModel entityModel); Maybe<CE> getContactForEntity(EntityModel entityModel);
LiveData<List<CE>> getAllContacts(long accountId); Observable<List<CE>> getAllContactsOfAccount(long accountId);
LiveData<List<CE>> getAllContacts(); Observable<List<CE>> getAllContacts();
} }

View File

@ -1,15 +1,15 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.ContactAttributes; import org.mercury_im.messenger.persistence.model.ContactAttributes;
import org.mercury_im.messenger.persistence.model.EntityModel; import org.mercury_im.messenger.persistence.model.EntityModel;
import io.reactivex.Maybe;
public interface EntityRepository<E extends EntityModel> { public interface EntityRepository<E extends EntityModel> {
<C extends ContactAttributes> LiveData<E> getEntity(C contact); <C extends ContactAttributes> Maybe<E> getEntity(C contact);
LiveData<E> getEntity(long accountId, EntityBareJid jid); Maybe<E> getEntity(long accountId, EntityBareJid jid);
} }

View File

@ -1,22 +1,25 @@
package org.mercury_im.messenger.persistence.repository; package org.mercury_im.messenger.persistence.repository;
import androidx.lifecycle.LiveData;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.EntityFullJid;
import org.mercury_im.messenger.persistence.model.MessageModel; import org.mercury_im.messenger.persistence.model.MessageModel;
import java.util.List; import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
public interface MessageRepository<E extends MessageModel> { public interface MessageRepository<E extends MessageModel> {
long insertMessage(E message); Maybe<E> getMessage(long accountId, long chatId, long messageId);
LiveData<List<E>> getAllMessagesOf(long accountId); Single<Long> insertMessage(E message);
LiveData<List<E>> getAllMessagesOfChat(long accountId, EntityBareJid peer); Observable<List<E>> getAllMessagesOf(long accountId);
LiveData<List<E>> getAllMessagesFrom(long accountId, EntityBareJid contact); Observable<List<E>> getAllMessagesOfChat(long accountId, EntityBareJid peer);
LiveData<List<E>> findMessageByQuery(String query); Observable<List<E>> getAllMessagesFrom(long accountId, EntityBareJid contact);
Observable<List<E>> findMessageByQuery(String query);
} }

View File

@ -1,4 +1,4 @@
include ':app', include ':app',
':xmpp_core', ':core',
':persistence-room', ':persistence-room',
':persistence' ':persistence'

View File

@ -70,16 +70,31 @@ ext {
// Other libraries // Other libraries
// Architecture Components // Architecture Components
lifecycleVersion = '2.2.0-alpha01' lifecycleVersion = "2.2.0-alpha01"
roomVersion = '2.1.0' roomVersion = "2.1.0"
roomRxJavaVersion = "2.1.0"
pagingVersion = "2.1.0" pagingVersion = "2.1.0"
appCompatVersion = "1.1.0-rc01"
// RxJava2
rxJava2Version = "2.2.11"
rxAndroidVersion = "2.1.1"
// Dagger 2 // Dagger 2
daggerVersion = '2.23.1' daggerVersion = "2.23.1"
// Android Support Library // Android Support Library
supportLibVersion = "28.0.0" supportLibVersion = "28.0.0"
// Butter Knife // Butter Knife
butterKnifeVersion = "10.1.0" butterKnifeVersion = "10.1.0"
// JUnit
junitVersion = "4.12"
andxTestJunitVersion = "1.1.1"
// androidx.test:runner
andxTestRunnerVersion = "1.2.0"
andxTestCoreVersion = "1.2.0"
andxTestEspressoVersion = "3.2.0"
} }

View File

@ -1,9 +0,0 @@
package org.mercury_im.messenger.xmpp_core;
import org.jivesoftware.smack.roster.PresenceEventListener;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smack.roster.RosterLoadedListener;
public interface RosterHandler extends RosterListener, RosterLoadedListener, PresenceEventListener {
}