Merging exp2
This commit is contained in:
commit
dd8f9cf6a3
|
@ -2,6 +2,7 @@ package org.mercury_im.messenger.di.component;
|
|||
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.di.module.AppModule;
|
||||
import org.mercury_im.messenger.handler.AvatarHandler;
|
||||
import org.mercury_im.messenger.handler.RoomPlainMessageHandler;
|
||||
import org.mercury_im.messenger.handler.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.persistence.room.RoomModule;
|
||||
|
@ -66,4 +67,6 @@ public interface AppComponent {
|
|||
void inject(RoomRosterHandler roomRosterHandler);
|
||||
|
||||
void inject(RoomPlainMessageHandler messageHandler);
|
||||
|
||||
void inject(AvatarHandler avatarHandler);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
package org.mercury_im.messenger.handler;
|
||||
|
||||
public class AvatarHandler {
|
||||
import org.jivesoftware.smackx.avatar.UserAvatarManager;
|
||||
import org.jivesoftware.smackx.avatar.element.MetadataExtension;
|
||||
import org.jivesoftware.smackx.avatar.listener.AvatarListener;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.persistence.repository.AvatarRepository;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomAvatarModel;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class AvatarHandler implements AvatarListener {
|
||||
|
||||
private final long accountId;
|
||||
|
||||
@Inject
|
||||
private AvatarRepository avatarRepository;
|
||||
|
||||
private UserAvatarManager avatarManager;
|
||||
|
||||
public AvatarHandler(long accountId, UserAvatarManager avatarManager) {
|
||||
this.accountId = accountId;
|
||||
this.avatarManager = avatarManager;
|
||||
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAvatarUpdateReceived(EntityBareJid user, MetadataExtension metadata) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package org.mercury_im.messenger.ui.login;
|
|||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
@ -15,43 +13,19 @@ import androidx.lifecycle.ViewModelProviders;
|
|||
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
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.handler.RoomRosterHandler;
|
||||
import org.mercury_im.messenger.persistence.model.AccountModel;
|
||||
import org.mercury_im.messenger.persistence.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomAccountModel;
|
||||
import org.mercury_im.messenger.core.MercuryConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import org.mercury_im.messenger.util.TextChangedListener;
|
||||
|
||||
import butterknife.BindView;
|
||||
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.
|
||||
*/
|
||||
public class LoginActivity extends AppCompatActivity implements TextView.OnEditorActionListener {
|
||||
|
||||
@Inject
|
||||
AccountRepository accountRepository;
|
||||
|
||||
// UI references.
|
||||
@BindView(R.id.jid)
|
||||
TextInputEditText mJidView;
|
||||
|
@ -77,15 +51,63 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
|
|||
viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
|
||||
displayCredentials(viewModel.getAccount());
|
||||
|
||||
viewModel.getJidError().observe(this, jidError -> {
|
||||
if (jidError == null) return;
|
||||
String errorMessage = null;
|
||||
switch (jidError) {
|
||||
case none:
|
||||
break;
|
||||
case emptyJid:
|
||||
errorMessage = getResources().getString(R.string.error_field_required);
|
||||
break;
|
||||
case invalidJid:
|
||||
errorMessage = getResources().getString(R.string.error_invalid_jid);
|
||||
break;
|
||||
case unknownJid:
|
||||
errorMessage = "Unknown Jid!";
|
||||
}
|
||||
mJidView.setError(errorMessage);
|
||||
});
|
||||
|
||||
viewModel.getPasswordError().observe(this, passwordError -> {
|
||||
if (passwordError == null) return;
|
||||
String errorMessage = null;
|
||||
switch (passwordError) {
|
||||
case none:
|
||||
break;
|
||||
case emptyPassword:
|
||||
errorMessage = getResources().getString(R.string.error_field_required);
|
||||
break;
|
||||
case invalidPassword:
|
||||
errorMessage = getResources().getString(R.string.error_invalid_password);
|
||||
break;
|
||||
case incorrectPassword:
|
||||
errorMessage = getResources().getString(R.string.error_incorrect_password);
|
||||
break;
|
||||
}
|
||||
mPasswordView.setError(errorMessage);
|
||||
});
|
||||
|
||||
mJidView.setOnEditorActionListener(this);
|
||||
mPasswordView.setOnEditorActionListener(this);
|
||||
|
||||
mSignInView.setOnClickListener(new OnClickListener() {
|
||||
mJidView.addTextChangedListener(new TextChangedListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
loginDetailsEntered();
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
viewModel.onJidInputChanged(charSequence.toString());
|
||||
Log.d("Mercury", "onTextChanged");
|
||||
}
|
||||
});
|
||||
|
||||
mPasswordView.addTextChangedListener(new TextChangedListener() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
viewModel.onPasswordInputChanged(charSequence.toString());
|
||||
Log.d("Mercury", "onTextChanged");
|
||||
}
|
||||
});
|
||||
|
||||
mSignInView.setOnClickListener(view -> viewModel.loginDetailsEntered());
|
||||
mSignInView.setEnabled(false);
|
||||
}
|
||||
|
||||
|
@ -105,106 +127,6 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: Move to ViewModel
|
||||
private void loginDetailsEntered() {
|
||||
boolean loginIntact = true;
|
||||
String jidInput = mJidView.getText().toString();
|
||||
if (jidInput.isEmpty()) {
|
||||
mJidView.setError(getResources().getString(R.string.error_field_required));
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
EntityBareJid jid = asValidJidOrNull(jidInput);
|
||||
if (jid == null) {
|
||||
mJidView.setError(getResources().getString(R.string.error_invalid_jid));
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
String password = mPasswordView.getText().toString();
|
||||
if (!isPasswordValid(password)) {
|
||||
mPasswordView.setError(getResources().getString(R.string.error_invalid_password));
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
if (loginIntact) {
|
||||
RoomAccountModel accountModel = new RoomAccountModel();
|
||||
accountModel.setEnabled(true);
|
||||
accountModel.setJid(jid);
|
||||
accountModel.setPassword(password);
|
||||
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);
|
||||
Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted.");
|
||||
attemptLogin(accountModel);
|
||||
}
|
||||
}
|
||||
|
||||
private void attemptLogin(AccountModel accountModel) {
|
||||
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
|
||||
.setHost(accountModel.getJid().getDomain().toString())
|
||||
.setXmppAddressAndPassword(accountModel.getJid(), accountModel.getPassword())
|
||||
.setConnectTimeout(2 * 60 * 1000)
|
||||
.build();
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
XMPPTCPConnection connection = new XMPPTCPConnection(configuration);
|
||||
connection.setUseStreamManagementResumption(true);
|
||||
connection.setUseStreamManagement(true);
|
||||
MercuryConnection mercuryConnection = new MercuryConnection(connection, accountModel.getId());
|
||||
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
|
||||
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
|
||||
|
||||
connection.connect().login();
|
||||
Log.d(MercuryImApplication.TAG, "Logged in for " + accountModel.getJid().toString());
|
||||
} catch (XmppStringprepException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SmackException e) {
|
||||
e.printStackTrace();
|
||||
} catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
super.finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the input string into a {@link EntityBareJid} and return it.
|
||||
* Return null on failure.
|
||||
* @param input input string
|
||||
* @return valid jid or null
|
||||
*/
|
||||
private EntityBareJid asValidJidOrNull(String input) {
|
||||
return JidCreate.entityBareFromOrNull(input);
|
||||
}
|
||||
|
||||
private boolean isPasswordValid(String password) {
|
||||
return !password.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
switch (v.getId()) {
|
||||
|
@ -217,7 +139,7 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
|
|||
|
||||
case R.id.password:
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) {
|
||||
loginDetailsEntered();
|
||||
viewModel.loginDetailsEntered();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,29 @@
|
|||
package org.mercury_im.messenger.ui.login;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
import org.mercury_im.messenger.MercuryImApplication;
|
||||
import org.mercury_im.messenger.core.MercuryConnection;
|
||||
import org.mercury_im.messenger.handler.RoomPlainMessageHandler;
|
||||
import org.mercury_im.messenger.handler.RoomRosterHandler;
|
||||
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 java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -16,13 +33,67 @@ public class LoginViewModel extends ViewModel {
|
|||
@Inject
|
||||
AccountRepository accountRepository;
|
||||
|
||||
private XmppConnectionService connectionService;
|
||||
|
||||
private String jid;
|
||||
private String password;
|
||||
|
||||
private MutableLiveData<JidError> jidError = new MutableLiveData<>();
|
||||
private MutableLiveData<PasswordError> passwordError = new MutableLiveData<>();
|
||||
|
||||
private MutableLiveData<RoomAccountModel> account = new MutableLiveData<>();
|
||||
|
||||
public LoginViewModel() {
|
||||
super();
|
||||
MercuryImApplication.getApplication().getAppComponent().inject(this);
|
||||
init(new RoomAccountModel());
|
||||
}
|
||||
|
||||
public enum JidError {
|
||||
none,
|
||||
emptyJid,
|
||||
invalidJid,
|
||||
unknownJid
|
||||
}
|
||||
|
||||
public enum PasswordError {
|
||||
none,
|
||||
emptyPassword,
|
||||
invalidPassword,
|
||||
incorrectPassword
|
||||
}
|
||||
|
||||
public void onJidInputChanged(String input) {
|
||||
this.jid = input;
|
||||
|
||||
}
|
||||
|
||||
public void onPasswordInputChanged(String input) {
|
||||
this.password = input;
|
||||
}
|
||||
|
||||
public LiveData<JidError> getJidError() {
|
||||
return jidError;
|
||||
}
|
||||
|
||||
public LiveData<PasswordError> getPasswordError() {
|
||||
return passwordError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse the input string into a {@link EntityBareJid} and return it.
|
||||
* Return null on failure.
|
||||
* @param input input string
|
||||
* @return valid jid or null
|
||||
*/
|
||||
private EntityBareJid asValidJidOrNull(String input) {
|
||||
return JidCreate.entityBareFromOrNull(input);
|
||||
}
|
||||
|
||||
private boolean isPasswordValid(String password) {
|
||||
return !password.isEmpty();
|
||||
}
|
||||
|
||||
public void init(@NonNull RoomAccountModel account) {
|
||||
this.account.setValue(account);
|
||||
}
|
||||
|
@ -37,4 +108,73 @@ public class LoginViewModel extends ViewModel {
|
|||
accountRepository.insertAccount(account);
|
||||
}
|
||||
}
|
||||
|
||||
public void loginDetailsEntered() {
|
||||
boolean loginIntact = true;
|
||||
if (jid.isEmpty()) {
|
||||
jidError.postValue(JidError.emptyJid);
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
EntityBareJid bareJid = asValidJidOrNull(jid);
|
||||
if (bareJid == null) {
|
||||
jidError.postValue(JidError.invalidJid);
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
if (!isPasswordValid(password)) {
|
||||
passwordError.postValue(PasswordError.invalidPassword);
|
||||
loginIntact = false;
|
||||
}
|
||||
|
||||
if (loginIntact) {
|
||||
RoomAccountModel accountModel = new RoomAccountModel();
|
||||
accountModel.setEnabled(true);
|
||||
accountModel.setJid(bareJid);
|
||||
accountModel.setPassword(password);
|
||||
long id = accountRepository.insertAccount(accountModel);
|
||||
accountModel.setId(id);
|
||||
Log.d(MercuryImApplication.TAG, "LoginActivity.loginDetailsEntered: Account " + id + " inserted.");
|
||||
attemptLogin(accountModel);
|
||||
}
|
||||
}
|
||||
|
||||
private void attemptLogin(AccountModel accountModel) {
|
||||
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
|
||||
.setHost(accountModel.getJid().getDomain().toString())
|
||||
.setXmppAddressAndPassword(accountModel.getJid(), accountModel.getPassword())
|
||||
.setConnectTimeout(2 * 60 * 1000)
|
||||
.build();
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
XMPPTCPConnection connection = new XMPPTCPConnection(configuration);
|
||||
connection.setUseStreamManagementResumption(true);
|
||||
connection.setUseStreamManagement(true);
|
||||
MercuryConnection mercuryConnection = new MercuryConnection(connection, accountModel.getId());
|
||||
connectionService.putConnection(accountModel.getId(), mercuryConnection);
|
||||
mercuryConnection.setRosterHandler(new RoomRosterHandler(mercuryConnection));
|
||||
mercuryConnection.setPlainMessageHandler(new RoomPlainMessageHandler(accountModel.getId()));
|
||||
|
||||
connection.connect().login();
|
||||
Log.d(MercuryImApplication.TAG, "Logged in for " + accountModel.getJid().toString());
|
||||
} catch (XmppStringprepException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SmackException e) {
|
||||
e.printStackTrace();
|
||||
} catch (XMPPException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public void setConnectionService(XmppConnectionService connectionService) {
|
||||
this.connectionService = connectionService;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.mercury_im.messenger.util;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
|
||||
public abstract class TextChangedListener implements TextWatcher {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.4.1'
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package org.mercury_im.messenger.persistence.store;
|
||||
|
||||
import dagger.MembersInjector;
|
||||
import javax.annotation.Generated;
|
||||
import javax.inject.Provider;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactRepository;
|
||||
|
||||
@Generated(
|
||||
value = "dagger.internal.codegen.ComponentProcessor",
|
||||
comments = "https://dagger.dev"
|
||||
)
|
||||
@SuppressWarnings({
|
||||
"unchecked",
|
||||
"rawtypes"
|
||||
})
|
||||
public final class RosterStore_MembersInjector implements MembersInjector<RosterStore> {
|
||||
private final Provider<ContactRepository> contactRepositoryProvider;
|
||||
|
||||
public RosterStore_MembersInjector(Provider<ContactRepository> contactRepositoryProvider) {
|
||||
this.contactRepositoryProvider = contactRepositoryProvider;
|
||||
}
|
||||
|
||||
public static MembersInjector<RosterStore> create(
|
||||
Provider<ContactRepository> contactRepositoryProvider) {
|
||||
return new RosterStore_MembersInjector(contactRepositoryProvider);}
|
||||
|
||||
@Override
|
||||
public void injectMembers(RosterStore instance) {
|
||||
injectContactRepository(instance, contactRepositoryProvider.get());
|
||||
}
|
||||
|
||||
public static void injectContactRepository(RosterStore instance,
|
||||
ContactRepository contactRepository) {
|
||||
instance.contactRepository = contactRepository;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 1,
|
||||
"identityHash": "1149b7d295726ec2043486e660dcf75d",
|
||||
"identityHash": "6f81947a36983067c387ec3ce77eb1cc",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "contacts",
|
||||
|
@ -371,12 +371,79 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "avatars",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`pk_avatar_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `fk_entity_id` INTEGER NOT NULL, `sha1sum` TEXT, `bytes` BLOB, FOREIGN KEY(`fk_entity_id`) REFERENCES `entities`(`pk_entity_id`) ON UPDATE NO ACTION ON DELETE RESTRICT )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "avatarId",
|
||||
"columnName": "pk_avatar_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "entityId",
|
||||
"columnName": "fk_entity_id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "sha1sum",
|
||||
"columnName": "sha1sum",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "bytes",
|
||||
"columnName": "bytes",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"pk_avatar_id"
|
||||
],
|
||||
"autoGenerate": true
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_avatars_pk_avatar_id",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"pk_avatar_id"
|
||||
],
|
||||
"createSql": "CREATE INDEX `index_avatars_pk_avatar_id` ON `${TABLE_NAME}` (`pk_avatar_id`)"
|
||||
},
|
||||
{
|
||||
"name": "index_avatars_fk_entity_id",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"fk_entity_id"
|
||||
],
|
||||
"createSql": "CREATE UNIQUE INDEX `index_avatars_fk_entity_id` ON `${TABLE_NAME}` (`fk_entity_id`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "entities",
|
||||
"onDelete": "RESTRICT",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"fk_entity_id"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"pk_entity_id"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1149b7d295726ec2043486e660dcf75d')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '6f81947a36983067c387ec3ce77eb1cc')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -10,42 +10,37 @@ import androidx.room.migration.Migration;
|
|||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import org.mercury_im.messenger.persistence.room.dao.AccountDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
|
||||
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.ContactAttributesDao;
|
||||
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.model.RoomAccountModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomAvatarModel;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomChatModel;
|
||||
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.RoomMessageModel;
|
||||
|
||||
@Database(version = 2,
|
||||
@Database(version = 1,
|
||||
entities = {
|
||||
RoomContactAttributes.class,
|
||||
RoomAccountModel.class,
|
||||
RoomChatModel.class,
|
||||
RoomMessageModel.class,
|
||||
RoomEntityModel.class
|
||||
RoomEntityModel.class,
|
||||
RoomAvatarModel.class
|
||||
})
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
|
||||
private static final String DB_NAME = "mercury_db";
|
||||
private static AppDatabase INSTANCE;
|
||||
|
||||
static Migration m1_2 = new Migration(1, 2) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("ALTER TABLE accounts ADD COLUMN state TEXT");
|
||||
}
|
||||
};
|
||||
|
||||
public static AppDatabase getDatabase(final Context context) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||
AppDatabase.class, DB_NAME)
|
||||
.addMigrations(m1_2)
|
||||
.build();
|
||||
}
|
||||
return INSTANCE;
|
||||
|
@ -61,5 +56,7 @@ public abstract class AppDatabase extends RoomDatabase {
|
|||
|
||||
public abstract EntityDao entityDao();
|
||||
|
||||
public abstract ContactDao contactAndEntityDao();
|
||||
public abstract ContactDao contactDao();
|
||||
|
||||
public abstract AvatarDao avatarDao();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.mercury_im.messenger.persistence.room;
|
|||
import android.app.Application;
|
||||
|
||||
import org.mercury_im.messenger.persistence.room.dao.AccountDao;
|
||||
import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
|
||||
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.ContactAttributesDao;
|
||||
|
@ -69,4 +70,10 @@ public class RoomModule {
|
|||
ContactDao provideContactAndEntityDao() {
|
||||
return mAppDatabase.contactAndEntityDao();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
AvatarDao providerAvatarDao() {
|
||||
return mAppDatabase.avatarDao();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
package org.mercury_im.messenger.persistence.room;
|
||||
|
||||
import org.mercury_im.messenger.persistence.repository.AccountRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.AvatarRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ChatRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactRepository;
|
||||
import org.mercury_im.messenger.persistence.repository.ContactAttributesRepository;
|
||||
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.AvatarDao;
|
||||
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.ContactAttributesDao;
|
||||
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.IAvatarRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IChatRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IContactRepository;
|
||||
import org.mercury_im.messenger.persistence.room.repository.IContactAttributesRepository;
|
||||
|
@ -62,4 +65,10 @@ public class RoomRepositoryModule {
|
|||
ContactRepository provideContactRepository(ContactDao dao) {
|
||||
return new IContactRepository(dao);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
AvatarRepository provideAvatarRepository(AvatarDao avatarDao) {
|
||||
return new IAvatarRepository(avatarDao);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.mercury_im.messenger.persistence.room.dao;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
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.RoomAvatarModel;
|
||||
import org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
|
||||
|
||||
@Dao
|
||||
@TypeConverters(EntityBareJidConverter.class)
|
||||
@WorkerThread
|
||||
public interface AvatarDao extends BaseDao<RoomAvatarModel> {
|
||||
|
||||
@Query("SELECT * FROM avatars WHERE pk_avatar_id = :avatarId")
|
||||
LiveData<RoomAvatarModel> getAvatarById(long avatarId);
|
||||
|
||||
@Query("SELECT * FROM avatars WHERE fk_entity_id = :entityId")
|
||||
LiveData<RoomAvatarModel> getAvatarByEntityId(long entityId);
|
||||
|
||||
@Query("SELECT avatars.* " +
|
||||
"FROM avatars INNER JOIN entities ON avatars.fk_entity_id = entities.pk_entity_id " +
|
||||
"WHERE entities.jid = :jid")
|
||||
LiveData<RoomAvatarModel> getAvatarByJid(EntityBareJid jid);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package org.mercury_im.messenger.persistence.room.model;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.ForeignKey;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import org.mercury_im.messenger.persistence.model.AvatarModel;
|
||||
|
||||
import static androidx.room.ForeignKey.RESTRICT;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomAvatarModel.KEY_ENTITY_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomAvatarModel.KEY_ID;
|
||||
import static org.mercury_im.messenger.persistence.room.model.RoomAvatarModel.TABLE;
|
||||
|
||||
@Entity(tableName = TABLE,
|
||||
indices = {
|
||||
@Index(value = KEY_ID),
|
||||
@Index(value = KEY_ENTITY_ID, unique = true)
|
||||
},
|
||||
foreignKeys = {
|
||||
@ForeignKey(entity = RoomEntityModel.class,
|
||||
parentColumns = RoomEntityModel.KEY_ID,
|
||||
childColumns = KEY_ENTITY_ID,
|
||||
onDelete = RESTRICT)
|
||||
})
|
||||
public class RoomAvatarModel implements AvatarModel {
|
||||
|
||||
public static final String TABLE = "avatars";
|
||||
public static final String KEY_ID = "pk_avatar_id";
|
||||
public static final String KEY_ENTITY_ID = "fk_entity_id";
|
||||
public static final String KEY_SHA1_SUM = "sha1sum";
|
||||
public static final String KEY_BYTES = "bytes";
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = KEY_ID)
|
||||
private long avatarId;
|
||||
|
||||
@ColumnInfo(name = KEY_ENTITY_ID)
|
||||
private long entityId;
|
||||
|
||||
@ColumnInfo(name = KEY_SHA1_SUM)
|
||||
private String sha1Sum;
|
||||
|
||||
@ColumnInfo(name = KEY_BYTES)
|
||||
private byte[] bytes;
|
||||
|
||||
@Override
|
||||
public long getAvatarId() {
|
||||
return avatarId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAvatarId(long id) {
|
||||
this.avatarId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long entityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEntityId(long entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSha1Sum() {
|
||||
return sha1Sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSha1Sum(String sha1Sum) {
|
||||
this.sha1Sum = sha1Sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
return bytes.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBytes(byte[] bytes) {
|
||||
this.bytes = bytes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.mercury_im.messenger.persistence.room.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.repository.AvatarRepository;
|
||||
import org.mercury_im.messenger.persistence.room.dao.AvatarDao;
|
||||
import org.mercury_im.messenger.persistence.room.model.RoomAvatarModel;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class IAvatarRepository implements AvatarRepository<RoomAvatarModel> {
|
||||
|
||||
private final AvatarDao dao;
|
||||
|
||||
@Inject
|
||||
public IAvatarRepository(AvatarDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomAvatarModel> getAvatarById(long avatarId) {
|
||||
return dao.getAvatarById(avatarId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomAvatarModel> getAvatarByEntityId(long entityId) {
|
||||
return dao.getAvatarByEntityId(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiveData<RoomAvatarModel> getAvatarByJid(EntityBareJid jid) {
|
||||
return dao.getAvatarByJid(jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long updateOrInsertAvatar(RoomAvatarModel avatarModel) {
|
||||
return dao.insert(avatarModel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package org.mercury_im.messenger.persistence.model;
|
||||
|
||||
public interface AvatarModel {
|
||||
|
||||
long getAvatarId();
|
||||
|
||||
void setAvatarId(long id);
|
||||
|
||||
long entityId();
|
||||
|
||||
void setEntityId(long entityId);
|
||||
|
||||
String getSha1Sum();
|
||||
|
||||
void setSha1Sum(String sha1Sum);
|
||||
|
||||
byte[] getBytes();
|
||||
|
||||
void setBytes(byte[] bytes);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.mercury_im.messenger.persistence.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.mercury_im.messenger.persistence.model.AvatarModel;
|
||||
|
||||
public interface AvatarRepository<E extends AvatarModel> {
|
||||
|
||||
LiveData<E> getAvatarById(long avatarId);
|
||||
|
||||
LiveData<E> getAvatarByEntityId(long entityId);
|
||||
|
||||
LiveData<E> getAvatarByJid(EntityBareJid jid);s
|
||||
|
||||
long updateOrInsertAvatar(E avatarModel);
|
||||
}
|
|
@ -3,8 +3,8 @@ ext {
|
|||
// Quickly switch between unique and normal releases using the toggle below
|
||||
|
||||
// Version Strings for non-unique releases
|
||||
/*
|
||||
smackVersion = "4.4.0-alpha2-SNAPSHOT"
|
||||
//*
|
||||
smackVersion = "4.4.0-alpha3-SNAPSHOT"
|
||||
|
||||
smackAndroidVersion = smackVersion
|
||||
smackAndroidExtensionsVersion = smackVersion
|
||||
|
@ -71,11 +71,13 @@ ext {
|
|||
|
||||
// Architecture Components
|
||||
lifecycleVersion = "2.2.0-alpha01"
|
||||
roomVersion = "2.1.0"
|
||||
roomRxJavaVersion = "2.1.0"
|
||||
pagingVersion = "2.1.0"
|
||||
appCompatVersion = "1.1.0-rc01"
|
||||
|
||||
// Room
|
||||
roomVersion = "2.1.0"
|
||||
roomRxJavaVersion = "2.1.0"
|
||||
|
||||
// RxJava2
|
||||
rxJava2Version = "2.2.11"
|
||||
rxAndroidVersion = "2.1.1"
|
||||
|
|
Loading…
Reference in New Issue