This commit is contained in:
Paul Schaub 2019-05-18 10:06:16 +02:00
parent 3c817a3172
commit ac2037e06c
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
39 changed files with 291 additions and 169 deletions

View File

@ -9,7 +9,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
multiDexEnabled true multiDexEnabled true
} }
@ -71,30 +71,33 @@ check.configure {
// Dependency versions are located in version.gradle // Dependency versions are located in version.gradle
dependencies { dependencies {
/*
architecture components for database and lifecycle management
*/
// architecture components for database and lifecycle management // ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$archCompVersion" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"
implementation "android.arch.persistence.room:runtime:$archCompVersion" annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycleVersion"
implementation "android.arch.lifecycle:extensions:$archCompVersion"
annotationProcessor "android.arch.lifecycle:compiler:$archCompVersion" // Room
annotationProcessor "android.arch.persistence.room:compiler:$archCompVersion" implementation "androidx.room:room-runtime:$roomVersion"
annotationProcessor "androidx.room:room-compiler:$roomVersion"
// 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"
// support libraries // support libraries
implementation "com.android.support:appcompat-v7:$supportLibVersion" implementation 'androidx.appcompat:appcompat:1.0.2'
implementation "com.android.support:design:$supportLibVersion" implementation 'com.google.android.material:material:1.0.0'
implementation "com.android.support:support-v4:$supportLibVersion" implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "com.android.support:support-vector-drawable:$supportLibVersion" implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
implementation "com.android.support:cardview-v7:$supportLibVersion" implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
// circular image viewer for avatars // circular image viewer for avatars
implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'de.hdodenhof:circleimageview:2.2.0'

View File

@ -1,8 +1,8 @@
package org.mercury_im.messenger; package org.mercury_im.messenger;
import android.content.Context; import android.content.Context;
import android.support.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@ -1,10 +1,11 @@
package org.mercury_im.messenger.persistence.database; package org.mercury_im.messenger.persistence.database;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context; import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import org.mercury_im.messenger.persistence.database.dao.AccountDao; import org.mercury_im.messenger.persistence.database.dao.AccountDao;
import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao;
import org.mercury_im.messenger.persistence.database.model.AccountModel; import org.mercury_im.messenger.persistence.database.model.AccountModel;

View File

@ -1,13 +1,13 @@
package org.mercury_im.messenger.persistence.database.dao; package org.mercury_im.messenger.persistence.database.dao;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import android.arch.persistence.room.Dao; import androidx.annotation.WorkerThread;
import android.arch.persistence.room.Delete; import androidx.room.Dao;
import android.arch.persistence.room.Insert; import androidx.room.Delete;
import android.arch.persistence.room.Query; import androidx.room.Insert;
import android.arch.persistence.room.TypeConverters; import androidx.room.Query;
import android.arch.persistence.room.Update; import androidx.room.TypeConverters;
import android.support.annotation.WorkerThread; import androidx.room.Update;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.database.model.AccountModel; import org.mercury_im.messenger.persistence.database.model.AccountModel;
@ -42,7 +42,7 @@ public interface AccountDao {
LiveData<AccountModel> getAccountByJid(EntityBareJid jid); LiveData<AccountModel> getAccountByJid(EntityBareJid jid);
@Insert @Insert
void insertAccount(AccountModel account); long insertAccount(AccountModel account);
@Update @Update
void updateAccount(AccountModel account); void updateAccount(AccountModel account);

View File

@ -1,18 +1,18 @@
package org.mercury_im.messenger.persistence.database.dao; package org.mercury_im.messenger.persistence.database.dao;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import android.arch.persistence.room.Dao; import androidx.room.Dao;
import android.arch.persistence.room.Delete; import androidx.room.Delete;
import android.arch.persistence.room.Insert; import androidx.room.Insert;
import android.arch.persistence.room.Query; import androidx.room.Query;
import android.arch.persistence.room.TypeConverters; import androidx.room.TypeConverters;
import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter;
import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; import org.mercury_im.messenger.persistence.database.model.RosterEntryModel;
import java.util.List; import java.util.List;
import static android.arch.persistence.room.OnConflictStrategy.REPLACE; import static androidx.room.OnConflictStrategy.REPLACE;
@Dao @Dao
@TypeConverters(EntityBareJidConverter.class) @TypeConverters(EntityBareJidConverter.class)

View File

@ -1,9 +1,10 @@
package org.mercury_im.messenger.persistence.database.model; package org.mercury_im.messenger.persistence.database.model;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity; import androidx.room.ColumnInfo;
import android.arch.persistence.room.PrimaryKey; import androidx.room.Entity;
import android.arch.persistence.room.TypeConverters; import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter;

View File

@ -1,14 +1,15 @@
package org.mercury_im.messenger.persistence.database.model; package org.mercury_im.messenger.persistence.database.model;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey; import androidx.room.Entity;
import android.arch.persistence.room.PrimaryKey; import androidx.room.ForeignKey;
import android.arch.persistence.room.TypeConverters; import androidx.room.PrimaryKey;
import androidx.room.TypeConverters;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter; import org.mercury_im.messenger.persistence.database.type_converter.EntityBareJidConverter;
import static android.arch.persistence.room.ForeignKey.CASCADE; import static androidx.room.ForeignKey.CASCADE;
@Entity(foreignKeys = @ForeignKey(entity = AccountModel.class, @Entity(foreignKeys = @ForeignKey(entity = AccountModel.class,
parentColumns = "id", parentColumns = "id",

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.persistence.database.type_converter; package org.mercury_im.messenger.persistence.database.type_converter;
import android.arch.persistence.room.TypeConverter; import androidx.room.TypeConverter;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.persistence.database.type_converter; package org.mercury_im.messenger.persistence.database.type_converter;
import android.arch.persistence.room.TypeConverter; import androidx.room.TypeConverter;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.persistence.repository.account; package org.mercury_im.messenger.persistence.repository.account;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import org.mercury_im.messenger.persistence.database.model.AccountModel; import org.mercury_im.messenger.persistence.database.model.AccountModel;
@ -12,5 +12,5 @@ public interface AccountRepository {
LiveData<List<AccountModel>> getAllAccounts(); LiveData<List<AccountModel>> getAllAccounts();
void insertAccount(AccountModel accountModel); long insertAccount(AccountModel accountModel);
} }

View File

@ -1,12 +1,13 @@
package org.mercury_im.messenger.persistence.repository.account; package org.mercury_im.messenger.persistence.repository.account;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import android.os.AsyncTask; import android.os.AsyncTask;
import org.mercury_im.messenger.persistence.database.dao.AccountDao; import org.mercury_im.messenger.persistence.database.dao.AccountDao;
import org.mercury_im.messenger.persistence.database.model.AccountModel; import org.mercury_im.messenger.persistence.database.model.AccountModel;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject; import javax.inject.Inject;
@ -30,12 +31,19 @@ public class AccountRepositoryImpl implements AccountRepository {
} }
@Override @Override
public void insertAccount(AccountModel accountModel) { public long insertAccount(AccountModel accountModel) {
InsertAsyncTask task = new InsertAsyncTask(accountDao); InsertAsyncTask task = new InsertAsyncTask(accountDao);
task.execute(accountModel); try {
return task.execute(accountModel).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return -1;
} }
private static class InsertAsyncTask extends AsyncTask<AccountModel, Void, Void> { private static class InsertAsyncTask extends AsyncTask<AccountModel, Void, Long> {
private final AccountDao accountDao; private final AccountDao accountDao;
@ -44,9 +52,9 @@ public class AccountRepositoryImpl implements AccountRepository {
} }
@Override @Override
protected Void doInBackground(AccountModel... accountModels) { protected Long doInBackground(AccountModel... accountModels) {
for (AccountModel accountModel : accountModels) { for (AccountModel accountModel : accountModels) {
accountDao.insertAccount(accountModel); return accountDao.insertAccount(accountModel);
} }
return null; return null;
} }

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.persistence.repository.roster; package org.mercury_im.messenger.persistence.repository.roster;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import org.jivesoftware.smack.roster.RosterEntry; import org.jivesoftware.smack.roster.RosterEntry;
import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; import org.mercury_im.messenger.persistence.database.model.RosterEntryModel;

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.persistence.repository.roster; package org.mercury_im.messenger.persistence.repository.roster;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao; import org.mercury_im.messenger.persistence.database.dao.RosterEntryDao;
import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; import org.mercury_im.messenger.persistence.database.model.RosterEntryModel;

View File

@ -5,18 +5,28 @@ import android.app.PendingIntent;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import android.util.Log; import android.util.Log;
import android.util.LongSparseArray; import android.util.LongSparseArray;
import android.widget.Toast;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
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.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.Notifications; import org.mercury_im.messenger.Notifications;
import org.mercury_im.messenger.R; import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.database.AppDatabase; import org.mercury_im.messenger.persistence.database.AppDatabase;
import org.mercury_im.messenger.ui.MainActivity; import org.mercury_im.messenger.ui.MainActivity;
import java.io.IOException;
import java.net.InetAddress;
import javax.inject.Inject; import javax.inject.Inject;
/** /**
@ -25,26 +35,31 @@ import javax.inject.Inject;
*/ */
public class XmppService extends Service { public class XmppService extends Service {
private static final String TAG = MercuryImApplication.TAG; private static final String TAG = MercuryImApplication.TAG;
private static final String APP = "org.olomono.mercury"; private static final String APP = "org.olomono.mercury";
private static final String SERVICE = APP + ".XmppService"; private static final String SERVICE = APP + ".XmppService";
private static final String ACTION = SERVICE + ".ACTION"; private static final String ACTION = SERVICE + ".ACTION";
private static final String EVENT = SERVICE + ".EVENT"; private static final String EVENT = SERVICE + ".EVENT";
private static final String STATUS = SERVICE + ".STATUS"; private static final String EXTRA = SERVICE + ".EXTRA";
private static final String STATUS = SERVICE + ".STATUS";
public static final String ACTION_START = ACTION + ".START"; public static final String ACTION_START = ACTION + ".START";
public static final String ACTION_STOP = ACTION + ".STOP"; public static final String ACTION_STOP = ACTION + ".STOP";
public static final String ACTION_CONNECT = ACTION + ".CONNECT"; public static final String ACTION_CONNECT = ACTION + ".CONNECT";
public static final String ACTION_DISCONNECT = ACTION + ".DISCONNECT"; public static final String ACTION_DISCONNECT = ACTION + ".DISCONNECT";
public static final String ACTION_PING = ACTION + ".PING"; public static final String ACTION_PING = ACTION + ".PING";
public static final String EVENT_INCOMING_MESSAGE = ".INCOMING_MESSAGE"; public static final String EVENT_INCOMING_MESSAGE = EVENT + ".INCOMING_MESSAGE";
public static final String EVENT_OUTGOING_MESSAGE = ".OUTGOING_MESSAGE"; public static final String EVENT_OUTGOING_MESSAGE = EVENT + ".OUTGOING_MESSAGE";
public static final String STATUS_SUCCESS = STATUS + ".SUCCESS"; public static final String EXTRA_JID = EXTRA + ".JID";
public static final String STATUS_FAILURE = STATUS + ".FAILURE"; public static final String EXTRA_PASSWORD = EXTRA + ".PASSWORD";
public static final String EXTRA_ACCOUNT_ID = EXTRA + ".ACCOUNT_ID";
public static final String STATUS_SUCCESS = STATUS + ".SUCCESS";
public static final String STATUS_FAILURE = STATUS + ".FAILURE";
@Inject @Inject
AppDatabase database; AppDatabase database;
@ -81,7 +96,70 @@ public class XmppService extends Service {
case ACTION_STOP: case ACTION_STOP:
stopForeground(true); stopForeground(true);
break; break;
case ACTION_CONNECT:
String jid = intent.getStringExtra(EXTRA_JID);
EntityBareJid bareJid = JidCreate.entityBareFromOrNull(jid);
if (jid == null) {
Toast.makeText(this, "No JID provided.", Toast.LENGTH_SHORT).show();
return START_STICKY_COMPATIBILITY;
}
String password = intent.getStringExtra(EXTRA_PASSWORD);
if (password == null) {
Toast.makeText(this, "No Password provided.", Toast.LENGTH_SHORT).show();
return START_STICKY_COMPATIBILITY;
}
long accountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
if (accountId == -1) {
Toast.makeText(this, "No account ID provided.", Toast.LENGTH_SHORT).show();
return START_STICKY_COMPATIBILITY;
}
new Thread() {
public void run() {
XMPPTCPConnection con = null;
try
{
InetAddress address = InetAddress.getByName(bareJid.getDomain().toString());
XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
.setXmppDomain(bareJid.asDomainBareJid())
.setUsernameAndPassword(bareJid.getLocalpart().toString(), password)
.setHostAddress(address)
.setConnectTimeout(2 * 60 * 1000)
.build();
con = new XMPPTCPConnection(conf);
con.connect().login();
} catch(
XMPPException e)
{
e.printStackTrace();
} catch(
SmackException e)
{
e.printStackTrace();
} catch(
IOException e)
{
e.printStackTrace();
} catch(
InterruptedException e)
{
e.printStackTrace();
}
connections.put(intent.getLongExtra(EXTRA_ACCOUNT_ID,-1),con);
while (true) {
}
}
}.start();
break;
default: default:
break; break;
} }

View File

@ -1,11 +1,13 @@
package org.mercury_im.messenger.ui; package org.mercury_im.messenger.ui;
import androidx.lifecycle.Observer;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.FloatingActionButton; import androidx.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import android.support.v7.widget.Toolbar; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -55,6 +57,15 @@ public class MainActivity extends AppCompatActivity {
accountRepository.insertAccount(account); accountRepository.insertAccount(account);
} }
}); });
accountRepository.getAllAccounts().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
@ -89,24 +100,6 @@ public class MainActivity extends AppCompatActivity {
new addRosterEntry(database).execute(rosterEntry); new addRosterEntry(database).execute(rosterEntry);
} }
private static class ifNoAccountsThen extends AsyncTask<Runnable, Void, Void> {
private final AppDatabase database;
public ifNoAccountsThen(AppDatabase database) {
this.database = database;
}
@Override
protected Void doInBackground(Runnable... runnables) {
List<AccountModel> accounts = database.accountDao().getAllAccounts().getValue();
if (accounts == null || accounts.size() == 0) {
runnables[0].run();
}
return null;
}
}
private static class addRosterEntry extends AsyncTask<RosterEntryModel, Void, Void> { private static class addRosterEntry extends AsyncTask<RosterEntryModel, Void, Void> {
private AppDatabase database; private AppDatabase database;

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.ui.chat; package org.mercury_im.messenger.ui.chat;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import org.mercury_im.messenger.R; import org.mercury_im.messenger.R;

View File

@ -1,12 +1,12 @@
package org.mercury_im.messenger.ui.chat; package org.mercury_im.messenger.ui.chat;
import android.arch.lifecycle.Observer; import androidx.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.design.widget.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View File

@ -1,7 +1,7 @@
package org.mercury_im.messenger.ui.chat; package org.mercury_im.messenger.ui.chat;
import android.arch.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
public class ChatInputViewModel extends ViewModel { public class ChatInputViewModel extends ViewModel {

View File

@ -1,6 +1,6 @@
package org.mercury_im.messenger.ui.chat; package org.mercury_im.messenger.ui.chat;
import android.arch.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.database.model.Account; import org.mercury_im.messenger.persistence.database.model.Account;

View File

@ -1,8 +1,9 @@
package org.mercury_im.messenger.ui.login; package org.mercury_im.messenger.ui.login;
import android.arch.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -14,13 +15,22 @@ import android.widget.TextView;
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.R; import org.mercury_im.messenger.R;
import org.mercury_im.messenger.persistence.database.model.AccountModel;
import org.mercury_im.messenger.persistence.repository.account.AccountRepository;
import org.mercury_im.messenger.service.XmppService;
import javax.inject.Inject;
/** /**
* A login screen that offers login via email/password. * A login screen that offers login via email/password.
*/ */
public class LoginActivity extends AppCompatActivity implements TextView.OnEditorActionListener { public class LoginActivity extends AppCompatActivity implements TextView.OnEditorActionListener {
@Inject
AccountRepository accountRepository;
// UI references. // UI references.
private AutoCompleteTextView mJidView; private AutoCompleteTextView mJidView;
private EditText mPasswordView; private EditText mPasswordView;
@ -34,6 +44,8 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); setContentView(R.layout.activity_login);
MercuryImApplication.getApplication().getAppComponent().inject(this);
// Set up the login form. // Set up the login form.
mJidView = findViewById(R.id.jid); mJidView = findViewById(R.id.jid);
mPasswordView = findViewById(R.id.password); mPasswordView = findViewById(R.id.password);
@ -69,22 +81,43 @@ public class LoginActivity extends AppCompatActivity implements TextView.OnEdito
} }
private void loginDetailsEntered() { private void loginDetailsEntered() {
boolean loginIntact = true;
String jidInput = mJidView.getText().toString(); String jidInput = mJidView.getText().toString();
if (jidInput.isEmpty()) { if (jidInput.isEmpty()) {
mJidView.setError(getResources().getString(R.string.error_field_required)); mJidView.setError(getResources().getString(R.string.error_field_required));
loginIntact = false;
} }
EntityBareJid jid = asValidJidOrNull(jidInput); EntityBareJid jid = asValidJidOrNull(jidInput);
if (jid == null) { if (jid == null) {
mJidView.setError(getResources().getString(R.string.error_invalid_jid)); mJidView.setError(getResources().getString(R.string.error_invalid_jid));
loginIntact = false;
} }
String password = mPasswordView.getText().toString(); String password = mPasswordView.getText().toString();
if (!isPasswordValid(password)) { if (!isPasswordValid(password)) {
mPasswordView.setError(getResources().getString(R.string.error_invalid_password)); mPasswordView.setError(getResources().getString(R.string.error_invalid_password));
loginIntact = false;
} }
viewModel.login(); if (loginIntact) {
AccountModel accountModel = new AccountModel();
accountModel.setEnabled(true);
accountModel.setJid(jid);
accountModel.setPassword(password);
long id = accountRepository.insertAccount(accountModel);
attemptLogin(jid, password, id);
}
}
private void attemptLogin(EntityBareJid jid, String password, long accountId) {
Intent connectIntent = new Intent(getApplicationContext(), XmppService.class);
connectIntent.setAction(XmppService.ACTION_CONNECT);
connectIntent.putExtra(XmppService.EXTRA_JID, jid.toString());
connectIntent.putExtra(XmppService.EXTRA_PASSWORD, password);
connectIntent.putExtra(XmppService.EXTRA_ACCOUNT_ID, accountId);
startService(connectIntent);
} }
/** /**

View File

@ -1,8 +1,8 @@
package org.mercury_im.messenger.ui.login; package org.mercury_im.messenger.ui.login;
import android.arch.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import org.mercury_im.messenger.persistence.database.model.AccountModel; import org.mercury_im.messenger.persistence.database.model.AccountModel;

View File

@ -1,11 +1,11 @@
package org.mercury_im.messenger.ui.roster; package org.mercury_im.messenger.ui.roster;
import android.arch.lifecycle.Observer; import androidx.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import androidx.lifecycle.ViewModelProviders;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View File

@ -1,7 +1,7 @@
package org.mercury_im.messenger.ui.roster; package org.mercury_im.messenger.ui.roster;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View File

@ -1,9 +1,9 @@
package org.mercury_im.messenger.ui.roster; package org.mercury_im.messenger.ui.roster;
import android.app.Application; import android.app.Application;
import android.arch.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import org.mercury_im.messenger.MercuryImApplication; import org.mercury_im.messenger.MercuryImApplication;
import org.mercury_im.messenger.persistence.database.model.RosterEntryModel; import org.mercury_im.messenger.persistence.database.model.RosterEntryModel;

View File

@ -3,11 +3,11 @@ package org.mercury_im.messenger.ui.settings;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v7.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.support.v7.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View File

@ -12,7 +12,7 @@ import android.os.Bundle;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.support.v7.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.RingtonePreference; import android.preference.RingtonePreference;

View File

@ -31,7 +31,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -44,9 +44,9 @@
android:maxLines="1" android:maxLines="1"
android:singleLine="true" /> android:singleLine="true" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@ -62,7 +62,7 @@
android:maxLines="1" android:maxLines="1"
android:singleLine="true" /> android:singleLine="true" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<Button <Button
android:id="@+id/sign_in_button" android:id="@+id/sign_in_button"

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.MainActivity"> tools:context=".ui.MainActivity">
<android.support.design.widget.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" /> app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" /> <include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -30,4 +30,4 @@
android:layout_margin="@dimen/fab_margin" android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" /> app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/chat" android:id="@+id/chat"
@ -7,7 +7,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.chat.ChatInputFragment"> tools:context=".ui.chat.ChatInputFragment">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -17,7 +17,7 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/recycler_view_item_1"> tools:listitem="@layout/recycler_view_item_1">
</android.support.v7.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
<FrameLayout <FrameLayout
android:id="@+id/container_chat" android:id="@+id/container_chat"
@ -32,4 +32,4 @@
</FrameLayout> </FrameLayout>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -7,14 +7,14 @@
tools:context=".ui.roster.RosterFragment" tools:context=".ui.roster.RosterFragment"
tools:showIn="@layout/activity_main"> tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/roster_entry_list__recycler_view" android:id="@+id/roster_entry_list__recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/recycler_view_item"> tools:listitem="@layout/recycler_view_item">
</android.support.v7.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@ -49,4 +49,4 @@
app:layout_constraintTop_toTopOf="@+id/imageView2" app:layout_constraintTop_toTopOf="@+id/imageView2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" /> android:layout_marginEnd="8dp" />
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@ -49,4 +49,4 @@
app:layout_constraintTop_toTopOf="@+id/imageView2" app:layout_constraintTop_toTopOf="@+id/imageView2"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp" /> android:layout_marginEnd="8dp" />
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@ -53,4 +53,4 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/roster_entry__avatar" app:layout_constraintTop_toTopOf="@+id/roster_entry__avatar"
tools:text="@tools:sample/date/hhmm" /> tools:text="@tools:sample/date/hhmm" />
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -7,7 +7,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:background="@null"> android:background="@null">
<android.support.design.widget.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/chat_field__fab_add" android:id="@+id/chat_field__fab_add"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -22,7 +22,7 @@
app:layout_constraintVertical_bias="1.0" app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_add_white_24dp" /> app:srcCompat="@drawable/ic_add_white_24dp" />
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -34,7 +34,7 @@
card_view:cardElevation="6dp" card_view:cardElevation="6dp"
app:cardUseCompatPadding="true"> app:cardUseCompatPadding="true">
<android.support.constraint.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minHeight="56dp"> android:minHeight="56dp">
@ -55,7 +55,7 @@
card_view:layout_constraintTop_toTopOf="parent" card_view:layout_constraintTop_toTopOf="parent"
tools:text="Open Protocols!" /> tools:text="Open Protocols!" />
<android.support.v7.widget.AppCompatImageButton <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/chat_field__button_send" android:id="@+id/chat_field__button_send"
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="56dp" android:layout_height="56dp"
@ -65,8 +65,8 @@
app:srcCompat="@drawable/ic_send_black_24dp" app:srcCompat="@drawable/ic_send_black_24dp"
card_view:layout_constraintBottom_toBottomOf="parent" /> card_view:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@ -18,7 +18,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" <androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
@ -36,8 +36,8 @@
android:layout_margin="8dp" android:layout_margin="8dp"
tools:text="Hello World" /> tools:text="Hello World" />
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" <androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
@ -22,6 +22,6 @@
android:layout_margin="8dp" android:layout_margin="8dp"
tools:text="Hello World!Hello World!Hello World!Hello World!" /> tools:text="Hello World!Hello World!Hello World!Hello World!" />
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</android.support.constraint.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,6 +6,8 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit

View File

@ -36,7 +36,8 @@ ext {
// Other libraries // Other libraries
// Architecture Components // Architecture Components
archCompVersion = "1.1.1" lifecycleVersion = "2.0.0"
roomVersion = "2.1.0-beta01"
// Dagger 2 // Dagger 2
daggerVersion = "2.17" daggerVersion = "2.17"