convert code to kotlin

This commit is contained in:
Phillip Thelen 2019-05-31 10:22:33 +02:00
parent a725b0f362
commit 6c8f909a47
15 changed files with 234 additions and 269 deletions

View file

@ -150,7 +150,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
multiDexEnabled true
versionCode 2141
versionCode 2144
versionName "1.10"
}

View file

@ -1,86 +0,0 @@
package com.habitrpg.android.habitica.helpers;
import android.content.Context;
import androidx.annotation.Nullable;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.data.ApiClient;
import com.habitrpg.android.habitica.events.ShowCheckinDialog;
import com.habitrpg.android.habitica.events.ShowSnackbarEvent;
import com.habitrpg.android.habitica.models.Notification;
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar;
import org.greenrobot.eventbus.EventBus;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by krh12 on 12/9/2016.
*/
public class PopupNotificationsManager {
private Map<String, Boolean> seenNotifications;
@Nullable
private ApiClient apiClient;
private Context context;
// @TODO: A queue for displaying alert dialogues
public PopupNotificationsManager(Context context) {
this.seenNotifications = new HashMap<>();
this.context = context;
}
public void setApiClient(@Nullable ApiClient apiClient) {
this.apiClient = apiClient;
}
Boolean displayNotification(Notification notification) {
String nextUnlockText = context.getString(R.string.nextPrizeUnlocks, notification.data.nextRewardAt);
if (notification.data.rewardKey != null) {
ShowCheckinDialog event = new ShowCheckinDialog();
event.notification = notification;
event.nextUnlockText = nextUnlockText;
EventBus.getDefault().post(event);
} else {
ShowSnackbarEvent event = new ShowSnackbarEvent();
event.title = notification.data.message;
event.text = nextUnlockText;
event.type = HabiticaSnackbar.SnackbarDisplayType.BLUE;
EventBus.getDefault().post(event);
if (apiClient != null) {
// @TODO: This should be handled somewhere else? MAybe we notifiy via event
apiClient.readNotification(notification.getId())
.subscribe(next -> {}, RxErrorHandler.handleEmptyError());
}
}
return true;
}
public Boolean showNotificationDialog(final List<Notification> notifications) {
if (notifications == null || notifications.size() == 0) {
return false;
}
if (this.seenNotifications == null) {
this.seenNotifications = new HashMap<>();
}
for (Notification notification : notifications) {
if (this.seenNotifications.get(notification.getId()) != null) {
continue;
}
if (!notification.getType().equals("LOGIN_INCENTIVE")) {
continue;
}
this.displayNotification(notification);
this.seenNotifications.put(notification.getId(), true);
}
return true;
}
}

View file

@ -0,0 +1,72 @@
package com.habitrpg.android.habitica.helpers
import android.content.Context
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.events.ShowCheckinDialog
import com.habitrpg.android.habitica.events.ShowSnackbarEvent
import com.habitrpg.android.habitica.models.Notification
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import io.reactivex.functions.Consumer
import org.greenrobot.eventbus.EventBus
import java.util.*
/**
* Created by krh12 on 12/9/2016.
*/
class PopupNotificationsManager(private val context: Context) {
private var seenNotifications: MutableMap<String, Boolean>? = null
private var apiClient: ApiClient? = null
init {
this.seenNotifications = HashMap()
}
fun setApiClient(apiClient: ApiClient?) {
this.apiClient = apiClient
}
private fun displayNotification(notification: Notification): Boolean? {
val nextUnlockText = context.getString(R.string.nextPrizeUnlocks, notification.data.nextRewardAt)
if (notification.data.rewardKey != null) {
val event = ShowCheckinDialog()
event.notification = notification
event.nextUnlockText = nextUnlockText
EventBus.getDefault().post(event)
} else {
val event = ShowSnackbarEvent()
event.title = notification.data.message
event.text = nextUnlockText
event.type = HabiticaSnackbar.SnackbarDisplayType.BLUE
EventBus.getDefault().post(event)
apiClient?.readNotification(notification.id)?.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
return true
}
fun showNotificationDialog(notifications: List<Notification>?): Boolean? {
if (notifications == null || notifications.isEmpty()) {
return false
}
if (this.seenNotifications == null) {
this.seenNotifications = HashMap()
}
for (notification in notifications) {
if (this.seenNotifications?.get(notification.id) != null) {
continue
}
if (notification.type != "LOGIN_INCENTIVE") {
continue
}
this.displayNotification(notification)
this.seenNotifications?.put(notification.id, true)
}
return true
}
}

View file

@ -1,47 +0,0 @@
package com.habitrpg.android.habitica.helpers;
import android.util.Log;
import com.habitrpg.android.habitica.BuildConfig;
import com.habitrpg.android.habitica.proxy.CrashlyticsProxy;
import java.io.EOFException;
import java.io.IOException;
import io.reactivex.functions.Consumer;
import okhttp3.internal.http2.ConnectionShutdownException;
import retrofit2.HttpException;
public class RxErrorHandler {
static private RxErrorHandler instance;
private CrashlyticsProxy crashlyticsProxy;
public static void init(CrashlyticsProxy crashlyticsProxy) {
instance = new RxErrorHandler();
instance.crashlyticsProxy = crashlyticsProxy;
//RxJavaHooks.setOnError(handleEmptyError());
}
public static Consumer<Throwable> handleEmptyError() {
//Can't be turned into a lambda, because it then doesn't work for some reason.
return RxErrorHandler::reportError;
}
public static void reportError(Throwable throwable) {
if (BuildConfig.DEBUG) {
try {
Log.e("ObservableError", Log.getStackTraceString(throwable));
} catch (Exception ignored) {}
} else {
if (!IOException.class.isAssignableFrom(throwable.getClass())
&& !HttpException.class.isAssignableFrom(throwable.getClass())
&& !retrofit2.HttpException.class.isAssignableFrom(throwable.getClass())
&& !EOFException.class.isAssignableFrom(throwable.getClass())
&& !ConnectionShutdownException.class.isAssignableFrom(throwable.getClass())) {
instance.crashlyticsProxy.logException(throwable);
}
}
}
}

View file

@ -0,0 +1,47 @@
package com.habitrpg.android.habitica.helpers
import android.util.Log
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.proxy.CrashlyticsProxy
import io.reactivex.functions.Consumer
import okhttp3.internal.http2.ConnectionShutdownException
import retrofit2.HttpException
import java.io.EOFException
import java.io.IOException
class RxErrorHandler {
private var crashlyticsProxy: CrashlyticsProxy? = null
companion object {
private var instance: RxErrorHandler? = null
fun init(crashlyticsProxy: CrashlyticsProxy) {
instance = RxErrorHandler()
instance?.crashlyticsProxy = crashlyticsProxy
}
fun handleEmptyError(): Consumer<Throwable> {
//Can't be turned into a lambda, because it then doesn't work for some reason.
return Consumer { reportError(it) }
}
fun reportError(throwable: Throwable) {
if (BuildConfig.DEBUG) {
try {
Log.e("ObservableError", Log.getStackTraceString(throwable))
} catch (ignored: Exception) {
}
} else {
if (!IOException::class.java.isAssignableFrom(throwable.javaClass)
&& !HttpException::class.java.isAssignableFrom(throwable.javaClass)
&& !retrofit2.HttpException::class.java.isAssignableFrom(throwable.javaClass)
&& !EOFException::class.java.isAssignableFrom(throwable.javaClass)
&& throwable !is ConnectionShutdownException) {
instance?.crashlyticsProxy?.logException(throwable)
}
}
}
}
}

View file

@ -1,87 +0,0 @@
package com.habitrpg.android.habitica.receivers;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import com.habitrpg.android.habitica.HabiticaBaseApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.data.ApiClient;
import com.habitrpg.android.habitica.data.SocialRepository;
import com.habitrpg.android.habitica.data.UserRepository;
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
import com.habitrpg.android.habitica.models.user.User;
import java.util.Objects;
import javax.inject.Inject;
public class LocalNotificationActionReceiver extends BroadcastReceiver {
@Inject
public UserRepository userRepository;
@Inject
public SocialRepository socialRepository;
@Inject
ApiClient apiClient;
private User user;
private String action;
private Resources resources;
private Intent intent;
private Context context;
@Override
public void onReceive(Context context, Intent intent) {
Objects.requireNonNull(HabiticaBaseApplication.Companion.getComponent()).inject(this);
this.resources = context.getResources();
this.action = intent.getAction();
this.intent = intent;
this.context = context;
this.userRepository.getUser().firstElement().subscribe(this::onUserReceived, RxErrorHandler.handleEmptyError());
}
public void onUserReceived(User user) {
this.user = user;
this.handleLocalNotificationAction(action);
userRepository.close();
}
private void handleLocalNotificationAction(String action) {
NotificationManager notificationManager = (NotificationManager) this.context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
//@TODO: This is a good place for a factory and event emitter pattern
if (action.equals(this.resources.getString(R.string.accept_party_invite))) {
if (this.user.getInvitations().getParty() == null) return;
String partyId = this.user.getInvitations().getParty().getId();
socialRepository.joinGroup(partyId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
} else if (action.equals(this.resources.getString(R.string.reject_party_invite))) {
if (this.user.getInvitations().getParty() == null) return;
String partyId = this.user.getInvitations().getParty().getId();
socialRepository.rejectGroupInvite(partyId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
} else if (action.equals(this.resources.getString(R.string.accept_quest_invite))) {
if (this.user.getParty() == null) return;
String partyId = this.user.getParty().getId();
socialRepository.acceptQuest(user, partyId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
} else if (action.equals(this.resources.getString(R.string.reject_quest_invite))) {
if (this.user.getParty() == null) return;
String partyId = this.user.getParty().getId();
socialRepository.rejectQuest(user, partyId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
} else if (action.equals(this.resources.getString(R.string.accept_guild_invite))) {
Bundle extras = this.intent.getExtras();
String guildId = extras.getString("groupID");
if (guildId == null) return;
socialRepository.joinGroup(guildId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
} else if (action.equals(this.resources.getString(R.string.reject_guild_invite))) {
Bundle extras = this.intent.getExtras();
String guildId = extras.getString("groupID");
if (guildId == null) return;
socialRepository.rejectGroupInvite(guildId).subscribe(aVoid -> {}, RxErrorHandler.handleEmptyError());
}
}
}

View file

@ -0,0 +1,81 @@
package com.habitrpg.android.habitica.receivers
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.user.User
import io.reactivex.functions.Consumer
import javax.inject.Inject
class LocalNotificationActionReceiver : BroadcastReceiver() {
@Inject
lateinit var userRepository: UserRepository
@Inject
lateinit var socialRepository: SocialRepository
@Inject
lateinit var apiClient: ApiClient
private var user: User? = null
private var action: String? = null
private var resources: Resources? = null
private var intent: Intent? = null
private var context: Context? = null
override fun onReceive(context: Context, intent: Intent) {
HabiticaBaseApplication.component?.inject(this)
this.resources = context.resources
this.action = intent.action
this.intent = intent
this.context = context
this.userRepository.getUser().firstElement().subscribe(Consumer { this.onUserReceived(it) }, RxErrorHandler.handleEmptyError())
}
fun onUserReceived(user: User) {
this.user = user
this.handleLocalNotificationAction(action)
userRepository.close()
}
private fun handleLocalNotificationAction(action: String?) {
val notificationManager = this.context?.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
notificationManager?.cancelAll()
//@TODO: This is a good place for a factory and event emitter pattern
when (action) {
this.resources?.getString(R.string.accept_party_invite) -> {
val partyID = this.user?.invitations?.party?.id ?: return
socialRepository.joinGroup(partyID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
this.resources?.getString(R.string.reject_party_invite) -> {
val partyID = this.user?.invitations?.party?.id ?: return
socialRepository.rejectGroupInvite(partyID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
this.resources?.getString(R.string.accept_quest_invite) -> {
val partyID = this.user?.party?.id ?: return
socialRepository.acceptQuest(user, partyID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
this.resources?.getString(R.string.reject_quest_invite) -> {
val partyID = this.user?.party?.id ?: return
socialRepository.rejectQuest(user, partyID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
this.resources?.getString(R.string.accept_guild_invite) -> {
val guildID = intent?.extras?.getString("groupID") ?: return
socialRepository.joinGroup(guildID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
this.resources?.getString(R.string.reject_guild_invite) -> {
val guildID = intent?.extras?.getString("groupID") ?: return
socialRepository.rejectGroupInvite(guildID).subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
}
}
}
}

View file

@ -1,28 +0,0 @@
package com.habitrpg.android.habitica.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
import java.util.Objects;
import javax.inject.Inject;
public class TaskAlarmBootReceiver extends BroadcastReceiver {
@Inject
TaskAlarmManager taskAlarmManager;
@Inject
SharedPreferences sharedPreferences;
@Override
public void onReceive(Context context, Intent arg1) {
Objects.requireNonNull(HabiticaApplication.Companion.getComponent()).inject(this);
taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false));
}
}

View file

@ -0,0 +1,23 @@
package com.habitrpg.android.habitica.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
import javax.inject.Inject
class TaskAlarmBootReceiver : BroadcastReceiver() {
@Inject
lateinit var taskAlarmManager: TaskAlarmManager
@Inject
lateinit var sharedPreferences: SharedPreferences
override fun onReceive(context: Context, arg1: Intent) {
HabiticaBaseApplication.component?.inject(this)
taskAlarmManager.scheduleAllSavedAlarms(sharedPreferences.getBoolean("preventDailyReminder", false))
}
}

View file

@ -7,10 +7,11 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.view.View;
import android.widget.RemoteViews;
import androidx.annotation.NonNull;
import com.habitrpg.android.habitica.HabiticaBaseApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.data.UserRepository;
@ -58,7 +59,7 @@ public class AvatarStatsWidgetProvider extends BaseWidgetProvider {
this.appWidgetManager = appWidgetManager;
this.setContext(context);
userRepository.getUser(userId).firstElement().subscribe(this::updateData, RxErrorHandler.handleEmptyError());
userRepository.getUser(userId).firstElement().subscribe(this::updateData, RxErrorHandler.Companion.handleEmptyError());
}
@NonNull

View file

@ -6,30 +6,21 @@ import android.appwidget.AppWidgetProvider
import android.content.Context
import android.os.Build
import android.os.Bundle
import androidx.core.util.Pair
import android.text.SpannableStringBuilder
import android.widget.RemoteViews
import android.widget.Toast
import com.habitrpg.android.habitica.HabiticaApplication
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.components.AppComponent
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.helpers.AmplitudeManager
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
import com.habitrpg.android.habitica.models.responses.TaskScoringResult
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import java.util.HashMap
import java.util.Objects
import java.util.*
import javax.inject.Inject
abstract class BaseWidgetProvider : AppWidgetProvider() {
@Inject
lateinit var userRepository: UserRepository
var userRepository: UserRepository? = null
protected var context: Context? = null
@ -48,7 +39,6 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
return n - 1
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) {
this.context = context
val options = appWidgetManager.getAppWidgetOptions(appWidgetId)
@ -61,8 +51,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
fun sizeRemoteViews(context: Context, options: Bundle, widgetId: Int): RemoteViews {
fun sizeRemoteViews(context: Context?, options: Bundle, widgetId: Int): RemoteViews {
this.context = context
val minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val minHeight = options

View file

@ -83,7 +83,7 @@ public class HabitButtonWidgetProvider extends BaseWidgetProvider {
if (taskId != null) {
getUserRepository().getUser(userId).firstElement().flatMap(user -> taskRepository.taskChecked(user, taskId, TaskDirection.UP.getText().equals(direction), false, null))
.subscribe(taskDirectionData -> showToastForTaskDirection(context, taskDirectionData, userId), RxErrorHandler.handleEmptyError(), () -> this.onUpdate(context, mgr, ids));
.subscribe(taskDirectionData -> showToastForTaskDirection(context, taskDirectionData, userId), RxErrorHandler.Companion.handleEmptyError(), () -> this.onUpdate(context, mgr, ids));
}
}
super.onReceive(context, intent);

View file

@ -59,7 +59,7 @@ public class HabitButtonWidgetService extends Service {
makeTaskMapping();
for (String taskid : this.taskMapping.keySet()) {
taskRepository.getUnmanagedTask(taskid).firstElement().subscribe(this::updateData, RxErrorHandler.handleEmptyError());
taskRepository.getUnmanagedTask(taskid).firstElement().subscribe(this::updateData, RxErrorHandler.Companion.handleEmptyError());
}
stopSelf();

View file

@ -75,7 +75,7 @@ public abstract class TaskListFactory implements RemoteViewsService.RemoteViewsF
reloadData = false;
taskList = tasks;
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(widgetId, R.id.list_view);
}, RxErrorHandler.handleEmptyError()));
}, RxErrorHandler.Companion.handleEmptyError()));
}

View file

@ -62,7 +62,7 @@ public abstract class TaskListWidgetProvider extends BaseWidgetProvider {
taskRepository.markTaskCompleted(taskId, true);
showToastForTaskDirection(context, taskDirectionData, userId);
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view);
}, RxErrorHandler.handleEmptyError());
}, RxErrorHandler.Companion.handleEmptyError());
}
}
super.onReceive(context, intent);