This commit is contained in:
Lyndon
2017-10-12 14:11:31 +02:00
parent c2a54969b0
commit e5417ff1c6
36 changed files with 406 additions and 244 deletions

View File

@@ -37,7 +37,6 @@ android {
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
storeFile file('../keystore.jks')
@@ -46,7 +45,6 @@ android {
keyPassword 'q7vWk(V&R6+NVjvg'
}
}
buildTypes {
debug {
ext.enableCrashlytics = false
@@ -61,7 +59,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
disable 'InvalidPackage'
@@ -74,55 +71,42 @@ dependencies {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
// Android support libraries
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:design:25.3.0'
// Butter Knife
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
// Dagger
compile 'com.google.dagger:dagger:2.7'
apt 'com.google.dagger:dagger-compiler:2.7'
provided 'javax.annotation:jsr250-api:1.0'
// Rx Java
compile 'io.reactivex:rxjava:1.1.6'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
// Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
// OkHttp
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
// Glide
compile 'com.github.bumptech.glide:glide:3.7.0'
// Circle ImageView
compile 'de.hdodenhof:circleimageview:2.1.0'
compile('com.crashlytics.sdk.android:crashlytics:2.6.6@aar') {
transitive = true;
}
// Secure Preferences
compile 'com.scottyab:secure-preferences-lib:0.1.4'
// Firebase
compile 'com.google.firebase:firebase-messaging:10.2.0'
// emojis
compile 'hani.momanii.supernova_emoji_library:supernova-emoji-library:0.0.2'
// circle progress
compile 'com.github.lzyzsd:circleprogress:1.2.1'
// event bus
compile 'org.greenrobot:eventbus:3.0.0'
}

View File

@@ -22,19 +22,24 @@ public class BewoplanerApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Realm.init(this);
if (!BuildConfig.DEBUG) {
Fabric.with(this, new Crashlytics());
}
buildGraphAndInject();
MessagingInstanceIdService.setApplicationContext(this);
}
private void buildGraphAndInject() {
final ApplicationModule applicationModule = new ApplicationModule(this);
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(applicationModule)
.build();
mApplicationComponent.inject(this);
}

View File

@@ -15,4 +15,6 @@ public interface AppPrefsConstants {
String PHONE_NUMBER = "phone_number";
String CHAT_OPENED = "chat_opened";
String APP_KILLED = "app_killed";
String UPLOAD_MAX_SIZE = "upload_max_size";
String IS_EMPLOYEE = "is_employee";
}

View File

@@ -8,7 +8,6 @@ import com.p3.bewoplaner.BuildConfig;
import com.p3.bewoplaner.data.AppPrefsConstants;
import com.p3.bewoplaner.data.prefs.StringPreference;
import com.p3.bewoplaner.di.P3DSEndpoint;
import com.p3.bewoplaner.di.VoucherEndpoint;
import com.p3.bewoplaner.di.scopes.ApplicationScope;
import com.p3.bewoplaner.utils.Constants;
@@ -79,9 +78,7 @@ public class ApiModule {
@Provides
@ApplicationScope
@P3DSEndpoint
OkHttpClient provideP3DSOkHttpClient(Cache cache,
HttpLoggingInterceptor loggingInterceptor,
Interceptor interceptor) {
OkHttpClient provideP3DSOkHttpClient(Cache cache, HttpLoggingInterceptor loggingInterceptor, Interceptor interceptor) {
return new OkHttpClient.Builder()
.cache(cache)
.connectTimeout(30, TimeUnit.SECONDS)
@@ -92,17 +89,6 @@ public class ApiModule {
.build();
}
@Provides
@ApplicationScope
@VoucherEndpoint
OkHttpClient provideVoucherkHttpClient(Cache cache,
HttpLoggingInterceptor loggingInterceptor) {
return new OkHttpClient.Builder()
.cache(cache)
.addInterceptor(loggingInterceptor)
.build();
}
@Provides
@ApplicationScope
CallAdapter.Factory provideCallAdapterFactory() {
@@ -137,18 +123,4 @@ public class ApiModule {
.client(okHttpClient)
.build();
}
@Provides
@ApplicationScope
@VoucherEndpoint
Retrofit provideVoucherRetrofit(@VoucherEndpoint final OkHttpClient okHttpClient,
final Converter.Factory converter,
final CallAdapter.Factory adapterFactory) {
return new Retrofit.Builder()
.baseUrl(Constants.VOUCHER_ENDPOINT)
.addCallAdapterFactory(adapterFactory)
.addConverterFactory(converter)
.client(okHttpClient)
.build();
}
}

View File

@@ -11,8 +11,7 @@ import rx.functions.Func1;
/**
* Created by laszloffiferenc on 2/21/17.
*/
public class ErrorHandlingResponseConverter<T extends BaseResponse>
implements Func1<T, Observable<T>> {
public class ErrorHandlingResponseConverter<T extends BaseResponse> implements Func1<T, Observable<T>> {
@Override
public Observable<T> call(T t) {
@@ -21,8 +20,22 @@ public class ErrorHandlingResponseConverter<T extends BaseResponse>
EventBus.getDefault().post(new InvalidTokenEvent());
return Observable.error(new ErrorThrowable(ErrorType.INVALID_TOKEN, t.errors));
}
if(t.errors.chatCodeFailed != null) {
return Observable.error(new ErrorThrowable(ErrorType.WRONG_CHATCODE, t.errors));
}
if(t.errors.chatCodeInactive != null) {
return Observable.error(new ErrorThrowable(ErrorType.DEACTIVATED_CHATCODE, t.errors));
}
if(t.errors.chatCodeTooShort != null) {
return Observable.error(new ErrorThrowable(ErrorType.CHATCODE_TOO_SHORT, t.errors));
}
return Observable.error(new ErrorThrowable(ErrorType.DATA_INPUT, t.errors));
}
return Observable.just(t);
}
}

View File

@@ -17,6 +17,20 @@ public enum ErrorType {
/**
* Expired/invalid token
*/
INVALID_TOKEN
INVALID_TOKEN,
/**
* Deactivated chat code
*/
DEACTIVATED_CHATCODE,
/**
* Wrong chat code
*/
WRONG_CHATCODE,
/**
* The chat code is too short
*/
CHATCODE_TOO_SHORT
}

View File

@@ -16,6 +16,5 @@ public class ProfileResponse extends BaseResponse {
@SerializedName("user")
public User user;
}
}

View File

@@ -39,5 +39,4 @@ public interface ChatService {
Observable<MessageResponse> sendMessage(
@Field("groupid") long groupId,
@Field("text") String text);
}

View File

@@ -1,10 +1,14 @@
package com.p3.bewoplaner.data.api.services;
import com.google.gson.JsonObject;
import com.p3.bewoplaner.data.api.responses.ProfileResponse;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Path;
import rx.Observable;
/**
@@ -17,4 +21,21 @@ public interface LoginService {
@Field("username") String username,
@Field("password") String password
);
@FormUrlEncoded
@POST("api/user/loginwithchatcode")
Observable<ProfileResponse> loginWithChatCode(
@Field("username") String username,
@Field("password") String password,
@Field("chatcode") String chatcode
);
@GET("https://dict.ownchat.de/api/server/resolve/{type}/{customerid}")
Observable<JsonObject> getServiceType(@Path("type") String type, @Path("customerid") String customerId);
@GET("api/ownchat/uploadmaxsize")
Observable<JsonObject> getUploadMaxSize();
@GET("api/ownchat/chatcode/verify/{customerid}/{userid}/{chatcode}")
Observable<JsonObject> verifyChatCode(@Path("customerid") String customerid, @Path("userid") String userid, @Path("chatcode") String chatcode);
}

View File

@@ -1,19 +0,0 @@
package com.p3.bewoplaner.data.api.services;
import com.google.gson.JsonObject;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;
/**
* Created by Rares Teodorescu on 24/03/2017.
*/
public interface VoucherService {
@GET("voucher_check.php")
Observable<JsonObject> checkVoucher(
@Query("k") String customerId,
@Query("Voucher") String voucher);
}

View File

@@ -110,4 +110,17 @@ public class AppPrefsModule {
return new BooleanPreference(sharedPreferences, AppPrefsConstants.APP_KILLED);
}
@Provides
@ApplicationScope
@Named(AppPrefsConstants.UPLOAD_MAX_SIZE)
LongPreference provideUploadMaxSize(@AppPrefs SharedPreferences sharedPreferences) {
return new LongPreference(sharedPreferences, AppPrefsConstants.UPLOAD_MAX_SIZE);
}
@Provides
@ApplicationScope
@Named(AppPrefsConstants.IS_EMPLOYEE)
BooleanPreference provideIsEmployee(@AppPrefs SharedPreferences sharedPreferences) {
return new BooleanPreference(sharedPreferences, AppPrefsConstants.IS_EMPLOYEE);
}
}

View File

@@ -38,9 +38,6 @@ public interface ApplicationComponent {
@P3DSEndpoint
Retrofit provideP3DSRetrofit();
@VoucherEndpoint
Retrofit provideVoucherRetrofit();
SystemUtils provideSystemUtils();
@AppPrefs
@@ -79,6 +76,12 @@ public interface ApplicationComponent {
@Named(AppPrefsConstants.APP_KILLED)
BooleanPreference provideAppKilled();
@Named(AppPrefsConstants.UPLOAD_MAX_SIZE)
LongPreference provideUploadMaxSize();
@Named(AppPrefsConstants.IS_EMPLOYEE)
BooleanPreference provideIsEmployee();
NotificationManager provideNotificationManager();
GroupRealmRepository provideGroupRealmRepository();

View File

@@ -41,6 +41,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sSplashComponent;
}
@@ -50,6 +51,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sLoginComponent;
}
@@ -59,6 +61,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sMainComponent;
}
@@ -68,6 +71,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sContactsComponent;
}
@@ -77,6 +81,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sMessagingComponent;
}
@@ -86,6 +91,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sProfileComponent;
}
@@ -95,6 +101,7 @@ public class InjectionHelper {
.applicationComponent(getApplicationComponent(context))
.build();
}
return sChatComponent;
}

View File

@@ -1,14 +0,0 @@
package com.p3.bewoplaner.di;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Qualifier;
/**
* Created by Rares Teodorescu on 24/03/2017.
*/
@Qualifier
@Retention(RetentionPolicy.SOURCE)
public @interface VoucherEndpoint {
}

View File

@@ -84,6 +84,7 @@ public class User implements Parcelable {
if (userRealm == null) {
return null;
}
return new User(userRealm.getId(), userRealm.getFirstName(), userRealm.getLastName(),
userRealm.getAvatar(), userRealm.getMobile(), userRealm.isEmployee());
}

View File

@@ -35,5 +35,13 @@ public class BaseResponse {
@SerializedName("token")
public String token;
@SerializedName("chatcode_inactive")
public List<String> chatCodeInactive;
@SerializedName("chatcode_failed")
public List<String> chatCodeFailed;
@SerializedName("chatcode")
public List<String> chatCodeTooShort;
}
}

View File

@@ -253,7 +253,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
@OnClick(R.id.chat_send_message)
void messageSent() {
mLoginPresenter.checkIfVoucherStillAvailable(this);
// mLoginPresenter.checkIfVoucherStillAvailable(this);
mCallback.sendMessage(mChatMessageEmojiEditText.getText().toString());
mChatMessageEmojiEditText.setText("");
}
@@ -280,7 +280,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
@Override
protected void onResume() {
super.onResume();
mLoginPresenter.checkIfVoucherStillAvailable(this);
// mLoginPresenter.checkIfVoucherStillAvailable(this);
}
@Override
@@ -359,7 +359,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
@Override
public void resendMessage(Message message) {
mLoginPresenter.checkIfVoucherStillAvailable(this);
// mLoginPresenter.checkIfVoucherStillAvailable(this);
if (!mChatPresenter.isAttached()) {
mChatPresenter.attachView(this);
}

View File

@@ -154,33 +154,43 @@ public class ChatPresenter extends MVPAbstractPresenter<ChatView>
if (messageResponse.response.messages == null || messageResponse.response.messages.isEmpty()) {
return Observable.just(null);
}
Message lastMessage = messageResponse.response.messages.get(messageResponse.response.messages.size() - 1);
lastMessage.status = Message.Status.DELIVERED;
lastMessage.isRead = true;
if (!mMessages.contains(lastMessage)) {
long groupId = mGroupId;
resetMessages();
loadMessagesFromServerByGroupId(groupId);
return Observable.just(null);
}
for (int i = 0; i < mMessageToUpdate.size(); i++) {
Pair<Message, String> messageToUpdate = mMessageToUpdate.get(i);
if (isAttached()) {
getView().lastMessageUpdated(messageToUpdate.first, messageToUpdate.second);
}
}
mMessageToUpdate.clear();
ArrayList<Message> messages = new ArrayList<>();
for (int i = messageResponse.response.messages.size() - 1; i >= 0; i--) {
Message message = messageResponse.response.messages.get(i);
message.status = Message.Status.DELIVERED;
message.isRead = true;
message.userId = mUserIdPreference.get();
if (mMessages.contains(message)) {
continue;
}
messages.add(message);
}
return mMessageRealmRepository.updateMessages(messages, new MessageByIdSpecification(mUserIdPreference.get()));
}
})

View File

@@ -14,9 +14,11 @@ public class BaseFragment extends Fragment {
@Override
public void onDestroyView() {
super.onDestroyView();
if (mUnbinder == null) {
return;
}
mUnbinder.unbind();
}
}

View File

@@ -40,8 +40,7 @@ import butterknife.OnEditorAction;
/**
* Created by imarneanu on 2/10/17.
*/
public class LoginActivity extends AppCompatActivity
implements LoginView {
public class LoginActivity extends AppCompatActivity implements LoginView {
@BindView(R.id.login_chat_code)
EditText mChatCodeEditText;
@@ -77,8 +76,7 @@ public class LoginActivity extends AppCompatActivity
mLoginPresenter.attachView(this);
decryptPreference();
ViewUtils.setProgressBarColor(mProgressBar, R.color.colorDefault);
mCallback.logout(Settings.Secure.getString(this.getContentResolver(),
Settings.Secure.ANDROID_ID), true, null);
mCallback.logout(Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID), true, null);
}
@OnEditorAction(R.id.login_password)
@@ -86,47 +84,61 @@ public class LoginActivity extends AppCompatActivity
if (actionId == EditorInfo.IME_ACTION_DONE) {
ViewUtils.hideKeyboard(this);
}
return false;
}
@OnClick(R.id.login_button)
void loginButtonClicked() {
mCallback.checkVoucher(mAccountEditText.getText().toString().trim(),
mChatCodeEditText.getText().toString().trim(),
mPasswordEditText.getText().toString(),
mSavePasswordCheckbox.isChecked());
mCallback.checkTypeAndCustomerId(mAccountEditText.getText().toString().trim(), mPasswordEditText.getText().toString().trim(), mSavePasswordCheckbox.isChecked());
}
@Override
public void voucherIsNotValid() {
public void customerIdIsValid() {
((BewoplanerApplication) getApplication()).resetApplicationComponent();
verifyIfIsChecked();
}
@Override
public void customerIdIsNotValid(int status) {
int dialogMessage;
switch (status) {
case 1:
dialogMessage = R.string.login_customer_id_is_invalid;
break;
default:
dialogMessage = R.string.login_service_type_is_undefined;
}
DialogHandler.createNoTitleDialog(this,
R.string.login_voucher_code_is_not_valid,
dialogMessage,
false,
android.R.string.ok,
(dialog, which) -> dialog.dismiss()).show();
}
@Override
public void voucherIsValid() {
((BewoplanerApplication) getApplication()).resetApplicationComponent();
verifyIfIsChecked();
}
private void verifyIfIsChecked() {
mLoginPresenter.detachView();
InjectionHelper.destroyLoginComponent();
InjectionHelper.getLoginComponent(this).inject(this);
mLoginPresenter.attachView(this);
mCallback.tryToLogin(mUsernameEditText.getText().toString().trim(), mPasswordEditText.getText().toString());
mCallback.tryToLogin(mUsernameEditText.getText().toString().trim(), mPasswordEditText.getText().toString(), mChatCodeEditText.getText().toString().trim());
}
@Override
public void loginSuccessful() {
mCallback.tryToRegisterDevice(Settings.Secure.getString(this.getContentResolver(),
Settings.Secure.ANDROID_ID), FirebaseInstanceId.getInstance().getToken());
mCallback.retrieveUploadMaxSize();
}
@Override
public void retrievedUploadMaxSize() {
mCallback.tryToRegisterDevice(Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID), FirebaseInstanceId.getInstance().getToken());
if (!mSavePasswordCheckbox.isChecked()) {
startService(new Intent(getBaseContext(), AppStoppedService.class));
}
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
@@ -135,6 +147,7 @@ public class LoginActivity extends AppCompatActivity
private void decryptPreference() {
for (Map.Entry<String, ?> entry : mSecuredPrefs.getAll().entrySet()) {
final String key = entry.getKey();
if (key == null) {
continue;
} else if (key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.CHAT_CODE))) {
@@ -180,10 +193,10 @@ public class LoginActivity extends AppCompatActivity
@Override
public void showError(String message) {
if (mSnackbar == null) {
mSnackbar = Snackbar.make(findViewById(R.id.login_coordinator_layout), message, Snackbar.LENGTH_LONG)
.setAction("Retry", view -> verifyIfIsChecked());
mSnackbar = Snackbar.make(findViewById(R.id.login_coordinator_layout), message, Snackbar.LENGTH_LONG).setAction("Retry", view -> verifyIfIsChecked());
mSnackbar.setActionTextColor(ContextCompat.getColor(this, R.color.colorDefault));
}
mSnackbar.setText(message);
mSnackbar.show();
}

View File

@@ -2,9 +2,7 @@ package com.p3.bewoplaner.page.login;
import com.p3.bewoplaner.data.api.services.LoginService;
import com.p3.bewoplaner.data.api.services.RegisterService;
import com.p3.bewoplaner.data.api.services.VoucherService;
import com.p3.bewoplaner.di.P3DSEndpoint;
import com.p3.bewoplaner.di.VoucherEndpoint;
import com.p3.bewoplaner.di.scopes.ActivityScope;
import dagger.Module;
@@ -28,10 +26,4 @@ public class LoginModule {
RegisterService provideRegisterService(@P3DSEndpoint Retrofit retrofit) {
return retrofit.create(RegisterService.class);
}
@Provides
@ActivityScope
VoucherService provideVoucherService(@VoucherEndpoint Retrofit retrofit) {
return retrofit.create(VoucherService.class);
}
}

View File

@@ -12,7 +12,6 @@ import com.p3.bewoplaner.data.api.common.ErrorUtils;
import com.p3.bewoplaner.data.api.responses.RegisterResponse;
import com.p3.bewoplaner.data.api.services.LoginService;
import com.p3.bewoplaner.data.api.services.RegisterService;
import com.p3.bewoplaner.data.api.services.VoucherService;
import com.p3.bewoplaner.data.prefs.AppPrefs;
import com.p3.bewoplaner.data.prefs.BooleanPreference;
import com.p3.bewoplaner.data.prefs.LongPreference;
@@ -54,20 +53,17 @@ import rx.schedulers.Schedulers;
/**
* Created by laszloffiferenc on 2/21/17.
*/
public class LoginPresenter extends MVPAbstractPresenter<LoginView>
implements LoginView.Callback {
public class LoginPresenter extends MVPAbstractPresenter<LoginView> implements LoginView.Callback {
private static final String TAG = "error";
//region Dependency injection
@Inject
LoginService mLoginService;
@Inject
RegisterService mRegisterService;
@Inject
VoucherService mVoucherService;
@Inject
@Named(AppPrefsConstants.API_ENDPOINT)
StringPreference mApiEndpointPreference;
@@ -104,6 +100,14 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
@Named(AppPrefsConstants.PHONE_NUMBER)
StringPreference mPhoneNumberPreference;
@Inject
@Named(AppPrefsConstants.UPLOAD_MAX_SIZE)
LongPreference mUploadMaxSizePreference;
@Inject
@Named(AppPrefsConstants.IS_EMPLOYEE)
BooleanPreference mIsEmployee;
@Inject
@AppPrefs
SharedPreferences mSharedPreferences;
@@ -135,13 +139,14 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
@Inject
Context mContext;
//endregion
private String mLastVoucher;
@Inject
LoginPresenter() {
private int mStatus;
}
@Inject
LoginPresenter() {}
@Override
protected void afterAttachView(@NonNull LoginView view) {
@@ -155,47 +160,73 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
super.beforeDetachView(view);
}
//region Login and device registration
/**
* Try to login with the given parameters
* @param username login username as {@code String}
* @param password login password as {@code String}
* @param chatCode login chat code as {@code String}
*/
private void loginCall(String username, String password) {
private void loginCall(String username, String password, String chatCode) {
getView().showLoading();
Subscription subscription = mLoginService.login(username, password)
mLastVoucher = chatCode;
Subscription subscription = mLoginService.loginWithChatCode(username, password, chatCode)
.compose(RxUtils.provideDefaultTransformer())
.flatMap(new ErrorHandlingResponseConverter<>())
.map(loginResponse -> loginResponse.response.user)
.subscribe(this::loginSuccess, this::loginError);
addSubscription(subscription);
}
/**
* Error to show in view if something went wrong during the login.
*/
private void loginError(Throwable throwable) {
getView().showContent();
if (mSystemUtils.isNetworkUnavailable()) {
getView().showError(R.string.error_no_internet_connection);
return;
}
if (ErrorUtils.getErrorType(throwable) == ErrorType.DATA_INPUT) {
ErrorThrowable errorThrowable = (ErrorThrowable) throwable;
if (errorThrowable.getError().loginFailed != null && errorThrowable.getError().loginFailed.size() > 0) {
getView().showError(errorThrowable.getError().loginFailed.get(0));
return;
}
ErrorThrowable errorThrowable = (ErrorThrowable) throwable;
switch(ErrorUtils.getErrorType(throwable)) {
case DATA_INPUT:
if (errorThrowable.getError().loginFailed != null && errorThrowable.getError().loginFailed.size() > 0) {
getView().showError(errorThrowable.getError().loginFailed.get(0));
return;
}
case WRONG_CHATCODE:
if (errorThrowable.getError().chatCodeFailed != null && errorThrowable.getError().chatCodeFailed.size() > 0) {
getView().showError(R.string.error_wrong_chat_code);
return;
}
case DEACTIVATED_CHATCODE:
if (errorThrowable.getError().chatCodeInactive != null && errorThrowable.getError().chatCodeInactive.size() > 0) {
getView().showError(R.string.error_deactivated_chat_code);
return;
}
case CHATCODE_TOO_SHORT:
if (errorThrowable.getError().chatCodeTooShort != null && errorThrowable.getError().chatCodeTooShort.size() > 0) {
getView().showError(R.string.error_chat_code_too_short);
return;
}
default:
getView().showError(R.string.error_something_went_wrong);
}
getView().showError(R.string.error_something_went_wrong);
}
/**
* Set user data in preferences if login is successful.
* @param user {@code User} the current logged in user.
*/
private void loginSuccess(User user) {
mIsEmployee.set(user.isEmployee);
mChatCodePreference.set(mLastVoucher);
mLoginTokenPreference.set(user.token);
mUserIdReference.set(user.id);
mAvatarPreference.set(user.avatar);
@@ -208,22 +239,22 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
*Checks the {@code String} username and {@code String} password
* if are corresponding to criteria.
*/
@Override
public void tryToLogin(String username, String password) {
public void tryToLogin(String username, String password, String chatCode) {
if (!checkPassword(password)) {
return;
}
if (!checkUsername(username)) {
return;
}
loginCall(username, password);
loginCall(username, password, chatCode);
}
/**
* Register the current device. Used if the login is successful.
*/
@Override
public void tryToRegisterDevice(String deviceId, String fcmToken) {
Subscription subscription = mRegisterService.registerDevice(deviceId, fcmToken)
@@ -231,89 +262,165 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
.flatMap(new ErrorHandlingResponseConverter<>())
.map(registerResponse -> registerResponse.response)
.subscribe(this::registerSuccessful, this::registerError);
addSubscription(subscription);
}
private void registerError(Throwable throwable) {
if (ErrorUtils.getErrorType(throwable) == ErrorType.DATA_INPUT) {
ErrorThrowable errorThrowable = (ErrorThrowable) throwable;
if (errorThrowable.getError().fcmToken != null && errorThrowable.getError().fcmToken.size() > 0) {
Log.d(TAG, "fcmToken error: " + errorThrowable.getError().fcmToken.get(0));
return;
}
if (errorThrowable.getError().deviceId != null && errorThrowable.getError().deviceId.size() > 0) {
Log.d(TAG, "fcmToken error: " + errorThrowable.getError().deviceId.get(0));
}
}
}
private void registerSuccessful(String s) {
}
//endregion
//region CheckTypeAndCustomerId
/**
* Checks if the voucher necessary for login is correct.
*/
@Override
public void checkVoucher(String customerId, String voucher, String password, boolean isChecked) {
mLastVoucher = voucher;
public void checkTypeAndCustomerId(String customerId, String password, boolean isChecked) {
mAccountNumberPreference.set(customerId);
mSavePasswordPreference.set(isChecked);
if (!checkPassword(password)) {
return;
}
if (TextUtils.isEmpty(voucher)) {
getView().showError(R.string.error_voucher_code_must_not_be_null);
return;
}
if (TextUtils.isEmpty(customerId)) {
getView().showError(R.string.error_customer_id_must_not_be_null);
return;
}
getView().showLoading();
Subscription subscription = mVoucherService.checkVoucher(customerId, voucher)
Subscription subscription = mLoginService.getServiceType("1", customerId)
.flatMap(new Func1<JsonObject, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(JsonObject response) {
if (response.has(voucher) && response.get(voucher) != null) {
JsonObject voucherObject = response.getAsJsonObject(voucher);
if (voucherObject.has("CustomerID")
&& !TextUtils.isEmpty(voucherObject.get("CustomerID").getAsString())
&& voucherObject.has("ServerName")
&& !TextUtils.isEmpty(voucherObject.get("ServerName").getAsString())) {
String serverName = voucherObject.get("ServerName").getAsString();
if (!serverName.startsWith("https")) {
serverName = "https://" + serverName + "/";
}
mApiEndpointPreference.set(serverName);
return Observable.just(true);
JsonObject serviceObject = response.getAsJsonObject();
if (serviceObject.has("Status")
&& !TextUtils.isEmpty(serviceObject.get("Status").getAsString())
&& serviceObject.has("URL")
&& !TextUtils.isEmpty(serviceObject.get("URL").getAsString())) {
String serverName = serviceObject.get("URL").getAsString();
if (!serverName.startsWith("https")) {
serverName = "https://" + serverName + "/";
}
mApiEndpointPreference.set(serverName);
return Observable.just(true);
} else if(serviceObject.has("Status") && !TextUtils.isEmpty(serviceObject.get("Status").getAsString())) {
mStatus = serviceObject.get("Status").getAsInt();
}
return Observable.just(false);
}
})
.compose(RxUtils.provideDefaultTransformer())
.subscribe(this::checkVoucherSuccessful, this::checkVoucherError);
.subscribe(this::checkTypeAndCustomerIdSuccessful, this::checkTypeAndCustomerIdError);
addSubscription(subscription);
}
private void checkVoucherError(Throwable throwable) {
private void checkTypeAndCustomerIdError(Throwable throwable) {
getView().showContent();
if (mSystemUtils.isNetworkUnavailable()) {
getView().showError(R.string.error_no_internet_connection);
return;
}
getView().showError(R.string.error_something_went_wrong);
}
private void checkVoucherSuccessful(Boolean vouchIsValid) {
private void checkTypeAndCustomerIdSuccessful(Boolean customerIdIsValid) {
getView().showContent();
if (vouchIsValid) {
mChatCodePreference.set(mLastVoucher);
getView().voucherIsValid();
if(customerIdIsValid) {
getView().customerIdIsValid();
return;
}
deleteData(true);
getView().voucherIsNotValid();
getView().customerIdIsNotValid(mStatus);
}
//endregion
//region UploadMaxSize
@Override
public void retrieveUploadMaxSize() {
getView().showLoading();
Subscription subscription = mLoginService.getUploadMaxSize()
.flatMap(new Func1<JsonObject, Observable<Integer>>() {
@Override
public Observable<Integer> call(JsonObject response) {
JsonObject maxSizeObject = response.getAsJsonObject();
if(maxSizeObject.has("file_upload_max_size")) {
mUploadMaxSizePreference.set(maxSizeObject.get("file_upload_max_size").getAsLong());
}
return Observable.just(0);
}
})
.compose(RxUtils.provideDefaultTransformer())
.subscribe(this::retrieveUploadMaxSizeSuccessful, this::retrieveUploadMaxSizeError);
addSubscription(subscription);
}
private void retrieveUploadMaxSizeError(Throwable throwable) {
getView().showContent();
if (mSystemUtils.isNetworkUnavailable()) {
getView().showError(R.string.error_no_internet_connection);
return;
}
getView().showError(R.string.login_service_type_is_undefined);
}
private void retrieveUploadMaxSizeSuccessful(long retrievedMaxSize) {
getView().showContent();
getView().retrievedUploadMaxSize();
}
//endregion
//region Logout
/**
* Logout from application deletes all login preferences and redirects to login screen.
*/
@Override
public void logout(String deviceId, boolean clearAllPrefs, MainNavigation mainNavigation) {
mNotificationManager.cancelAll();
if (!mLoginTokenPreference.isSet()) {
if (mainNavigation != null) {
mainNavigation.goToLoginActivity();
}
return;
}
mRegisterService.unregisterDevice(deviceId)
.compose(RxUtils.provideDefaultTransformer())
.flatMap(new ErrorHandlingResponseConverter<>())
@@ -323,6 +430,7 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
//after device unregister we remove also the token
mLoginTokenPreference.delete();
deleteData(clearAllPrefs);
if (mainNavigation != null) {
mainNavigation.goToLoginActivity();
}
@@ -334,6 +442,7 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
//after device unregister we remove also the token
mLoginTokenPreference.delete();
deleteData(clearAllPrefs);
if (mainNavigation != null) {
mainNavigation.goToLoginActivity();
}
@@ -346,72 +455,64 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
});
}
private void registerError(Throwable throwable) {
if (ErrorUtils.getErrorType(throwable) == ErrorType.DATA_INPUT) {
ErrorThrowable errorThrowable = (ErrorThrowable) throwable;
if (errorThrowable.getError().fcmToken != null && errorThrowable.getError().fcmToken.size() > 0) {
Log.d(TAG, "fcmToken error: " + errorThrowable.getError().fcmToken.get(0));
return;
}
if (errorThrowable.getError().deviceId != null && errorThrowable.getError().deviceId.size() > 0) {
Log.d(TAG, "fcmToken error: " + errorThrowable.getError().deviceId.get(0));
}
}
}
@Override
public void tryToLogout(String deviceId, MainNavigation mainNavigation) {
if (mSavePasswordPreference.get()) {
return;
}
logout(deviceId, false, mainNavigation);
}
//endregion
@Override
public void checkIfVoucherStillAvailable(LogoutNavigation logoutNavigation) {
public void verifyChatCode(LogoutNavigation logoutNavigation) {
if (mAccountNumberPreference.get() == null) {
return;
}
String voucher = mChatCodePreference.get();
String chatCode = mChatCodePreference.get();
String customerId = mAccountNumberPreference.get();
Subscription subscription = mVoucherService.checkVoucher(customerId, voucher)
String userId = (mIsEmployee.get() ? "E" : "C") + mUserIdReference.get().toString();
Subscription subscription = mLoginService.verifyChatCode(customerId, userId, chatCode)
.compose(RxUtils.provideDefaultTransformer())
.subscribe(new Subscriber<JsonObject>() {
@Override
public void onCompleted() {
}
public void onCompleted() {}
@Override
public void onError(Throwable e) {
if (mSystemUtils.isNetworkUnavailable() || e instanceof SocketTimeoutException) {
return;
}
Toast.makeText(mContext, "Please make sure you have internet connection", Toast.LENGTH_SHORT).show();
Toast.makeText(mContext, mContext.getString(R.string.error_token_validation_failed), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(JsonObject response) {
if (!response.has(voucher) || response.get(voucher) == null) {
if (!response.has("result") || response.get("result") == null) {
logoutNavigation.logoutDirectly();
return;
}
JsonObject voucherObject = response.getAsJsonObject(voucher);
if (!voucherObject.has("CustomerID")
|| TextUtils.isEmpty(voucherObject.get("CustomerID").getAsString())
|| !voucherObject.has("ServerName")
|| TextUtils.isEmpty(voucherObject.get("ServerName").getAsString())) {
logoutNavigation.logoutDirectly();
int result = response.get("result").getAsInt();
if(result == 0) {
deleteData(true);
}
logoutNavigation.logoutDirectly();
}
});
addSubscription(subscription);
}
/**
* Clears all login preferences.
*/
private void deleteData(boolean clearAllPrefs) {
if (clearAllPrefs) {
Observable.create(subscriber -> mGlide.clearDiskCache())
@@ -422,10 +523,13 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
mAccountNumberPreference.deleteFromSecurePreference();
mChatCodePreference.deleteFromSecurePreference();
mSavePasswordPreference.deleteFromSecurePreference();
File dir = mContext.getExternalFilesDir(null);
if (dir != null) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
//noinspection ResultOfMethodCallIgnored
new File(dir, aChildren).delete();
@@ -435,8 +539,10 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
}
} else {
dir = new File(Environment.getExternalStorageDirectory(), "BeWoPlaner");
if (dir.isDirectory()) {
String[] children = dir.list();
for (String aChildren : children) {
//noinspection ResultOfMethodCallIgnored
new File(dir, aChildren).delete();
@@ -445,6 +551,7 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
Log.e("deleteData", dir.getAbsolutePath() + " is not a directory!");
}
}
Realm realm = mRealmProvider.provide();
realm.executeTransaction(realm1 -> realm1.deleteAll());
} else {
@@ -452,21 +559,20 @@ public class LoginPresenter extends MVPAbstractPresenter<LoginView>
}
}
private void registerSuccessful(String s) {
}
private boolean checkPassword(String password) {
if (password.length() >= 8) {
if (password.length() >= 1) {
return true;
}
getView().showError(R.string.error_password_too_short);
return false;
}
private boolean checkUsername(String username) {
if (username.length() >= 4) {
if (username.length() >= 1) {
return true;
}
getView().showError(R.string.error_username_too_short);
return false;
}

View File

@@ -12,22 +12,25 @@ interface LoginView extends MVPLceView {
void setCallback(Callback callback);
void voucherIsValid();
void customerIdIsValid();
void voucherIsNotValid();
void customerIdIsNotValid(int status);
void retrievedUploadMaxSize();
interface Callback {
void verifyChatCode(LogoutNavigation logoutNavigation);
void checkVoucher(String customerId, String voucher, String password, boolean isChecked);
void retrieveUploadMaxSize();
void tryToLogin(String email, String password);
void checkTypeAndCustomerId(String customerId, String password, boolean isChecked);
void tryToLogin(String email, String password, String chatCode);
void tryToRegisterDevice(String deviceId, String fcmToken);
void logout(String deviceId, boolean clearAllPrefs, MainNavigation mainNavigation);
void tryToLogout(String deviceId, MainNavigation mainNavigation);
void checkIfVoucherStillAvailable(LogoutNavigation logoutNavigation);
}
}

View File

@@ -38,10 +38,10 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import javax.inject.Inject;
import javax.inject.Named;
@@ -115,39 +115,44 @@ public class MainActivity extends AppCompatActivity
Utils.hideKeyboard(MainActivity.this);
}
};
mDrawer.closeDrawer(GravityCompat.START);
mDrawer.addDrawerListener(toggle);
View headerLayout = mNavigationView.getHeaderView(0);
CircleImageView avatar = (CircleImageView) headerLayout.findViewById(R.id.menu_profile_imageView);
Glide.with(this).load(mAvatarPreference.get()).into(avatar);
mDrawer.setOnTouchListener((view, motionEvent) -> {
Glide.with(view.getContext()).load(mAvatarPreference.get()).into(avatar);
return false;
});
toggle.syncState();
ArrayAdapter<String> adapter = new NavigationMenuAdapter(this,
getResources().getStringArray(R.array.nav_menu), this);
ArrayAdapter<String> adapter = new NavigationMenuAdapter(this, getResources().getStringArray(R.array.nav_menu), this);
mNavigationListView.setAdapter(adapter);
switchFragment(new ContactsFragment());
onNewIntent(getIntent());
}
@Override
protected void onSaveInstanceState(Bundle outState) {
}
protected void onSaveInstanceState(Bundle outState) {}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra(REDIRECT_TO_CHAT) && !mChatOpenedPref.get()) {
Bundle message = intent.getBundleExtra(BUNDLE);
Intent startIntent;
if (intent.getIntExtra(Constants.GROUP_NR_USERS, 2) > 2) {
startIntent = GroupChatActivity.createIntent(this, message);
} else {
startIntent = SingleChatActivity.createIntent(this, message);
}
mChatOpenedPref.set(true);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(startIntent);
intent.removeExtra(REDIRECT_TO_CHAT);
@@ -158,7 +163,6 @@ public class MainActivity extends AppCompatActivity
@Override
protected void onResume() {
super.onResume();
mLoginPresenter.checkIfVoucherStillAvailable(this);
}
private void switchFragment(@NonNull Fragment fragment) {
@@ -170,9 +174,11 @@ public class MainActivity extends AppCompatActivity
if (fragment.getClass().isInstance(currentFragment)) {
return;
}
if (clearBackStack) {
Utils.clearFullBackStack(this);
}
addFragmentToBackStack(fragment);
}
@@ -189,23 +195,22 @@ public class MainActivity extends AppCompatActivity
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
}
if (getSupportFragmentManager().getBackStackEntryCount() <= 1) {
finish();
}
mLoginPresenter.checkIfVoucherStillAvailable(this);
super.onBackPressed();
}
@Override
public void goToContacts() {
mLoginPresenter.checkIfVoucherStillAvailable(this);
mDrawer.closeDrawer(GravityCompat.START);
switchFragment(new ContactsFragment());
}
@Override
public void goToProfile() {
mLoginPresenter.checkIfVoucherStillAvailable(this);
mDrawer.closeDrawer(GravityCompat.START);
switchFragment(new ProfileFragment(), false);
}
@@ -220,8 +225,7 @@ public class MainActivity extends AppCompatActivity
(dialog, which) -> {
mLogoutClicked = true;
mDrawer.closeDrawer(GravityCompat.START);
mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(),
Settings.Secure.ANDROID_ID), false, this);
mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(), Settings.Secure.ANDROID_ID), false, this);
},
(dialog, which) -> dialog.dismiss());
if (!isFinishing()) {
@@ -238,8 +242,7 @@ public class MainActivity extends AppCompatActivity
@Override
public void logoutDirectly() {
mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(),
Settings.Secure.ANDROID_ID), true, this);
mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(), Settings.Secure.ANDROID_ID), true, this);
}
@Override
@@ -247,6 +250,7 @@ public class MainActivity extends AppCompatActivity
if (isFinishing()) {
return;
}
startActivity(new Intent(MainActivity.this, LoginActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
finish();
}
@@ -254,8 +258,8 @@ public class MainActivity extends AppCompatActivity
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onInvalidToken(InvalidTokenEvent invalidTokenEvent) {
Toast.makeText(this, R.string.login_again, Toast.LENGTH_LONG).show();
logoutDirectly();
Log.d("INVALID TOKEN", " invalid token event fired");
mLoginPresenter.verifyChatCode(this);
}
@SuppressWarnings("unused")
@@ -268,10 +272,11 @@ public class MainActivity extends AppCompatActivity
protected void onDestroy() {
EventBus.getDefault().unregister(this);
mChatOpenedPref.set(false);
if (!mLogoutClicked && getIntent().getBooleanExtra(LOGOUT, true)) {
mLoginPresenter.tryToLogout(Settings.Secure.getString(this.getContentResolver(),
Settings.Secure.ANDROID_ID), this);
mLoginPresenter.tryToLogout(Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID), this);
}
getIntent().removeExtra(LOGOUT);
InjectionHelper.destroyMainComponents();
super.onDestroy();

View File

@@ -35,6 +35,7 @@ class NavigationMenuAdapter extends ArrayAdapter<String> {
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
@@ -43,11 +44,12 @@ class NavigationMenuAdapter extends ArrayAdapter<String> {
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.action.setText(mData[position]);
holder.action.setTextSize(position < IMPRESSUM ? 21.0f : 12.0f);
holder.action.setTextColor(ContextCompat.getColor(mContext, (position < IMPRESSUM ?
R.color.colorWhite : R.color.colorImpressum)));
holder.action.setTextColor(ContextCompat.getColor(mContext, (position < IMPRESSUM ? R.color.colorWhite : R.color.colorImpressum)));
holder.position = position;
return view;
}

View File

@@ -111,6 +111,7 @@ class ProfilePresenter extends MVPAbstractPresenter<ProfileView> implements Prof
getView().showError(R.string.error_no_internet_connection);
return;
}
getView().showError(R.string.error_something_went_wrong);
}

View File

@@ -25,6 +25,7 @@ public class SplashActivity extends AppCompatActivity implements SplashView {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
// Activity was brought to front and not created,
// Thus finishing this will get us to the last viewed activity
@@ -32,6 +33,7 @@ public class SplashActivity extends AppCompatActivity implements SplashView {
Log.e("Splash", "FINISH");
return;
}
InjectionHelper.getSplashComponent(this).inject(this);
mSplashPresenter.attachView(this);
mCallbacks.startTimer();
@@ -42,6 +44,7 @@ public class SplashActivity extends AppCompatActivity implements SplashView {
if (mSplashPresenter != null && mSplashPresenter.isAttached()) {
mSplashPresenter.detachView();
}
InjectionHelper.destroySplashComponent();
super.onDestroy();
}
@@ -64,6 +67,7 @@ public class SplashActivity extends AppCompatActivity implements SplashView {
goToMainActivity();
return;
}
goToLoginActivity();
}

View File

@@ -19,8 +19,7 @@ import rx.Subscription;
/**
* Created by imarneanu on 2/9/17.
*/
class SplashPresenter extends MVPAbstractPresenter<SplashView>
implements SplashView.Callbacks {
class SplashPresenter extends MVPAbstractPresenter<SplashView> implements SplashView.Callbacks {
private static final int SPLASH_DELAY_MILLIS = BuildConfig.DEBUG ? 0 : 1500;

View File

@@ -75,9 +75,11 @@ public final class DialogHandler {
DialogInterface.OnClickListener callback) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.StyledDialog);
if (title != 0) {
builder.setTitle(title);
}
return builder
.setMessage(message)
.setPositiveButton(positiveButton, callback)

View File

@@ -32,12 +32,13 @@ public abstract class EndlessScrollListener extends RecyclerView.OnScrollListene
mPreviousTotal = totalItemCount;
}
}
if (recyclerView == null) {
return;
}
recyclerView.post(() -> {
if (!mLoading
&& (totalItemCount - visibleItemCount) <= (mVisibleItem + mVisibleThreshold)) {
if (!mLoading && (totalItemCount - visibleItemCount) <= (mVisibleItem + mVisibleThreshold)) {
mLoading = onLoad();
}
});

View File

@@ -67,6 +67,7 @@ public class FileUtils {
}
int dot = uri.lastIndexOf(".");
if (dot >= 0) {
return uri.substring(dot);
} else {
@@ -217,18 +218,19 @@ public class FileUtils {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
if (DEBUG) {
DatabaseUtils.dumpCursor(cursor);
}
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {

View File

@@ -42,10 +42,11 @@ public class LoggedOutUtils {
public boolean checkLoggedOutPrefs() {
if (!mSavePasswordPreference.get() && mAppKilledPreference.get()) {
mNotificationManager.cancelAll();
mLoginPresenter.logout(Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.ANDROID_ID), true, null);
mLoginPresenter.logout(Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID), true, null);
return true;
}
return false;
}
}

View File

@@ -48,6 +48,7 @@ public final class Preconditions {
if (thing == null) {
throw new NullPointerException(formatMessage(message, args));
}
return thing;
}

View File

@@ -17,6 +17,7 @@ public class SystemUtils {
public boolean isNetworkUnavailable() {
NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo();
return activeNetwork == null || !activeNetwork.isConnectedOrConnecting();
}
}

View File

@@ -11,12 +11,13 @@ import android.view.inputmethod.InputMethodManager;
*/
public class Utils {
/**
* Clears activity's backstack
* Clears activity's back stack
*
* @param appCompatActivity The activity which will have no fragments in backstack
* @param appCompatActivity The activity which will have no fragments in back stack
*/
public static void clearFullBackStack(AppCompatActivity appCompatActivity) {
FragmentManager fragmentManager = appCompatActivity.getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
// clear the fragment back stack
FragmentManager.BackStackEntry first = fragmentManager.getBackStackEntryAt(0);
@@ -27,10 +28,11 @@ public class Utils {
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
View view = activity.getCurrentFocus();
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}

View File

@@ -15,6 +15,8 @@
<string name="login_save_password">Passwort speichern</string>
<string name="login_button_text">Anmelden</string>
<string name="login_voucher_code_is_not_valid">Chat-Code oder Kundennummer stimmen nicht überein.</string>
<string name="login_customer_id_is_invalid">Die Kundennummer ist ungültig.</string>
<string name="login_service_type_is_undefined">Fehler. Bitte wenden Sie sich an den Support.</string>
<!-- Navigation Drawer -->
<string-array name="nav_menu">
@@ -23,6 +25,7 @@
<item>Abmelden</item>
<item>Impressum</item>
</string-array>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
@@ -45,18 +48,22 @@
<!-- Error messages -->
<string name="error_no_internet_connection">Keine Internetverbindung</string>
<string name="error_password_too_short">Passwort ist zu kurz</string>
<string name="error_username_too_short">Username is too short</string>
<string name="error_username_too_short">Benutzername ist zu kurz</string>
<string name="error_something_went_wrong">Ungültige Eingabe</string>
<string name="error_customer_id_must_not_be_null">Kundennummer darf nicht leer sein</string>
<string name="error_voucher_code_must_not_be_null">Chat-code darf nicht leer sein</string>
<string name="error_retry">Wiederholen</string>
<string name="error">Fehler</string>
<string name="change_avatar_permisssion">Avatar Berechtigung ändern</string>
<string name="change_avatar_permisssion">Avatar-Berechtigung ändern</string>
<string name="error_retry_failed">Erneut fehlgeschlagen</string>
<string name="error_message_not_sent">Nachricht konnte nicht gesendet werden</string>
<string name="error_could_not_open_file">Datei konnte nicht geöffnet werden</string>
<string name="error_file_does_not_exist_anymore">File does not exist anymore.</string>
<string name="error_file_not_found">File not found, please try again.</string>
<string name="error_file_does_not_exist_anymore">Die Datei existiert nicht mehr.</string>
<string name="error_file_not_found">Die Datei konnte nicht gefunden werden, bitte versuchen Sie es erneut.</string>
<string name="error_wrong_chat_code">Bitte den Chat-Code prüfen</string>
<string name="error_deactivated_chat_code">Chat-Code ist deaktiviert</string>
<string name="error_chat_code_too_short">Chat-Code hat eine falsche Länge</string>
<string name="error_token_validation_failed">Bitte stellen Sie sicher, dass Sie mit dem Internet verbunden sind.</string>
<!-- Permissions -->
<string name="permission_grant">Erlauben</string>