Add caching, profile editing and call testing feature
parent
a9d1051aa8
commit
997b43f2e2
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,4 +1,5 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'realm-android'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 24
|
compileSdkVersion 24
|
||||||
|
@ -40,5 +41,6 @@ dependencies {
|
||||||
compile 'io.reactivex:rxjava:1.2.0'
|
compile 'io.reactivex:rxjava:1.2.0'
|
||||||
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
|
compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
|
||||||
compile 'com.squareup.picasso:picasso:2.5.2'
|
compile 'com.squareup.picasso:picasso:2.5.2'
|
||||||
|
compile 'com.android.support:support-v4:24.2.1'
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,14 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.smarthomies.realtimetalk">
|
package="com.smarthomies.realtimetalk">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.RECORD_AUDIO"/>
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".RTTApp"
|
android:name=".RTTApp"
|
||||||
|
@ -15,24 +22,39 @@
|
||||||
android:name=".views.activities.LoginActivity"
|
android:name=".views.activities.LoginActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme.NoActionBar"
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
android:windowSoftInputMode="adjustPan">
|
android:windowSoftInputMode="adjustPan"/>
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.SearchActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:parentActivityName=".views.activities.MainActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.ProfileActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:parentActivityName=".views.activities.MainActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.RegistrationActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.CallActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".views.activities.SplashScreenActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".views.activities.MainActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar"/>
|
|
||||||
<activity
|
|
||||||
android:name=".views.activities.SearchActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar"
|
|
||||||
android:parentActivityName=".views.activities.MainActivity"/>
|
|
||||||
<activity android:name=".views.activities.RegistrationActivity"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar"/>
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -4,6 +4,8 @@ import android.app.Application;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 31/10/16.
|
* Created by ensar on 31/10/16.
|
||||||
*/
|
*/
|
||||||
|
@ -15,5 +17,7 @@ public class RTTApp extends Application {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
RTTAppHelper.getInstance().initWithContext(getApplicationContext());
|
RTTAppHelper.getInstance().initWithContext(getApplicationContext());
|
||||||
|
|
||||||
|
Realm.init(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.smarthomies.realtimetalk.database;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
|
import io.realm.RealmObject;
|
||||||
|
import io.realm.RealmResults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 12/12/16.
|
||||||
|
*/
|
||||||
|
public class RealmDAO<T extends RealmObject> {
|
||||||
|
public static final String TAG = RealmDAO.class.getSimpleName();
|
||||||
|
|
||||||
|
protected Class<T> entityClass;
|
||||||
|
|
||||||
|
public RealmDAO(Class<T> entityClass) {
|
||||||
|
this.entityClass = entityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> load(Realm realm) {
|
||||||
|
RealmResults result = realm.where(entityClass).findAll();
|
||||||
|
return realm.copyFromRealm(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanSave(Realm realm, List objects) {
|
||||||
|
deleteAll(realm);
|
||||||
|
|
||||||
|
realm.beginTransaction();
|
||||||
|
for (Object realmObject : objects) {
|
||||||
|
realm.copyToRealm((RealmObject) realmObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(Realm realm, List objects) {
|
||||||
|
|
||||||
|
realm.beginTransaction();
|
||||||
|
|
||||||
|
for (Object realmObject : objects) {
|
||||||
|
realm.copyToRealm((RealmObject) realmObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateOrCreate(Realm realm, T object) {
|
||||||
|
realm.beginTransaction();
|
||||||
|
realm.copyToRealmOrUpdate(object);
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateOrCreate(Realm realm, List<? extends RealmObject> objects, boolean deleteIfMissing) {
|
||||||
|
if(objects.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Class clazz = objects.get(0).getClass();
|
||||||
|
realm.beginTransaction();
|
||||||
|
List liveObjects = realm.copyToRealmOrUpdate(objects);
|
||||||
|
|
||||||
|
// If true, all objects in DB which are not updated or added will be deleted
|
||||||
|
if(deleteIfMissing) {
|
||||||
|
RealmResults allDbObjects = realm.where(entityClass).findAll();
|
||||||
|
for(int i=0; i<allDbObjects.size(); i++) {
|
||||||
|
if(!liveObjects.contains(allDbObjects.get(i))) {
|
||||||
|
allDbObjects.deleteFromRealm(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAll(Realm realm) {
|
||||||
|
realm.beginTransaction();
|
||||||
|
realm.where(entityClass).findAll().deleteAllFromRealm();
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.smarthomies.realtimetalk.database;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 12/12/16.
|
||||||
|
*/
|
||||||
|
public class UserDAO extends RealmDAO<User> {
|
||||||
|
public static final String TAG = UserDAO.class.getSimpleName();
|
||||||
|
|
||||||
|
public UserDAO() {
|
||||||
|
super(User.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User findUserById(Realm realm, int id) {
|
||||||
|
return realm.where(entityClass).equalTo(User.PRIMARY_KEY, id).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(Realm realm, int id) {
|
||||||
|
realm.beginTransaction();
|
||||||
|
realm.where(entityClass).equalTo(User.PRIMARY_KEY, id).findFirst().deleteFromRealm();
|
||||||
|
realm.commitTransaction();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.smarthomies.realtimetalk.managers;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.database.UserDAO;
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.PasswordChangeRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UserResponse;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
|
import com.smarthomies.realtimetalk.services.AccountAPIService;
|
||||||
|
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.functions.Action1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 01/11/16.
|
||||||
|
*/
|
||||||
|
public class AccountManager {
|
||||||
|
public static final String TAG = AccountManager.class.getSimpleName();
|
||||||
|
|
||||||
|
public Observable<UserResponse> getProfile() {
|
||||||
|
return Observable.just(getUserFromDb()).concatWith(AccountAPIService.getInstance().getProfile()
|
||||||
|
.doOnNext(saveProfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> updateProfile(User newProfile) {
|
||||||
|
return AccountAPIService.getInstance().updateProfile(getUpdateRequest(newProfile))
|
||||||
|
.doOnNext(new UpdateProfileDb(newProfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> changePassword(String oldPassword, String newPassword) {
|
||||||
|
return AccountAPIService.getInstance().changePassword(getPasswordChangeRequest(oldPassword, newPassword));
|
||||||
|
}
|
||||||
|
|
||||||
|
private PasswordChangeRequest getPasswordChangeRequest(String oldPassword, String newPassword) {
|
||||||
|
PasswordChangeRequest passwordChangeRequest = new PasswordChangeRequest();
|
||||||
|
passwordChangeRequest.setCurrentPassword(oldPassword);
|
||||||
|
passwordChangeRequest.setNewPassword(newPassword);
|
||||||
|
return passwordChangeRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegistrationRequest getUpdateRequest(User user) {
|
||||||
|
RegistrationRequest registrationRequest = new RegistrationRequest();
|
||||||
|
registrationRequest.setEmail(user.getEmail());
|
||||||
|
registrationRequest.setFirstName(user.getFirstName());
|
||||||
|
registrationRequest.setLastName(user.getLastName());
|
||||||
|
return registrationRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action1<UserResponse> saveProfile = new Action1<UserResponse>() {
|
||||||
|
@Override
|
||||||
|
public void call(UserResponse userResponse) {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
new UserDAO().updateOrCreate(realm, userResponse.getData());
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private UserResponse getUserFromDb() {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
UserResponse userResponse = new UserResponse();
|
||||||
|
userResponse.setData(new UserDAO().findUserById(realm, RTTAppHelper.getInstance().getUserId()));
|
||||||
|
return userResponse;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UpdateProfileDb implements Action1<Object> {
|
||||||
|
private User contact;
|
||||||
|
|
||||||
|
public UpdateProfileDb(User contact) {
|
||||||
|
this.contact = contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(Object o) {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
new UserDAO().updateOrCreate(realm, contact);
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import com.smarthomies.realtimetalk.services.AuthenticationAPIService;
|
||||||
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
||||||
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
import rx.functions.Action0;
|
||||||
import rx.functions.Action1;
|
import rx.functions.Action1;
|
||||||
import rx.functions.Func1;
|
import rx.functions.Func1;
|
||||||
|
|
||||||
|
@ -18,7 +19,8 @@ public class AuthenticationManager {
|
||||||
public static final String TAG = AuthenticationManager.class.getSimpleName();
|
public static final String TAG = AuthenticationManager.class.getSimpleName();
|
||||||
|
|
||||||
public Observable<AuthenticationResponse> loginUser(String username, String password) {
|
public Observable<AuthenticationResponse> loginUser(String username, String password) {
|
||||||
return AuthenticationAPIService.getInstance().login(getLoginRequest(username, password)).doOnNext(processAuthenticationResponse);
|
return AuthenticationAPIService.getInstance().login(getLoginRequest(username, password))
|
||||||
|
.doOnNext(processAuthenticationResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<AuthenticationResponse> registerUser(User user, final String username, final String password) {
|
public Observable<AuthenticationResponse> registerUser(User user, final String username, final String password) {
|
||||||
|
@ -30,7 +32,14 @@ public class AuthenticationManager {
|
||||||
return Observable.just(getLoginRequest(username, password));
|
return Observable.just(getLoginRequest(username, password));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatMap(requestLogin).doOnNext(processAuthenticationResponse);
|
.flatMap(requestLogin)
|
||||||
|
.doOnNext(processAuthenticationResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> logout() {
|
||||||
|
return AuthenticationAPIService.getInstance().logout()
|
||||||
|
.doOnNext(processLogoutResponse)
|
||||||
|
.doOnError(processLogoutFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Func1<LoginRequest, Observable<AuthenticationResponse>> requestLogin = new Func1<LoginRequest, Observable<AuthenticationResponse>>() {
|
private Func1<LoginRequest, Observable<AuthenticationResponse>> requestLogin = new Func1<LoginRequest, Observable<AuthenticationResponse>>() {
|
||||||
|
@ -44,9 +53,29 @@ public class AuthenticationManager {
|
||||||
@Override
|
@Override
|
||||||
public void call(AuthenticationResponse authenticationResponse) {
|
public void call(AuthenticationResponse authenticationResponse) {
|
||||||
RTTAppHelper.getInstance().saveToken(authenticationResponse.getToken());
|
RTTAppHelper.getInstance().saveToken(authenticationResponse.getToken());
|
||||||
|
RTTAppHelper.getInstance().saveUserId(authenticationResponse.getId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private Action1<Object> processLogoutResponse = new Action1<Object>() {
|
||||||
|
@Override
|
||||||
|
public void call(Object object) {
|
||||||
|
clearToken();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Action1<Throwable> processLogoutFailure = new Action1<Throwable>() {
|
||||||
|
@Override
|
||||||
|
public void call(Throwable object) {
|
||||||
|
clearToken();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void clearToken() {
|
||||||
|
RTTAppHelper.getInstance().saveToken("");
|
||||||
|
RTTAppHelper.getInstance().saveUserId(-1);
|
||||||
|
}
|
||||||
|
|
||||||
private RegistrationRequest getRegistrationRequest(User user, String username, String password) {
|
private RegistrationRequest getRegistrationRequest(User user, String username, String password) {
|
||||||
RegistrationRequest registrationRequest = new RegistrationRequest();
|
RegistrationRequest registrationRequest = new RegistrationRequest();
|
||||||
registrationRequest.setUsername(username);
|
registrationRequest.setUsername(username);
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
package com.smarthomies.realtimetalk.managers;
|
package com.smarthomies.realtimetalk.managers;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.database.UserDAO;
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.ContactRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
import com.smarthomies.realtimetalk.services.ContactsAPIService;
|
import com.smarthomies.realtimetalk.services.ContactsAPIService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.Realm;
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
import rx.functions.Action1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 01/11/16.
|
* Created by ensar on 01/11/16.
|
||||||
|
@ -16,9 +25,91 @@ public class ContactsManager {
|
||||||
return ContactsAPIService.getInstance().search(getSearchRequest(searchString));
|
return ContactsAPIService.getInstance().search(getSearchRequest(searchString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Observable<UsersResponse> getContacts() {
|
||||||
|
return Observable.just(getUsersFromDb()).concatWith(ContactsAPIService.getInstance().getContacts()
|
||||||
|
.doOnNext(saveContacts));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> saveContact(User contact) {
|
||||||
|
return ContactsAPIService.getInstance().saveContact(getContactRequest(contact))
|
||||||
|
.doOnNext(new UpdateContactDb(contact, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> deleteContact(User contact) {
|
||||||
|
return ContactsAPIService.getInstance().deleteContact(getContactRequest(contact))
|
||||||
|
.doOnNext(new UpdateContactDb(contact, false));
|
||||||
|
}
|
||||||
|
|
||||||
private SearchRequest getSearchRequest(String searchString) {
|
private SearchRequest getSearchRequest(String searchString) {
|
||||||
SearchRequest searchRequest = new SearchRequest();
|
SearchRequest searchRequest = new SearchRequest();
|
||||||
searchRequest.setSearch(searchString);
|
searchRequest.setSearch(searchString);
|
||||||
return searchRequest;
|
return searchRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ContactRequest getContactRequest(User user) {
|
||||||
|
ContactRequest contactRequest = new ContactRequest();
|
||||||
|
contactRequest.setUsername(user.getUsername());
|
||||||
|
return contactRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsersResponse getUsersFromDb() {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
UsersResponse usersResponse = new UsersResponse();
|
||||||
|
usersResponse.setData(new UserDAO().load(realm));
|
||||||
|
return usersResponse;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action1<UsersResponse> saveContacts = new Action1<UsersResponse>() {
|
||||||
|
@Override
|
||||||
|
public void call(UsersResponse usersResponse) {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
new UserDAO().updateOrCreate(realm, usersResponse.getData(), true);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private class UpdateContactDb implements Action1<Object> {
|
||||||
|
private User contact;
|
||||||
|
private boolean add;
|
||||||
|
|
||||||
|
public UpdateContactDb(User contact, boolean add) {
|
||||||
|
this.contact = contact;
|
||||||
|
this.add = add;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void call(Object o) {
|
||||||
|
Realm realm = null;
|
||||||
|
try {
|
||||||
|
realm = Realm.getDefaultInstance();
|
||||||
|
if(add) {
|
||||||
|
new UserDAO().updateOrCreate(realm, contact);
|
||||||
|
} else {
|
||||||
|
new UserDAO().deleteById(realm, contact.getId());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if(realm != null) {
|
||||||
|
realm.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,19 @@ package com.smarthomies.realtimetalk.models.db;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import io.realm.RealmObject;
|
||||||
|
import io.realm.annotations.PrimaryKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 01/11/16.
|
* Created by ensar on 01/11/16.
|
||||||
*/
|
*/
|
||||||
public class User{
|
public class User extends RealmObject{
|
||||||
public static final String TAG = User.class.getSimpleName();
|
public static final String TAG = User.class.getSimpleName();
|
||||||
|
|
||||||
|
public static final String PRIMARY_KEY = "username";
|
||||||
|
|
||||||
|
@PrimaryKey
|
||||||
|
private int id;
|
||||||
@SerializedName("first_name")
|
@SerializedName("first_name")
|
||||||
private String firstName;
|
private String firstName;
|
||||||
@SerializedName("last_name")
|
@SerializedName("last_name")
|
||||||
|
@ -16,6 +23,15 @@ public class User{
|
||||||
private String email;
|
private String email;
|
||||||
@SerializedName("profile_picture")
|
@SerializedName("profile_picture")
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
return firstName;
|
return firstName;
|
||||||
|
@ -48,4 +64,12 @@ public class User{
|
||||||
public void setImageUrl(String imageUrl) {
|
public void setImageUrl(String imageUrl) {
|
||||||
this.imageUrl = imageUrl;
|
this.imageUrl = imageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ public class AuthenticationResponse {
|
||||||
public static final String TAG = AuthenticationResponse.class.getSimpleName();
|
public static final String TAG = AuthenticationResponse.class.getSimpleName();
|
||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
|
private int id;
|
||||||
|
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
return token;
|
return token;
|
||||||
|
@ -15,4 +16,12 @@ public class AuthenticationResponse {
|
||||||
public void setToken(String token) {
|
public void setToken(String token) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.smarthomies.realtimetalk.models.network;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 11/12/16.
|
||||||
|
*/
|
||||||
|
public class ContactRequest {
|
||||||
|
public static final String TAG = ContactRequest.class.getSimpleName();
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.smarthomies.realtimetalk.models.network;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 31/10/16.
|
||||||
|
*/
|
||||||
|
public class PasswordChangeRequest {
|
||||||
|
public static final String TAG = PasswordChangeRequest.class.getSimpleName();
|
||||||
|
|
||||||
|
@SerializedName("current_password")
|
||||||
|
private String currentPassword;
|
||||||
|
@SerializedName("new_password")
|
||||||
|
private String newPassword;
|
||||||
|
|
||||||
|
public String getCurrentPassword() {
|
||||||
|
return currentPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPassword(String currentPassword) {
|
||||||
|
this.currentPassword = currentPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewPassword() {
|
||||||
|
return newPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewPassword(String newPassword) {
|
||||||
|
this.newPassword = newPassword;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package com.smarthomies.realtimetalk.models.network;
|
package com.smarthomies.realtimetalk.models.network;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 31/10/16.
|
* Created by ensar on 31/10/16.
|
||||||
*/
|
*/
|
||||||
|
@ -9,7 +11,9 @@ public class RegistrationRequest {
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private String email;
|
private String email;
|
||||||
|
@SerializedName("first_name")
|
||||||
private String firstName;
|
private String firstName;
|
||||||
|
@SerializedName("last_name")
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.smarthomies.realtimetalk.models.network;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 06/12/16.
|
||||||
|
*/
|
||||||
|
public class UserResponse {
|
||||||
|
public static final String TAG = UserResponse.class.getSimpleName();
|
||||||
|
|
||||||
|
private User data;
|
||||||
|
|
||||||
|
public User getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(User data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
package com.smarthomies.realtimetalk.network;
|
package com.smarthomies.realtimetalk.network;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.network.exceptions.APIConflictException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.BadAPIRequestException;
|
import com.smarthomies.realtimetalk.network.exceptions.BadAPIRequestException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.NetworkException;
|
import com.smarthomies.realtimetalk.network.exceptions.NetworkException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.RemoteResourceNotFoundException;
|
import com.smarthomies.realtimetalk.network.exceptions.RemoteResourceNotFoundException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.ResourceForbiddenException;
|
import com.smarthomies.realtimetalk.network.exceptions.ResourceForbiddenException;
|
||||||
|
import com.smarthomies.realtimetalk.network.exceptions.ServerErrorException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.UnauthorizedException;
|
import com.smarthomies.realtimetalk.network.exceptions.UnauthorizedException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -31,25 +33,16 @@ public class APIErrorHandler {
|
||||||
throw new ResourceForbiddenException(throwable);
|
throw new ResourceForbiddenException(throwable);
|
||||||
case HttpURLConnection.HTTP_UNAUTHORIZED:
|
case HttpURLConnection.HTTP_UNAUTHORIZED:
|
||||||
throw new UnauthorizedException(throwable);
|
throw new UnauthorizedException(throwable);
|
||||||
|
case HttpURLConnection.HTTP_CONFLICT:
|
||||||
|
throw new APIConflictException(throwable);
|
||||||
|
case HttpURLConnection.HTTP_UNAVAILABLE:
|
||||||
|
case HttpURLConnection.HTTP_INTERNAL_ERROR:
|
||||||
|
throw new ServerErrorException(throwable);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(throwable instanceof IOException) {
|
if(throwable instanceof IOException) {
|
||||||
throw new NetworkException(throwable);
|
throw new NetworkException(throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void handleLoginErrors(Throwable throwable)
|
|
||||||
throws APIException {
|
|
||||||
handleGeneralAPIErrors(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handleRegistrationErrors(Throwable throwable)
|
|
||||||
throws APIException {
|
|
||||||
handleGeneralAPIErrors(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handleSearchErrors(Throwable throwable)
|
|
||||||
throws APIException {
|
|
||||||
handleGeneralAPIErrors(throwable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.smarthomies.realtimetalk.network;
|
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
|
||||||
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
|
||||||
|
|
||||||
import retrofit2.http.Body;
|
|
||||||
import retrofit2.http.GET;
|
|
||||||
import retrofit2.http.POST;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by ensar on 15/11/16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface ContactsAPI {
|
|
||||||
|
|
||||||
@POST(NetworkingConstants.API_SEARCH_ENDPOINT)
|
|
||||||
Observable<UsersResponse> searchUsers(@Body SearchRequest searchRequest);
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,8 +7,14 @@ public class NetworkingConstants {
|
||||||
public static final String TAG = NetworkingConstants.class.getSimpleName();
|
public static final String TAG = NetworkingConstants.class.getSimpleName();
|
||||||
|
|
||||||
public static final String API_BASE_URL = "https://realtimetalk.herokuapp.com/rest/";
|
public static final String API_BASE_URL = "https://realtimetalk.herokuapp.com/rest/";
|
||||||
|
|
||||||
public static final String API_LOGIN_ENDPOINT = "prijava";
|
public static final String API_LOGIN_ENDPOINT = "prijava";
|
||||||
|
public static final String API_LOGOUT_ENDPOINT = "odjava";
|
||||||
public static final String API_REGISTRATION_ENDPOINT = "dodaj";
|
public static final String API_REGISTRATION_ENDPOINT = "dodaj";
|
||||||
public static final String API_CONTACTS_ENDPOINT = "contacts";
|
public static final String API_CONTACTS_ENDPOINT = "contacts";
|
||||||
|
public static final String API_PROFILE_ENDPOINT = "profile";
|
||||||
|
public static final String API_PASSWORD_UPDATE_ENDPOINT = API_PROFILE_ENDPOINT + "/password";
|
||||||
public static final String API_SEARCH_ENDPOINT = "search";
|
public static final String API_SEARCH_ENDPOINT = "search";
|
||||||
|
|
||||||
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.smarthomies.realtimetalk.network.apis;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.network.ContactRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.PasswordChangeRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UserResponse;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
|
import com.smarthomies.realtimetalk.network.NetworkingConstants;
|
||||||
|
|
||||||
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.DELETE;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
import retrofit2.http.PUT;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 15/11/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface AccountAPI {
|
||||||
|
|
||||||
|
@GET(NetworkingConstants.API_PROFILE_ENDPOINT)
|
||||||
|
Observable<UserResponse> getProfile();
|
||||||
|
|
||||||
|
@PUT(NetworkingConstants.API_PROFILE_ENDPOINT)
|
||||||
|
Observable<Object> updateProfile(@Body RegistrationRequest request);
|
||||||
|
|
||||||
|
@PUT(NetworkingConstants.API_PASSWORD_UPDATE_ENDPOINT)
|
||||||
|
Observable<Object> changePassword(@Body PasswordChangeRequest request);
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
package com.smarthomies.realtimetalk.network;
|
package com.smarthomies.realtimetalk.network.apis;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
||||||
import com.smarthomies.realtimetalk.models.network.LoginRequest;
|
import com.smarthomies.realtimetalk.models.network.LoginRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
||||||
|
import com.smarthomies.realtimetalk.network.NetworkingConstants;
|
||||||
|
|
||||||
import retrofit2.http.Body;
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.DELETE;
|
||||||
import retrofit2.http.POST;
|
import retrofit2.http.POST;
|
||||||
import retrofit2.http.PUT;
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +19,10 @@ public interface AuthenticationAPI {
|
||||||
@POST(NetworkingConstants.API_LOGIN_ENDPOINT)
|
@POST(NetworkingConstants.API_LOGIN_ENDPOINT)
|
||||||
Observable<AuthenticationResponse> login(@Body LoginRequest request);
|
Observable<AuthenticationResponse> login(@Body LoginRequest request);
|
||||||
|
|
||||||
@PUT(NetworkingConstants.API_REGISTRATION_ENDPOINT)
|
@POST(NetworkingConstants.API_REGISTRATION_ENDPOINT)
|
||||||
Observable<AuthenticationResponse> register(@Body RegistrationRequest request);
|
Observable<AuthenticationResponse> register(@Body RegistrationRequest request);
|
||||||
|
|
||||||
|
@DELETE(NetworkingConstants.API_LOGOUT_ENDPOINT)
|
||||||
|
Observable<Object> logout();
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.smarthomies.realtimetalk.network.apis;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.network.ContactRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
|
import com.smarthomies.realtimetalk.network.NetworkingConstants;
|
||||||
|
|
||||||
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.DELETE;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 15/11/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ContactsAPI {
|
||||||
|
|
||||||
|
@POST(NetworkingConstants.API_SEARCH_ENDPOINT)
|
||||||
|
Observable<UsersResponse> searchUsers(@Body SearchRequest searchRequest);
|
||||||
|
|
||||||
|
@GET(NetworkingConstants.API_CONTACTS_ENDPOINT)
|
||||||
|
Observable<UsersResponse> getContacts();
|
||||||
|
|
||||||
|
@POST(NetworkingConstants.API_CONTACTS_ENDPOINT)
|
||||||
|
Observable<Object> saveContact(@Body ContactRequest contactRequest);
|
||||||
|
|
||||||
|
@DELETE(NetworkingConstants.API_CONTACTS_ENDPOINT)
|
||||||
|
Observable<Object> deleteContact(@Body ContactRequest contactRequest);
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,10 @@
|
||||||
package com.smarthomies.realtimetalk.network;
|
package com.smarthomies.realtimetalk.network.clients;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.network.NetworkingConstants;
|
||||||
|
import com.smarthomies.realtimetalk.network.apis.AccountAPI;
|
||||||
|
import com.smarthomies.realtimetalk.network.apis.AuthenticationAPI;
|
||||||
|
import com.smarthomies.realtimetalk.network.apis.ContactsAPI;
|
||||||
|
import com.smarthomies.realtimetalk.network.interceptors.AuthorizationInterceptor;
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.logging.HttpLoggingInterceptor;
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
|
@ -17,6 +23,7 @@ public class RestClient {
|
||||||
private Retrofit retrofit;
|
private Retrofit retrofit;
|
||||||
private AuthenticationAPI authenticationAPI;
|
private AuthenticationAPI authenticationAPI;
|
||||||
private ContactsAPI contactsAPI;
|
private ContactsAPI contactsAPI;
|
||||||
|
private AccountAPI accountAPI;
|
||||||
|
|
||||||
private RestClient() {
|
private RestClient() {
|
||||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||||
|
@ -25,6 +32,7 @@ public class RestClient {
|
||||||
|
|
||||||
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
|
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
|
||||||
// add your other interceptors …
|
// add your other interceptors …
|
||||||
|
httpClient.addInterceptor(new AuthorizationInterceptor());
|
||||||
|
|
||||||
// add logging as last interceptor
|
// add logging as last interceptor
|
||||||
httpClient.addInterceptor(logging); // <-- this is the important line!
|
httpClient.addInterceptor(logging); // <-- this is the important line!
|
||||||
|
@ -57,4 +65,11 @@ public class RestClient {
|
||||||
}
|
}
|
||||||
return contactsAPI;
|
return contactsAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AccountAPI getAccountAPI() {
|
||||||
|
if(accountAPI == null) {
|
||||||
|
accountAPI = retrofit.create(AccountAPI.class);
|
||||||
|
}
|
||||||
|
return accountAPI;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.smarthomies.realtimetalk.network.exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 01/11/16.
|
||||||
|
*/
|
||||||
|
public class APIConflictException extends APIException {
|
||||||
|
public static final String TAG = APIConflictException.class.getSimpleName();
|
||||||
|
|
||||||
|
public APIConflictException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public APIConflictException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.smarthomies.realtimetalk.network.exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 01/11/16.
|
||||||
|
*/
|
||||||
|
public class ServerErrorException extends APIException {
|
||||||
|
public static final String TAG = ServerErrorException.class.getSimpleName();
|
||||||
|
|
||||||
|
public ServerErrorException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerErrorException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.smarthomies.realtimetalk.network.interceptors;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.network.NetworkingConstants;
|
||||||
|
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 11/12/16.
|
||||||
|
*/
|
||||||
|
public class AuthorizationInterceptor implements Interceptor {
|
||||||
|
public static final String TAG = AuthorizationInterceptor.class.getSimpleName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Request request = chain
|
||||||
|
.request()
|
||||||
|
.newBuilder()
|
||||||
|
.addHeader(NetworkingConstants.AUTHORIZATION_HEADER, RTTAppHelper.getInstance().getToken()).build();
|
||||||
|
return chain.proceed(request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.smarthomies.realtimetalk.services;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.network.PasswordChangeRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UserResponse;
|
||||||
|
import com.smarthomies.realtimetalk.network.APIErrorHandler;
|
||||||
|
import com.smarthomies.realtimetalk.network.clients.RestClient;
|
||||||
|
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
||||||
|
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.exceptions.Exceptions;
|
||||||
|
import rx.functions.Action1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 31/10/16.
|
||||||
|
*/
|
||||||
|
public class AccountAPIService {
|
||||||
|
public static final String TAG = AccountAPIService.class.getSimpleName();
|
||||||
|
|
||||||
|
private static AccountAPIService instance;
|
||||||
|
|
||||||
|
private AccountAPIService() {}
|
||||||
|
|
||||||
|
public static AccountAPIService getInstance() {
|
||||||
|
if(instance == null) {
|
||||||
|
instance = new AccountAPIService();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<UserResponse> getProfile() {
|
||||||
|
return RestClient.getInstance().getAccountAPI().getProfile()
|
||||||
|
.doOnError(handleGeneralErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> updateProfile(RegistrationRequest request) {
|
||||||
|
return RestClient.getInstance().getAccountAPI().updateProfile(request)
|
||||||
|
.doOnError(handleGeneralErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> changePassword(PasswordChangeRequest request) {
|
||||||
|
return RestClient.getInstance().getAccountAPI().changePassword(request)
|
||||||
|
.doOnError(handleGeneralErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action1<Throwable> handleGeneralErrors = new Action1<Throwable>() {
|
||||||
|
@Override
|
||||||
|
public void call(Throwable throwable) {
|
||||||
|
try {
|
||||||
|
APIErrorHandler.handleGeneralAPIErrors(throwable);
|
||||||
|
} catch (APIException apiException) {
|
||||||
|
throw Exceptions.propagate(apiException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
||||||
import com.smarthomies.realtimetalk.models.network.LoginRequest;
|
import com.smarthomies.realtimetalk.models.network.LoginRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
import com.smarthomies.realtimetalk.models.network.RegistrationRequest;
|
||||||
import com.smarthomies.realtimetalk.network.APIErrorHandler;
|
import com.smarthomies.realtimetalk.network.APIErrorHandler;
|
||||||
import com.smarthomies.realtimetalk.network.RestClient;
|
import com.smarthomies.realtimetalk.network.clients.RestClient;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
||||||
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
@ -30,30 +30,24 @@ public class AuthenticationAPIService {
|
||||||
|
|
||||||
public Observable<AuthenticationResponse> login(LoginRequest request) {
|
public Observable<AuthenticationResponse> login(LoginRequest request) {
|
||||||
return RestClient.getInstance().getAuthenticationAPI().login(request)
|
return RestClient.getInstance().getAuthenticationAPI().login(request)
|
||||||
.doOnError(handleLoginErrors);
|
.doOnError(handleGeneralErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<AuthenticationResponse> register(RegistrationRequest request) {
|
public Observable<AuthenticationResponse> register(RegistrationRequest request) {
|
||||||
return RestClient.getInstance().getAuthenticationAPI().register(request)
|
return RestClient.getInstance().getAuthenticationAPI().register(request)
|
||||||
.doOnError(handleRegistrationErrors);
|
.doOnError(handleGeneralErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action1<Throwable> handleLoginErrors = new Action1<Throwable>() {
|
public Observable<Object> logout() {
|
||||||
@Override
|
return RestClient.getInstance().getAuthenticationAPI().logout()
|
||||||
public void call(Throwable throwable) {
|
.doOnError(handleGeneralErrors);
|
||||||
try {
|
}
|
||||||
APIErrorHandler.handleLoginErrors(throwable);
|
|
||||||
} catch (APIException apiException) {
|
|
||||||
throw Exceptions.propagate(apiException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private Action1<Throwable> handleRegistrationErrors = new Action1<Throwable>() {
|
private Action1<Throwable> handleGeneralErrors = new Action1<Throwable>() {
|
||||||
@Override
|
@Override
|
||||||
public void call(Throwable throwable) {
|
public void call(Throwable throwable) {
|
||||||
try {
|
try {
|
||||||
APIErrorHandler.handleRegistrationErrors(throwable);
|
APIErrorHandler.handleGeneralAPIErrors(throwable);
|
||||||
} catch (APIException apiException) {
|
} catch (APIException apiException) {
|
||||||
throw Exceptions.propagate(apiException);
|
throw Exceptions.propagate(apiException);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package com.smarthomies.realtimetalk.services;
|
package com.smarthomies.realtimetalk.services;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.models.network.ContactRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
import com.smarthomies.realtimetalk.models.network.SearchRequest;
|
||||||
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
import com.smarthomies.realtimetalk.network.APIErrorHandler;
|
import com.smarthomies.realtimetalk.network.APIErrorHandler;
|
||||||
import com.smarthomies.realtimetalk.network.RestClient;
|
import com.smarthomies.realtimetalk.network.clients.RestClient;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
import com.smarthomies.realtimetalk.network.exceptions.APIException;
|
||||||
|
|
||||||
import rx.Observable;
|
import rx.Observable;
|
||||||
|
@ -29,14 +30,29 @@ public class ContactsAPIService {
|
||||||
|
|
||||||
public Observable<UsersResponse> search(SearchRequest request) {
|
public Observable<UsersResponse> search(SearchRequest request) {
|
||||||
return RestClient.getInstance().getContactsAPI().searchUsers(request)
|
return RestClient.getInstance().getContactsAPI().searchUsers(request)
|
||||||
.doOnError(handleSearchErrors);
|
.doOnError(handleApiErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action1<Throwable> handleSearchErrors = new Action1<Throwable>() {
|
public Observable<UsersResponse> getContacts() {
|
||||||
|
return RestClient.getInstance().getContactsAPI().getContacts()
|
||||||
|
.doOnError(handleApiErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> saveContact(ContactRequest request) {
|
||||||
|
return RestClient.getInstance().getContactsAPI().saveContact(request)
|
||||||
|
.doOnError(handleApiErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Object> deleteContact(ContactRequest request) {
|
||||||
|
return RestClient.getInstance().getContactsAPI().deleteContact(request)
|
||||||
|
.doOnError(handleApiErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Action1<Throwable> handleApiErrors = new Action1<Throwable>() {
|
||||||
@Override
|
@Override
|
||||||
public void call(Throwable throwable) {
|
public void call(Throwable throwable) {
|
||||||
try {
|
try {
|
||||||
APIErrorHandler.handleSearchErrors(throwable);
|
APIErrorHandler.handleGeneralAPIErrors(throwable);
|
||||||
} catch (APIException apiException) {
|
} catch (APIException apiException) {
|
||||||
throw Exceptions.propagate(apiException);
|
throw Exceptions.propagate(apiException);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.smarthomies.realtimetalk.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioRecord;
|
||||||
|
import android.media.MediaRecorder;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.CallActivity;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class MediaStreamClient {
|
||||||
|
|
||||||
|
boolean isRecording;
|
||||||
|
int recBufSize;
|
||||||
|
//ServerSocket sockfd;
|
||||||
|
Socket connfd;
|
||||||
|
AudioRecord audioRecord;
|
||||||
|
private static final String TAG = "MyActivity";
|
||||||
|
|
||||||
|
public MediaStreamClient(final Context ctx, final String ip) {
|
||||||
|
|
||||||
|
Properties prop = new Properties();
|
||||||
|
try {
|
||||||
|
InputStream inputStream = ctx.getResources().openRawResource(R.raw.config);
|
||||||
|
prop.load(inputStream);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("Can't finde config");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Can't load config");
|
||||||
|
}
|
||||||
|
|
||||||
|
final int frequency = Integer.parseInt(prop.getProperty("frequency"));
|
||||||
|
final int channelConfiguration = Integer.parseInt(prop.getProperty("channal_server"));
|
||||||
|
final int audioEncoding = Integer.parseInt(prop.getProperty("audio_encoding"));
|
||||||
|
final int SERVERPORT = Integer.parseInt(prop.getProperty("serverport_server"));
|
||||||
|
|
||||||
|
recBufSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
|
||||||
|
//Log.v(TAG,String.valueOf(AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO , AudioFormat.ENCODING_PCM_16BIT)));
|
||||||
|
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, recBufSize);
|
||||||
|
|
||||||
|
new Thread() {
|
||||||
|
byte[] buffer = new byte[recBufSize];
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try { connfd = new Socket(ip, SERVERPORT); }
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Can't connect!",ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
audioRecord.startRecording();
|
||||||
|
isRecording = true;
|
||||||
|
while (isRecording) {
|
||||||
|
|
||||||
|
int readSize = audioRecord.read(buffer, 0, recBufSize);
|
||||||
|
|
||||||
|
try { connfd.getOutputStream().write(buffer, 0, readSize);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Closed stream by revicer!",ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
audioRecord.stop();
|
||||||
|
//audioRecord.release();
|
||||||
|
try { connfd.close(); }
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Can't close connection!",ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void stop(Context ctx) {
|
||||||
|
isRecording = false;
|
||||||
|
/*try { connfd.close(); }
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
MainActivity.toast("Can't close connection!",ctx);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.smarthomies.realtimetalk.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.AudioTrack;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.CallActivity;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class MediaStreamServer implements Runnable {
|
||||||
|
|
||||||
|
boolean isPlaying;
|
||||||
|
int playBufSize;
|
||||||
|
Socket connfd;
|
||||||
|
ServerSocket sockfd;
|
||||||
|
AudioTrack audioTrack;
|
||||||
|
private static final String TAG = "MyActivity";
|
||||||
|
final int SERVERPORT;
|
||||||
|
Context ctx;
|
||||||
|
|
||||||
|
public MediaStreamServer(final Context ctx) {
|
||||||
|
|
||||||
|
Properties prop = new Properties();
|
||||||
|
try {
|
||||||
|
InputStream inputStream = ctx.getResources().openRawResource(R.raw.config);
|
||||||
|
prop.load(inputStream);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("Can't finde config");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Can't load config");
|
||||||
|
}
|
||||||
|
|
||||||
|
final int frequency = Integer.parseInt(prop.getProperty("frequency"));
|
||||||
|
final int channelConfiguration = Integer.parseInt(prop.getProperty("channal_client"));
|
||||||
|
final int audioEncoding = Integer.parseInt(prop.getProperty("audio_encoding"));
|
||||||
|
SERVERPORT = Integer.parseInt(prop.getProperty("serverport_client"));
|
||||||
|
|
||||||
|
|
||||||
|
playBufSize=AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
|
||||||
|
audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL, frequency, channelConfiguration, audioEncoding, playBufSize, AudioTrack.MODE_STREAM);
|
||||||
|
audioTrack.setStereoVolume(1f, 1f);
|
||||||
|
this.ctx=ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
isPlaying = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setVolume(float lvol, float rvol) {
|
||||||
|
audioTrack.setStereoVolume(lvol, rvol);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
byte[] buffer = new byte[playBufSize];
|
||||||
|
try { sockfd = new ServerSocket(SERVERPORT); }
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Port unavailable",ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
connfd = sockfd.accept();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Connection not accepted",ctx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CallActivity.toast("Connected",ctx);
|
||||||
|
audioTrack.play();
|
||||||
|
isPlaying = true;
|
||||||
|
while (isPlaying) {
|
||||||
|
int readSize = 0;
|
||||||
|
try {
|
||||||
|
readSize = connfd.getInputStream().read(buffer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.v(TAG, "palo");
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Closed stream by sender",ctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
audioTrack.write(buffer, 0, readSize);
|
||||||
|
}
|
||||||
|
audioTrack.stop();
|
||||||
|
audioTrack.flush();
|
||||||
|
try {
|
||||||
|
connfd.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
CallActivity.toast("Can't close connection!",ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ public class RTTAppHelper {
|
||||||
public static final String TAG = RTTAppHelper.class.getSimpleName();
|
public static final String TAG = RTTAppHelper.class.getSimpleName();
|
||||||
|
|
||||||
public static final String SHARED_PREFERENCES_USER_TOKEN = "SHARED_PREFERENCES_USER_TOKEN";
|
public static final String SHARED_PREFERENCES_USER_TOKEN = "SHARED_PREFERENCES_USER_TOKEN";
|
||||||
|
public static final String SHARED_PREFERENCES_USER_ID = "SHARED_PREFERENCES_USER_ID";
|
||||||
|
|
||||||
private static RTTAppHelper instance;
|
private static RTTAppHelper instance;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
@ -34,7 +35,21 @@ public class RTTAppHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
return readFromSharedPrefs(SHARED_PREFERENCES_USER_TOKEN);
|
return readFromSharedPrefs(SHARED_PREFERENCES_USER_TOKEN, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveUserId(int userId) {
|
||||||
|
writeToSharedPrefs(SHARED_PREFERENCES_USER_ID, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return readFromSharedPrefs(SHARED_PREFERENCES_USER_ID, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToSharedPrefs(String key, int value) {
|
||||||
|
SharedPreferences.Editor editor = context.getSharedPreferences(TAG, Context.MODE_PRIVATE).edit();
|
||||||
|
editor.putInt(key, value);
|
||||||
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToSharedPrefs(String key, String value) {
|
private void writeToSharedPrefs(String key, String value) {
|
||||||
|
@ -52,4 +67,9 @@ public class RTTAppHelper {
|
||||||
return sharedPreferences.getString(key, defaultValue);
|
return sharedPreferences.getString(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int readFromSharedPrefs(String key, int defaultValue) {
|
||||||
|
SharedPreferences sharedPreferences = context.getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||||
|
return sharedPreferences.getInt(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,12 @@ import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.R;
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.network.exceptions.APIConflictException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.BadAPIRequestException;
|
import com.smarthomies.realtimetalk.network.exceptions.BadAPIRequestException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.NetworkException;
|
import com.smarthomies.realtimetalk.network.exceptions.NetworkException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.RemoteResourceNotFoundException;
|
import com.smarthomies.realtimetalk.network.exceptions.RemoteResourceNotFoundException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.ResourceForbiddenException;
|
import com.smarthomies.realtimetalk.network.exceptions.ResourceForbiddenException;
|
||||||
|
import com.smarthomies.realtimetalk.network.exceptions.ServerErrorException;
|
||||||
import com.smarthomies.realtimetalk.network.exceptions.UnauthorizedException;
|
import com.smarthomies.realtimetalk.network.exceptions.UnauthorizedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,8 +27,12 @@ public class RTTErrorUtil {
|
||||||
return R.string.error_unknown;
|
return R.string.error_unknown;
|
||||||
} else if (e instanceof UnauthorizedException) {
|
} else if (e instanceof UnauthorizedException) {
|
||||||
return R.string.error_user_bad_credentials;
|
return R.string.error_user_bad_credentials;
|
||||||
|
} else if (e instanceof APIConflictException) {
|
||||||
|
return R.string.error_user_already_exists;
|
||||||
} else if (e instanceof NetworkException) {
|
} else if (e instanceof NetworkException) {
|
||||||
return R.string.error_no_internet;
|
return R.string.error_no_internet;
|
||||||
|
} else if (e instanceof ServerErrorException) {
|
||||||
|
return R.string.error_server;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,9 @@ public class LoginViewModel extends BaseObservable {
|
||||||
return new View.OnClickListener() {
|
return new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// if(validateFields()) {
|
if(validateFields()) {
|
||||||
// loginUser();
|
loginUser();
|
||||||
// }
|
}
|
||||||
onLoginDone();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -90,6 +89,7 @@ public class LoginViewModel extends BaseObservable {
|
||||||
|
|
||||||
public void onLoginDone() {
|
public void onLoginDone() {
|
||||||
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(MainActivity.class, null));
|
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(MainActivity.class, null));
|
||||||
|
NavigationSubject.getInstance().onNext(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRequestCompleted() {
|
public void onRequestCompleted() {
|
||||||
|
|
|
@ -2,35 +2,124 @@ package com.smarthomies.realtimetalk.viewmodels;
|
||||||
|
|
||||||
import android.databinding.BaseObservable;
|
import android.databinding.BaseObservable;
|
||||||
import android.databinding.Bindable;
|
import android.databinding.Bindable;
|
||||||
|
import android.databinding.ObservableField;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.RTTActivity;
|
import com.smarthomies.realtimetalk.RTTActivity;
|
||||||
|
import com.smarthomies.realtimetalk.managers.AccountManager;
|
||||||
|
import com.smarthomies.realtimetalk.managers.AuthenticationManager;
|
||||||
|
import com.smarthomies.realtimetalk.managers.ContactsManager;
|
||||||
import com.smarthomies.realtimetalk.models.db.User;
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UserResponse;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UsersResponse;
|
||||||
import com.smarthomies.realtimetalk.utils.NavigationSubject;
|
import com.smarthomies.realtimetalk.utils.NavigationSubject;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.LoginActivity;
|
||||||
import com.smarthomies.realtimetalk.views.activities.MainActivity;
|
import com.smarthomies.realtimetalk.views.activities.MainActivity;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.ProfileActivity;
|
||||||
import com.smarthomies.realtimetalk.views.activities.SearchActivity;
|
import com.smarthomies.realtimetalk.views.activities.SearchActivity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import rx.Observable;
|
||||||
|
import rx.Subscriber;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
import rx.subjects.AsyncSubject;
|
||||||
|
import rx.subscriptions.CompositeSubscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 15/11/16.
|
* Created by ensar on 15/11/16.
|
||||||
*/
|
*/
|
||||||
public class MainViewModel extends BaseObservable {
|
public class MainViewModel extends BaseObservable {
|
||||||
public static final String TAG = MainViewModel.class.getSimpleName();
|
public static final String TAG = MainViewModel.class.getSimpleName();
|
||||||
|
|
||||||
UserViewModel userViewModel;
|
private AsyncSubject<Object> logoutSubject;
|
||||||
|
|
||||||
public void setUser(User user) {
|
private CompositeSubscription subscription;
|
||||||
userViewModel = new UserViewModel(user);
|
|
||||||
|
private ObservableField<List<User>> contacts = new ObservableField<>();
|
||||||
|
|
||||||
|
private ObservableField<UserViewModel> userViewModel = new ObservableField<>();
|
||||||
|
|
||||||
|
public MainViewModel() {
|
||||||
|
logoutSubject = AsyncSubject.create();
|
||||||
|
subscription = new CompositeSubscription();
|
||||||
|
userViewModel.set(new UserViewModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadContacts() {
|
||||||
|
subscription.add(new ContactsManager().getContacts()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<UsersResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(UsersResponse usersResponse) {
|
||||||
|
contacts.set(usersResponse.getData());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadProfile() {
|
||||||
|
subscription.add(new AccountManager().getProfile()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<UserResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(UserResponse userResponse) {
|
||||||
|
userViewModel.get().setModel(userResponse.getData());
|
||||||
|
userViewModel.notifyChange();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncSubject<Object> createLogoutSubject() {
|
||||||
|
logoutSubject = AsyncSubject.create();
|
||||||
|
return logoutSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncSubject<Object> getLogoutSubject() {
|
||||||
|
return logoutSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logoutUser() {
|
||||||
|
new AuthenticationManager().logout().subscribeOn(Schedulers.io()).subscribe(logoutSubject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<List<User>> getContacts() {
|
||||||
|
return contacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContacts(ObservableField<List<User>> contacts) {
|
||||||
|
this.contacts = contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bindable
|
@Bindable
|
||||||
public UserViewModel getUserViewModel() {
|
public UserViewModel getUserViewModel() {
|
||||||
return userViewModel;
|
return userViewModel.get();
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserViewModel(UserViewModel userViewModel) {
|
|
||||||
this.userViewModel = userViewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public View.OnClickListener onSearchClick() {
|
public View.OnClickListener onSearchClick() {
|
||||||
|
@ -41,4 +130,22 @@ public class MainViewModel extends BaseObservable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onLogoutClick() {
|
||||||
|
logoutUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onProfileClick() {
|
||||||
|
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(ProfileActivity.class, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLogoutDone() {
|
||||||
|
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(LoginActivity.class, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if(subscription != null && !subscription.isUnsubscribed()) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
package com.smarthomies.realtimetalk.viewmodels;
|
||||||
|
|
||||||
|
import android.databinding.BaseObservable;
|
||||||
|
import android.databinding.ObservableBoolean;
|
||||||
|
import android.databinding.ObservableField;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.RTTActivity;
|
||||||
|
import com.smarthomies.realtimetalk.RTTFragment;
|
||||||
|
import com.smarthomies.realtimetalk.managers.AccountManager;
|
||||||
|
import com.smarthomies.realtimetalk.managers.AuthenticationManager;
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
||||||
|
import com.smarthomies.realtimetalk.models.network.UserResponse;
|
||||||
|
import com.smarthomies.realtimetalk.utils.NavigationSubject;
|
||||||
|
import com.smarthomies.realtimetalk.utils.RTTUtil;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.MainActivity;
|
||||||
|
import com.smarthomies.realtimetalk.views.fragments.registration.PasswordRegistrationFragment;
|
||||||
|
import com.smarthomies.realtimetalk.views.fragments.registration.UserNameRegistrationFragment;
|
||||||
|
|
||||||
|
import rx.Subscriber;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
import rx.subjects.AsyncSubject;
|
||||||
|
import rx.subscriptions.CompositeSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 01/11/16.
|
||||||
|
*/
|
||||||
|
public class ProfileViewModel extends BaseObservable {
|
||||||
|
public static final String TAG = ProfileViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private ObservableField<String> firstName = new ObservableField<>();
|
||||||
|
private ObservableField<String> lastName = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> firstNameError = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> lastNameError = new ObservableField<>();
|
||||||
|
private ObservableField<String> oldPassword = new ObservableField<>();
|
||||||
|
private ObservableField<String> password = new ObservableField<>();
|
||||||
|
private ObservableField<String> passwordConfirmation = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> oldPasswordError = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> passwordError = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> passwordConfirmationError = new ObservableField<>();
|
||||||
|
private ObservableField<String> email = new ObservableField<>();
|
||||||
|
private ObservableField<Integer> emailError = new ObservableField<>();
|
||||||
|
private ObservableBoolean passwordsVisibility = new ObservableBoolean();
|
||||||
|
|
||||||
|
private CompositeSubscription subscription;
|
||||||
|
|
||||||
|
public ProfileViewModel() {
|
||||||
|
subscription = new CompositeSubscription();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateNames() {
|
||||||
|
clearNamesErrors();
|
||||||
|
|
||||||
|
firstNameError.set(RTTUtil.getRequiredFieldError(firstName.get()));
|
||||||
|
lastNameError.set(RTTUtil.getRequiredFieldError(lastName.get()));
|
||||||
|
emailError.set(RTTUtil.getRequiredFieldError(email.get()));
|
||||||
|
|
||||||
|
return firstNameError.get() == 0 && lastNameError.get() == 0 && emailError.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validatePassword() {
|
||||||
|
clearPasswordErrors();
|
||||||
|
|
||||||
|
oldPasswordError.set(RTTUtil.getPasswordError(oldPassword.get()));
|
||||||
|
passwordError.set(RTTUtil.getPasswordError(password.get()));
|
||||||
|
passwordConfirmationError.set(RTTUtil.getPasswordConfirmationError(password.get(), passwordConfirmation.get()));
|
||||||
|
|
||||||
|
return passwordError.get() == 0 && passwordConfirmationError.get() == 0 && oldPasswordError.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearNamesErrors() {
|
||||||
|
firstNameError.set(0);
|
||||||
|
lastNameError.set(0);
|
||||||
|
emailError.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearPasswordErrors() {
|
||||||
|
oldPasswordError.set(0);
|
||||||
|
passwordError.set(0);
|
||||||
|
passwordConfirmationError.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(ObservableField<String> firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(ObservableField<String> lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getFirstNameError() {
|
||||||
|
return firstNameError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstNameError(ObservableField<Integer> firstNameError) {
|
||||||
|
this.firstNameError = firstNameError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getLastNameError() {
|
||||||
|
return lastNameError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastNameError(ObservableField<Integer> lastNameError) {
|
||||||
|
this.lastNameError = lastNameError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(ObservableField<String> password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getPasswordConfirmation() {
|
||||||
|
return passwordConfirmation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordConfirmation(ObservableField<String> passwordConfirmation) {
|
||||||
|
this.passwordConfirmation = passwordConfirmation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getPasswordError() {
|
||||||
|
return passwordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordError(ObservableField<Integer> passwordError) {
|
||||||
|
this.passwordError = passwordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getPasswordConfirmationError() {
|
||||||
|
return passwordConfirmationError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordConfirmationError(ObservableField<Integer> passwordConfirmationError) {
|
||||||
|
this.passwordConfirmationError = passwordConfirmationError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableBoolean getPasswordsVisibility() {
|
||||||
|
return passwordsVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordsVisibility(ObservableBoolean passwordsVisibility) {
|
||||||
|
this.passwordsVisibility = passwordsVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getOldPassword() {
|
||||||
|
return oldPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldPassword(ObservableField<String> oldPassword) {
|
||||||
|
this.oldPassword = oldPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getOldPasswordError() {
|
||||||
|
return oldPasswordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldPasswordError(ObservableField<Integer> oldPasswordError) {
|
||||||
|
this.oldPasswordError = oldPasswordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<String> getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(ObservableField<String> email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableField<Integer> getEmailError() {
|
||||||
|
return emailError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailError(ObservableField<Integer> emailError) {
|
||||||
|
this.emailError = emailError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSaveClicked() {
|
||||||
|
saveProfile();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadProfile() {
|
||||||
|
subscription.add(new AccountManager().getProfile()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<UserResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(UserResponse userResponse) {
|
||||||
|
User user = userResponse.getData();
|
||||||
|
if(user != null) {
|
||||||
|
firstName.set(user.getFirstName());
|
||||||
|
lastName.set(user.getLastName());
|
||||||
|
email.set(user.getEmail());
|
||||||
|
clearPasswordErrors();
|
||||||
|
clearNamesErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveProfile() {
|
||||||
|
if (validateNames()) {
|
||||||
|
if(passwordsVisibility.get() && validatePassword()) {
|
||||||
|
subscription.add(new AccountManager().changePassword(oldPassword.get(), password.get())
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<Object>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(Object o) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
User user = new User();
|
||||||
|
user.setFirstName(firstName.get());
|
||||||
|
user.setLastName(lastName.get());
|
||||||
|
user.setEmail(email.get());
|
||||||
|
subscription.add(new AccountManager().updateProfile(user)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<Object>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(Object o) {
|
||||||
|
if(!passwordsVisibility.get() || validatePassword()) {
|
||||||
|
NavigationSubject.getInstance().onNext(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if(subscription != null && !subscription.isUnsubscribed()) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ public class SearchViewModel extends BaseObservable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
rxSearch = rxSearch.debounce(1000, TimeUnit.MILLISECONDS);
|
rxSearch = rxSearch.debounce(500, TimeUnit.MILLISECONDS);
|
||||||
subscription = rxSearch.flatMap(new Func1<String, rx.Observable<UsersResponse>>() {
|
subscription = rxSearch.flatMap(new Func1<String, rx.Observable<UsersResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public rx.Observable<UsersResponse> call(String s) {
|
public rx.Observable<UsersResponse> call(String s) {
|
||||||
|
|
|
@ -1,17 +1,28 @@
|
||||||
package com.smarthomies.realtimetalk.viewmodels;
|
package com.smarthomies.realtimetalk.viewmodels;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.databinding.BaseObservable;
|
import android.databinding.BaseObservable;
|
||||||
import android.databinding.Bindable;
|
import android.databinding.Bindable;
|
||||||
import android.databinding.BindingAdapter;
|
import android.databinding.BindingAdapter;
|
||||||
import android.databinding.ObservableBoolean;
|
import android.databinding.ObservableBoolean;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.R;
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.managers.ContactsManager;
|
||||||
import com.smarthomies.realtimetalk.models.db.User;
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.CallActivity;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import rx.Subscriber;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ensar on 15/11/16.
|
* Created by ensar on 15/11/16.
|
||||||
*/
|
*/
|
||||||
|
@ -21,10 +32,22 @@ public class UserViewModel extends BaseObservable {
|
||||||
private User model;
|
private User model;
|
||||||
private ObservableBoolean state = new ObservableBoolean();
|
private ObservableBoolean state = new ObservableBoolean();
|
||||||
|
|
||||||
|
public UserViewModel() {
|
||||||
|
this.model = new User();
|
||||||
|
}
|
||||||
|
|
||||||
public UserViewModel(User model) {
|
public UserViewModel(User model) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setModel(User model) {
|
||||||
|
this.model = model;
|
||||||
|
if (model == null) {
|
||||||
|
this.model = new User();
|
||||||
|
}
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
|
||||||
@Bindable
|
@Bindable
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return model.getFirstName() + " " + model.getLastName();
|
return model.getFirstName() + " " + model.getLastName();
|
||||||
|
@ -48,8 +71,48 @@ public class UserViewModel extends BaseObservable {
|
||||||
return new View.OnClickListener() {
|
return new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
final Subscription subscription = new ContactsManager()
|
||||||
|
.saveContact(model)
|
||||||
|
.delaySubscription(3000, TimeUnit.MILLISECONDS)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new Subscriber<Object>() {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
state.set(!state.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(Object o) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
Log.d(TAG, "onClick: ");
|
Log.d(TAG, "onClick: ");
|
||||||
state.set(!state.get());
|
state.set(!state.get());
|
||||||
|
Snackbar.make(v, model.getFirstName() + " " + model.getLastName() + " added to conctacts.", Snackbar.LENGTH_LONG)
|
||||||
|
.setDuration(3000)
|
||||||
|
.setAction("Undo", new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(subscription != null && !subscription.isUnsubscribed()) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
state.set(!state.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public View.OnClickListener call() {
|
||||||
|
return new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
v.getContext().startActivity(new Intent(v.getContext(), CallActivity.class));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.smarthomies.realtimetalk.views.activities;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.utils.MediaStreamClient;
|
||||||
|
import com.smarthomies.realtimetalk.utils.MediaStreamServer;
|
||||||
|
|
||||||
|
public class CallActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private TextView serverStatus;
|
||||||
|
private EditText serverIp;
|
||||||
|
private Button nazovi;
|
||||||
|
private MediaStreamClient mss;
|
||||||
|
private MediaStreamServer msc;
|
||||||
|
// DESIGNATE A PORT
|
||||||
|
boolean isRecording;
|
||||||
|
private static Handler handler = new Handler();
|
||||||
|
Thread t=null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_call);
|
||||||
|
|
||||||
|
nazovi = (Button) findViewById(R.id.nazovi);
|
||||||
|
serverIp = (EditText) findViewById(R.id.ipAdress);
|
||||||
|
serverStatus=(TextView) findViewById(R.id.labela);
|
||||||
|
nazovi.setOnTouchListener(nazoviL);
|
||||||
|
isRecording=false;
|
||||||
|
msc=new MediaStreamServer(CallActivity.this);
|
||||||
|
t=new Thread(msc);
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private View.OnTouchListener nazoviL=new View.OnTouchListener() {
|
||||||
|
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String ip=serverIp.getText().toString();
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
msc.stop();
|
||||||
|
mss=new MediaStreamClient(CallActivity.this,ip);
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
mss.stop(CallActivity.this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void toast(final String msg, final Context ctx){
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Context context = ctx;
|
||||||
|
CharSequence text =msg;
|
||||||
|
int duration = Toast.LENGTH_SHORT;
|
||||||
|
|
||||||
|
Toast toast = Toast.makeText(context, text, duration);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,13 +2,11 @@ package com.smarthomies.realtimetalk.views.activities;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.databinding.DataBindingUtil;
|
import android.databinding.DataBindingUtil;
|
||||||
|
import android.databinding.Observable;
|
||||||
|
import android.databinding.ObservableField;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.support.design.widget.NavigationView;
|
import android.support.design.widget.NavigationView;
|
||||||
import android.support.v4.view.GravityCompat;
|
import android.support.v4.view.GravityCompat;
|
||||||
import android.support.v4.widget.DrawerLayout;
|
import android.support.v4.widget.DrawerLayout;
|
||||||
|
@ -16,25 +14,35 @@ import android.support.v7.app.ActionBarDrawerToggle;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.R;
|
import com.smarthomies.realtimetalk.R;
|
||||||
import com.smarthomies.realtimetalk.RTTActivity;
|
import com.smarthomies.realtimetalk.RTTActivity;
|
||||||
import com.smarthomies.realtimetalk.databinding.ActivityMainBinding;
|
import com.smarthomies.realtimetalk.databinding.ActivityMainBinding;
|
||||||
import com.smarthomies.realtimetalk.databinding.AppBarMainBinding;
|
import com.smarthomies.realtimetalk.databinding.AppBarMainBinding;
|
||||||
import com.smarthomies.realtimetalk.databinding.NavHeaderMainBinding;
|
|
||||||
import com.smarthomies.realtimetalk.models.db.User;
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
import com.smarthomies.realtimetalk.viewmodels.UserViewModel;
|
import com.smarthomies.realtimetalk.models.network.AuthenticationResponse;
|
||||||
|
import com.smarthomies.realtimetalk.utils.RTTErrorUtil;
|
||||||
import com.smarthomies.realtimetalk.views.adapters.UsersAdapter;
|
import com.smarthomies.realtimetalk.views.adapters.UsersAdapter;
|
||||||
import com.smarthomies.realtimetalk.views.fragments.MainViewModelHolder;
|
import com.smarthomies.realtimetalk.views.fragments.MainViewModelHolder;
|
||||||
import com.smarthomies.realtimetalk.views.fragments.registration.RegistrationViewModelHolder;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import rx.Subscriber;
|
||||||
|
import rx.Subscription;
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.exceptions.CompositeException;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
public class MainActivity extends RTTActivity
|
public class MainActivity extends RTTActivity
|
||||||
implements NavigationView.OnNavigationItemSelectedListener {
|
implements NavigationView.OnNavigationItemSelectedListener {
|
||||||
|
|
||||||
private MainViewModelHolder viewModelHolder;
|
private MainViewModelHolder viewModelHolder;
|
||||||
|
|
||||||
|
private Subscription logoutSubscription;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -54,24 +62,25 @@ public class MainActivity extends RTTActivity
|
||||||
|
|
||||||
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
|
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
|
||||||
AppBarMainBinding appBarMainBinding = binding.appBarMain;
|
AppBarMainBinding appBarMainBinding = binding.appBarMain;
|
||||||
User user = new User();
|
|
||||||
user.setFirstName("Ensar");
|
|
||||||
user.setLastName("Sarajcic");
|
|
||||||
user.setEmail("es.ensar@gmail.com");
|
|
||||||
user.setImageUrl("https://avatars3.githubusercontent.com/u/2764831?v=3&s=460");
|
|
||||||
viewModelHolder.getMainViewModel().setUser(user);
|
|
||||||
binding.setViewModel(viewModelHolder.getMainViewModel());
|
binding.setViewModel(viewModelHolder.getMainViewModel());
|
||||||
appBarMainBinding.setViewModel(viewModelHolder.getMainViewModel());
|
appBarMainBinding.setViewModel(viewModelHolder.getMainViewModel());
|
||||||
|
|
||||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvUsersList);
|
viewModelHolder.getMainViewModel().loadContacts();
|
||||||
|
viewModelHolder.getMainViewModel().loadProfile();
|
||||||
|
|
||||||
|
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvUsersList);
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
|
||||||
UsersAdapter usersAdapter = new UsersAdapter(UsersAdapter.ViewType.LIST);
|
viewModelHolder.getMainViewModel().getContacts().addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
|
||||||
ArrayList<User> users = new ArrayList<User>();
|
@Override
|
||||||
users.add(user);
|
public void onPropertyChanged(Observable observable, int i) {
|
||||||
usersAdapter.setUsers(users);
|
List<User> users = ((ObservableField<List<User>>)observable).get();
|
||||||
|
UsersAdapter usersAdapter = new UsersAdapter(UsersAdapter.ViewType.LIST);
|
||||||
recyclerView.setAdapter(usersAdapter);
|
usersAdapter.setUsers(users);
|
||||||
|
recyclerView.setAdapter(usersAdapter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
|
||||||
|
@ -87,6 +96,59 @@ public class MainActivity extends RTTActivity
|
||||||
binding.navView.setNavigationItemSelectedListener(this);
|
binding.navView.setNavigationItemSelectedListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void subscribeToSubjects() {
|
||||||
|
super.subscribeToSubjects();
|
||||||
|
logoutSubscription = getViewModelHolder().getMainViewModel().getLogoutSubject().observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new LogoutSubscriber());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void unsubscribeFromSubjects() {
|
||||||
|
super.unsubscribeFromSubjects();
|
||||||
|
if(logoutSubscription != null && !logoutSubscription.isUnsubscribed()) {
|
||||||
|
logoutSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reconnectToLogoutSubject() {
|
||||||
|
logoutSubscription = getViewModelHolder().getMainViewModel().createLogoutSubject().observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new LogoutSubscriber());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LogoutSubscriber extends Subscriber<Object> {
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
reconnectToLogoutSubject();
|
||||||
|
getViewModelHolder().getMainViewModel().onLogoutDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable e) {
|
||||||
|
reconnectToLogoutSubject();
|
||||||
|
getViewModelHolder().getMainViewModel().onLogoutDone();
|
||||||
|
|
||||||
|
if (e instanceof CompositeException) {
|
||||||
|
for (Throwable ex : ((CompositeException) e).getExceptions()) {
|
||||||
|
if(ex instanceof RuntimeException) {
|
||||||
|
handleException(ex.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(Object object) {
|
||||||
|
getViewModelHolder().getMainViewModel().onLogoutDone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||||
|
@ -127,8 +189,11 @@ public class MainActivity extends RTTActivity
|
||||||
|
|
||||||
if (id == R.id.nav_logout) {
|
if (id == R.id.nav_logout) {
|
||||||
// Handle the camera action
|
// Handle the camera action
|
||||||
startActivity(new Intent(this, LoginActivity.class));
|
getViewModelHolder().getMainViewModel().onLogoutClick();
|
||||||
finish();
|
}
|
||||||
|
|
||||||
|
if (id == R.id.nav_profile) {
|
||||||
|
getViewModelHolder().getMainViewModel().onProfileClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||||
|
@ -140,4 +205,8 @@ public class MainActivity extends RTTActivity
|
||||||
return viewModelHolder;
|
return viewModelHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleException(Throwable e) {
|
||||||
|
Toast.makeText(this, RTTErrorUtil.getErrorString(e), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.smarthomies.realtimetalk.views.activities;
|
||||||
|
|
||||||
|
import android.app.SearchManager;
|
||||||
|
import android.databinding.DataBindingUtil;
|
||||||
|
import android.databinding.Observable;
|
||||||
|
import android.databinding.ObservableField;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.view.MenuItemCompat;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.support.v7.widget.SearchView;
|
||||||
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.RTTActivity;
|
||||||
|
import com.smarthomies.realtimetalk.databinding.ActivityProfileBinding;
|
||||||
|
import com.smarthomies.realtimetalk.databinding.ActivitySearchBinding;
|
||||||
|
import com.smarthomies.realtimetalk.models.db.User;
|
||||||
|
import com.smarthomies.realtimetalk.viewmodels.SearchViewModel;
|
||||||
|
import com.smarthomies.realtimetalk.views.activities.bindingutils.OnErrorChangedCallback;
|
||||||
|
import com.smarthomies.realtimetalk.views.adapters.UsersAdapter;
|
||||||
|
import com.smarthomies.realtimetalk.views.fragments.ProfileViewModelHolder;
|
||||||
|
import com.smarthomies.realtimetalk.views.fragments.SearchViewModelHolder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProfileActivity extends RTTActivity {
|
||||||
|
|
||||||
|
private ProfileViewModelHolder viewModelHolder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Add retained to fragment manager
|
||||||
|
if(getSupportFragmentManager().findFragmentByTag(ProfileViewModelHolder.class.getName()) == null) {
|
||||||
|
viewModelHolder = new ProfileViewModelHolder();
|
||||||
|
|
||||||
|
getSupportFragmentManager()
|
||||||
|
.beginTransaction()
|
||||||
|
.add(viewModelHolder, SearchViewModelHolder.class.getName())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
viewModelHolder = (ProfileViewModelHolder)getSupportFragmentManager().findFragmentByTag(ProfileViewModelHolder.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityProfileBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_profile);
|
||||||
|
binding.setViewModel(viewModelHolder.getProfileViewModel());
|
||||||
|
|
||||||
|
|
||||||
|
getViewModelHolder().getProfileViewModel().getFirstNameError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilFirstName));
|
||||||
|
getViewModelHolder().getProfileViewModel().getLastNameError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilLastName));
|
||||||
|
getViewModelHolder().getProfileViewModel().getEmailError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilEmail));
|
||||||
|
|
||||||
|
getViewModelHolder().getProfileViewModel().getOldPasswordError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilCurrentPassword));
|
||||||
|
getViewModelHolder().getProfileViewModel().getPasswordError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilPassword));
|
||||||
|
getViewModelHolder().getProfileViewModel().getPasswordConfirmationError().addOnPropertyChangedCallback(new OnErrorChangedCallback(binding.tilConfirmPassword));
|
||||||
|
|
||||||
|
viewModelHolder.getProfileViewModel().loadProfile();
|
||||||
|
|
||||||
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
getMenuInflater().inflate(R.menu.profile, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
// Handle action bar item clicks here. The action bar will
|
||||||
|
// automatically handle clicks on the Home/Up button, so long
|
||||||
|
// as you specify a parent activity in AndroidManifest.xml.
|
||||||
|
int id = item.getItemId();
|
||||||
|
|
||||||
|
//noinspection SimplifiableIfStatement
|
||||||
|
if (id == R.id.action_save) {
|
||||||
|
getViewModelHolder().getProfileViewModel().onSaveClicked();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileViewModelHolder getViewModelHolder() {
|
||||||
|
return viewModelHolder;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.smarthomies.realtimetalk.views.activities;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.support.v7.app.ActionBar;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Pair;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.R;
|
||||||
|
import com.smarthomies.realtimetalk.RTTActivity;
|
||||||
|
import com.smarthomies.realtimetalk.utils.NavigationSubject;
|
||||||
|
import com.smarthomies.realtimetalk.utils.RTTAppHelper;
|
||||||
|
|
||||||
|
public class SplashScreenActivity extends RTTActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_splash_screen);
|
||||||
|
|
||||||
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(TextUtils.isEmpty(RTTAppHelper.getInstance().getToken())) {
|
||||||
|
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(LoginActivity.class, null));
|
||||||
|
} else {
|
||||||
|
NavigationSubject.getInstance().onNext(new Pair<Class<? extends RTTActivity>, Bundle>(MainActivity.class, null));
|
||||||
|
}
|
||||||
|
NavigationSubject.getInstance().onNext(null);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,15 @@
|
||||||
package com.smarthomies.realtimetalk.views.activities.bindingutils;
|
package com.smarthomies.realtimetalk.views.activities.bindingutils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.databinding.BindingAdapter;
|
import android.databinding.BindingAdapter;
|
||||||
import android.support.design.widget.NavigationView;
|
import android.support.design.widget.NavigationView;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.smarthomies.realtimetalk.R;
|
import com.smarthomies.realtimetalk.R;
|
||||||
import com.smarthomies.realtimetalk.viewmodels.UserViewModel;
|
import com.smarthomies.realtimetalk.viewmodels.UserViewModel;
|
||||||
|
@ -27,8 +33,27 @@ public class BindingAdapters {
|
||||||
NavHeaderMainBinding navHeaderMainBinding = NavHeaderMainBinding.inflate(LayoutInflater.from(view.getContext()));
|
NavHeaderMainBinding navHeaderMainBinding = NavHeaderMainBinding.inflate(LayoutInflater.from(view.getContext()));
|
||||||
navHeaderMainBinding.setViewModel(userViewModel);
|
navHeaderMainBinding.setViewModel(userViewModel);
|
||||||
navHeaderMainBinding.executePendingBindings();
|
navHeaderMainBinding.executePendingBindings();
|
||||||
|
for(int i = 0; i < view.getHeaderCount(); i++) {
|
||||||
|
view.removeHeaderView(view.getHeaderView(i));
|
||||||
|
}
|
||||||
view.addHeaderView(navHeaderMainBinding.getRoot());
|
view.addHeaderView(navHeaderMainBinding.getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("android:imeActionId")
|
||||||
|
public static void setActionId(EditText view, int id) {
|
||||||
|
if (view.getContext() instanceof Activity) {
|
||||||
|
final View actionView = ((Activity) view.getContext()).findViewById(id);
|
||||||
|
view.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if(actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
actionView.performClick();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,10 @@ public class MainViewModelHolder extends ViewModelHolder {
|
||||||
public void setMainViewModel(MainViewModel mainViewModel) {
|
public void setMainViewModel(MainViewModel mainViewModel) {
|
||||||
this.mainViewModel = mainViewModel;
|
this.mainViewModel = mainViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
mainViewModel.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.smarthomies.realtimetalk.views.fragments;
|
||||||
|
|
||||||
|
import com.smarthomies.realtimetalk.viewmodels.ProfileViewModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ensar on 15/11/16.
|
||||||
|
*/
|
||||||
|
public class ProfileViewModelHolder extends ViewModelHolder {
|
||||||
|
public static final String TAG = ProfileViewModelHolder.class.getSimpleName();
|
||||||
|
|
||||||
|
private ProfileViewModel profileViewModel = new ProfileViewModel();
|
||||||
|
|
||||||
|
public ProfileViewModel getProfileViewModel() {
|
||||||
|
return profileViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileViewModel(ProfileViewModel profileViewModel) {
|
||||||
|
this.profileViewModel = profileViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
profileViewModel.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<size android:width="300dp"
|
||||||
|
android:height="300dp"/>
|
||||||
|
<solid android:color="@color/colorAccent"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/clicked_rounde_shape" android:state_pressed="true"/>
|
||||||
|
<item android:drawable="@drawable/round_shape"/>
|
||||||
|
<item android:drawable="@drawable/round_shape" android:state_pressed="false"/>
|
||||||
|
</selector>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<size android:width="300dp"
|
||||||
|
android:height="300dp"/>
|
||||||
|
<solid android:color="#01579B"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
|
@ -2,8 +2,8 @@
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<gradient
|
<gradient
|
||||||
android:angle="135"
|
android:angle="135"
|
||||||
android:centerColor="#4CAF50"
|
android:centerColor="@color/colorPrimaryDark"
|
||||||
android:endColor="#2E7D32"
|
android:endColor="@color/colorPrimary"
|
||||||
android:startColor="#81C784"
|
android:startColor="@color/colorPrimary"
|
||||||
android:type="linear" />
|
android:type="linear" />
|
||||||
</shape>
|
</shape>
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
android:background="@color/colorPrimary"
|
||||||
|
android:clickable="false">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/nazovi"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nazovi"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:background="@drawable/mjenjanje"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textColor="@color/colorAccent"
|
||||||
|
android:text="@string/ipAdresa"
|
||||||
|
|
||||||
|
android:id="@+id/labela"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_alignLeft="@id/nazovi" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
android:id="@+id/ipAdress"
|
||||||
|
android:layout_below="@+id/labela"
|
||||||
|
android:layout_alignLeft="@+id/labela"
|
||||||
|
android:layout_alignStart="@+id/labela"
|
||||||
|
android:layout_marginTop="41dp"
|
||||||
|
android:layout_alignRight="@+id/nazovi"
|
||||||
|
android:layout_alignEnd="@+id/nazovi" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
|
@ -0,0 +1,220 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<data>
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.smarthomies.realtimetalk.viewmodels.ProfileViewModel"
|
||||||
|
/>
|
||||||
|
<import type="android.view.View" />
|
||||||
|
</data>
|
||||||
|
<android.support.design.widget.CoordinatorLayout
|
||||||
|
android:id="@+id/layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
android:background="@color/colorPrimary">
|
||||||
|
|
||||||
|
<android.support.design.widget.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_marginTop="?attr/actionBarSize"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
android:animateLayoutChanges="true">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilFirstName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tierFirstName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.first_name"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:maxLength="30"
|
||||||
|
android:text="@={viewModel.firstName}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilLastName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent"
|
||||||
|
app:passwordToggleTint="@color/white.50"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tierLastName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.last_name"
|
||||||
|
android:imeActionId="@+id/login"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:maxLength="30"
|
||||||
|
android:text="@={viewModel.lastName}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilEmail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent"
|
||||||
|
app:passwordToggleTint="@color/white.50"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tietEmail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.email"
|
||||||
|
android:imeActionId="@+id/login"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:text="@={viewModel.email}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:id="@+id/passwordChange"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Check to edit password too"
|
||||||
|
android:textColor="@color/colorAccent"
|
||||||
|
android:checked="@={viewModel.passwordsVisibility}"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/llPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="@{viewModel.passwordsVisibility ? View.VISIBLE : View.GONE}"
|
||||||
|
android:animateLayoutChanges="true">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilCurrentPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
app:passwordToggleTint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tietCurrentPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.old_password"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:text="@={viewModel.oldPassword}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
app:passwordToggleTint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tietPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.new_password"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:text="@={viewModel.password}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/tilConfirmPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
app:passwordToggleTint="@color/white.50"
|
||||||
|
app:counterTextAppearance="@color/colorAccent"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
android:id="@+id/tietConfirmPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt.password_confirm"
|
||||||
|
android:imeActionId="@+id/login"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/white.50"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:text="@={viewModel.passwordConfirmation}"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
</layout>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorPrimary"
|
||||||
|
tools:context="com.smarthomies.realtimetalk.views.activities.SplashScreenActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivLogo"
|
||||||
|
android:src="@mipmap/ic_launcher"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -12,7 +12,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="8dp">
|
android:layout_marginBottom="8dp"
|
||||||
|
android:onClick="@{viewModel.call()}">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivUserImage"
|
android:id="@+id/ivUserImage"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/nav_profile"
|
||||||
|
android:icon="@drawable/ic_menu_manage"
|
||||||
|
android:title="@string/action.profile" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_logout"
|
android:id="@+id/nav_logout"
|
||||||
android:icon="@drawable/ic_menu_send"
|
android:icon="@drawable/ic_menu_send"
|
||||||
android:title="Logout" />
|
android:title="@string/action.logout" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_save"
|
||||||
|
android:title="@string/title.save"
|
||||||
|
app:title="@string/title.save"
|
||||||
|
android:icon="@android:drawable/ic_menu_save"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
</menu>
|
|
@ -0,0 +1,6 @@
|
||||||
|
frequency = 44100
|
||||||
|
serverport_client = 8087
|
||||||
|
serverport_server = 8083
|
||||||
|
audio_encoding=2
|
||||||
|
channal_client=4
|
||||||
|
channal_server=2
|
|
@ -0,0 +1,12 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Declare custom theme attributes that allow changing which styles are
|
||||||
|
used for button bars depending on the API level.
|
||||||
|
?android:attr/buttonBarStyle is new as of API 11 so this is
|
||||||
|
necessary to support previous API levels. -->
|
||||||
|
<declare-styleable name="ButtonBarContainerTheme">
|
||||||
|
<attr name="metaButtonBarStyle" format="reference" />
|
||||||
|
<attr name="metaButtonBarButtonStyle" format="reference" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -13,4 +13,6 @@
|
||||||
<color name="text.hint">@color/white.50</color>
|
<color name="text.hint">@color/white.50</color>
|
||||||
<color name="text">@color/white</color>
|
<color name="text">@color/white</color>
|
||||||
|
|
||||||
|
<color name="black_overlay">#66000000</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<string name="title.introduction">Tell us who you are</string>
|
<string name="title.introduction">Tell us who you are</string>
|
||||||
<string name="title.credentials">Almost there</string>
|
<string name="title.credentials">Almost there</string>
|
||||||
<string name="title.search">Search</string>
|
<string name="title.search">Search</string>
|
||||||
|
<string name="title.save">Save</string>
|
||||||
|
|
||||||
<string name="subtitle.welcome">Input your login details</string>
|
<string name="subtitle.welcome">Input your login details</string>
|
||||||
<string name="subtitle.introduction">Input your full name</string>
|
<string name="subtitle.introduction">Input your full name</string>
|
||||||
|
@ -18,6 +19,8 @@
|
||||||
<!-- Strings related to login -->
|
<!-- Strings related to login -->
|
||||||
<string name="prompt.username">Username</string>
|
<string name="prompt.username">Username</string>
|
||||||
<string name="prompt.password">Password</string>
|
<string name="prompt.password">Password</string>
|
||||||
|
<string name="prompt.old_password">Old Password</string>
|
||||||
|
<string name="prompt.new_password">New Password</string>
|
||||||
<string name="prompt.password_confirm">Confirm Password</string>
|
<string name="prompt.password_confirm">Confirm Password</string>
|
||||||
<string name="prompt.email">Email</string>
|
<string name="prompt.email">Email</string>
|
||||||
<string name="prompt.first_name">First Name</string>
|
<string name="prompt.first_name">First Name</string>
|
||||||
|
@ -30,6 +33,8 @@
|
||||||
<string name="action.forgot_password">Forgot username or password?</string>
|
<string name="action.forgot_password">Forgot username or password?</string>
|
||||||
<string name="action.next">Next</string>
|
<string name="action.next">Next</string>
|
||||||
<string name="action.create_account">Create Account</string>
|
<string name="action.create_account">Create Account</string>
|
||||||
|
<string name="action.logout">Logout</string>
|
||||||
|
<string name="action.profile">Profile</string>
|
||||||
|
|
||||||
<!-- Login errors -->
|
<!-- Login errors -->
|
||||||
<string name="error.email.invalid">Email address is invalid</string>
|
<string name="error.email.invalid">Email address is invalid</string>
|
||||||
|
@ -43,6 +48,14 @@
|
||||||
<string name="error.bad_request">Bad request, blame Dino Dizdarevic!</string>
|
<string name="error.bad_request">Bad request, blame Dino Dizdarevic!</string>
|
||||||
<string name="error.user.not_found">User not found!</string>
|
<string name="error.user.not_found">User not found!</string>
|
||||||
<string name="error.user.bad_credentials">Please check your username and password!</string>
|
<string name="error.user.bad_credentials">Please check your username and password!</string>
|
||||||
|
<string name="error.user.already_exists">User with same username already exists!</string>
|
||||||
|
<string name="error.server">Service is currently unavailable!</string>
|
||||||
<string name="error.unknown">Unknown error!</string>
|
<string name="error.unknown">Unknown error!</string>
|
||||||
|
|
||||||
|
<string name="title_activity_splash_screen">SplashScreenActivity</string>
|
||||||
|
<string name="dummy_button">Dummy Button</string>
|
||||||
|
<string name="dummy_content">DUMMY\nCONTENT</string>
|
||||||
|
<string name="nazovi">Nazovi</string>
|
||||||
|
<string name="ipAdresa">Ip adresa</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -19,4 +19,16 @@
|
||||||
|
|
||||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||||
|
|
||||||
|
<style name="FullscreenTheme" parent="AppTheme">
|
||||||
|
<item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
|
||||||
|
<item name="android:windowActionBarOverlay">true</item>
|
||||||
|
<item name="android:windowBackground">@null</item>
|
||||||
|
<item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
|
||||||
|
<item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
|
||||||
|
<item name="android:background">@color/black_overlay</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -6,6 +6,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.2.0'
|
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||||
|
classpath "io.realm:realm-gradle-plugin:2.2.1"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
Loading…
Reference in New Issue