diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml
index aa7037eb5..4bc8fd300 100644
--- a/Habitica/AndroidManifest.xml
+++ b/Habitica/AndroidManifest.xml
@@ -64,6 +64,13 @@
android:pathPattern="/settings/.*"/>
+
+
-
+ android:color="@color/brand_400" />
\ No newline at end of file
diff --git a/Habitica/res/drawable/badge_gray.xml b/Habitica/res/drawable/badge_gray.xml
new file mode 100644
index 000000000..206ef9eac
--- /dev/null
+++ b/Habitica/res/drawable/badge_gray.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/layout/activity_notifications.xml b/Habitica/res/layout/activity_notifications.xml
new file mode 100644
index 000000000..1f3f7e3bc
--- /dev/null
+++ b/Habitica/res/layout/activity_notifications.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Habitica/res/layout/drawer_main.xml b/Habitica/res/layout/drawer_main.xml
index 0dac86e80..d718d1a0b 100644
--- a/Habitica/res/layout/drawer_main.xml
+++ b/Habitica/res/layout/drawer_main.xml
@@ -12,7 +12,7 @@
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingLeft="16dp"
- android:paddingRight="16dp"
+ android:paddingRight="1dp"
android:layout_marginTop="16dp"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -58,10 +58,42 @@
+
+
+
+
+
+
+ tools:text="1"
+ tools:visibility="visible" />
+
+ tools:text="1"
+ tools:visibility="visible" />
diff --git a/Habitica/res/layout/no_notifications.xml b/Habitica/res/layout/no_notifications.xml
new file mode 100644
index 000000000..56b4de376
--- /dev/null
+++ b/Habitica/res/layout/no_notifications.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Habitica/res/layout/notification_item.xml b/Habitica/res/layout/notification_item.xml
new file mode 100644
index 000000000..26a6827df
--- /dev/null
+++ b/Habitica/res/layout/notification_item.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Habitica/res/layout/notifications_header.xml b/Habitica/res/layout/notifications_header.xml
new file mode 100644
index 000000000..e060a4296
--- /dev/null
+++ b/Habitica/res/layout/notifications_header.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Habitica/res/navigation/navigation.xml b/Habitica/res/navigation/navigation.xml
index 871c95d1a..b95ed891c 100644
--- a/Habitica/res/navigation/navigation.xml
+++ b/Habitica/res/navigation/navigation.xml
@@ -210,6 +210,11 @@
app:argType="string"
app:nullable="true" />
+
+
Open Settings
It seems like you have the Developer option \“Don\'t keep Activities\” active. Currently this option causes issues with the habitica app, so we suggest disabling it.
Messages
+ Notifications
Frequently Asked Questions
Special
Because you subscribe to Habitica, you can purchase a number of Gems each month using Gold.
@@ -858,6 +859,14 @@
Discover
Damage paused
Important Announcements
+ You’re all caught up!
+ The notification fairies give you a raucous round of applause! Well done!
+ Dismiss All
+ New Bailey Update!
+ %1$s has new posts]]>
+ %1$s, has new posts]]>
+ %1$s unallocated Stat Points]]>
+ Mystery Items]]>
Create
Only leader can create Challenges
Create Party
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java
index 76e26c9f3..70f8e0b76 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.java
@@ -348,6 +348,12 @@ public interface ApiService {
@POST("notifications/{notificationId}/read")
Flowable> readNotification(@Path("notificationId") String notificationId);
+ @POST("notifications/read")
+ Flowable> readNotifications(@Body Map> notificationIds);
+
+ @POST("notifications/see")
+ Flowable> seeNotifications(@Body Map> notificationIds);
+
@POST("user/open-mystery-item")
Flowable> openMysteryItem();
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java b/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java
index ecd3f19c1..e04e2a582 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java
@@ -6,6 +6,7 @@ import com.google.gson.reflect.TypeToken;
import com.habitrpg.android.habitica.models.Achievement;
import com.habitrpg.android.habitica.models.ContentResult;
import com.habitrpg.android.habitica.models.FAQArticle;
+import com.habitrpg.android.habitica.models.Notification;
import com.habitrpg.android.habitica.models.Skill;
import com.habitrpg.android.habitica.models.Tag;
import com.habitrpg.android.habitica.models.TutorialStep;
@@ -45,6 +46,7 @@ import com.habitrpg.android.habitica.utils.GroupSerialization;
import com.habitrpg.android.habitica.utils.MemberSerialization;
import com.habitrpg.android.habitica.utils.OwnedItemListDeserializer;
import com.habitrpg.android.habitica.utils.OwnedMountListDeserializer;
+import com.habitrpg.android.habitica.utils.NotificationDeserializer;
import com.habitrpg.android.habitica.utils.OwnedPetListDeserializer;
import com.habitrpg.android.habitica.utils.PurchasedDeserializer;
import com.habitrpg.android.habitica.utils.QuestCollectDeserializer;
@@ -118,6 +120,7 @@ public class GSonFactoryCreator {
.registerTypeAdapter(Member.class, new MemberSerialization())
.registerTypeAdapter(WorldState.class, new WorldStateSerialization())
.registerTypeAdapter(FindUsernameResult.class, new FindUsernameResultDeserializer())
+ .registerTypeAdapter(Notification.class, new NotificationDeserializer())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.create();
return GsonConverterFactory.create(gson);
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java
index 66e2d26e6..26da966de 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/AppComponent.java
@@ -27,6 +27,7 @@ import com.habitrpg.android.habitica.ui.activities.IntroActivity;
import com.habitrpg.android.habitica.ui.activities.LoginActivity;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import com.habitrpg.android.habitica.ui.activities.MaintenanceActivity;
+import com.habitrpg.android.habitica.ui.activities.NotificationsActivity;
import com.habitrpg.android.habitica.ui.activities.GroupInviteActivity;
import com.habitrpg.android.habitica.ui.activities.PrefsActivity;
import com.habitrpg.android.habitica.ui.activities.ReportMessageActivity;
@@ -94,6 +95,7 @@ import com.habitrpg.android.habitica.ui.fragments.social.party.PartyMemberListFr
import com.habitrpg.android.habitica.ui.fragments.tasks.TaskRecyclerViewFragment;
import com.habitrpg.android.habitica.ui.fragments.tasks.TasksFragment;
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel;
+import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel;
import com.habitrpg.android.habitica.ui.views.social.ChatBarView;
import com.habitrpg.android.habitica.ui.views.stats.BulkAllocateStatsDialog;
import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog;
@@ -134,6 +136,8 @@ public interface AppComponent {
void inject(PrefsActivity prefsActivity);
+ void inject(NotificationsActivity notificationsActivity);
+
void inject(SetupActivity setupActivity);
void inject(SkillTasksActivity skillTasksActivity);
@@ -302,6 +306,8 @@ public interface AppComponent {
void inject(@NotNull GroupViewModel viewModel);
+ void inject(@NotNull NotificationsViewModel viewModel);
+
void inject(@NotNull ChatFragment chatFragment);
void inject(@NotNull GiftIAPActivity giftIAPActivity);
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
index ecccbde42..6b5c2bc04 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt
@@ -212,6 +212,8 @@ interface ApiClient {
// Notifications
fun readNotification(notificationId: String): Flowable>
+ fun readNotifications(notificationIds: Map>): Flowable>
+ fun seeNotifications(notificationIds: Map>): Flowable>
fun getErrorResponse(throwable: HttpException): ErrorResponse
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
index b25ae6b31..3de37b1ea 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
@@ -52,6 +52,8 @@ interface UserRepository : BaseRepository {
fun runCron()
fun readNotification(id: String): Flowable>
+ fun readNotifications(notificationIds: Map>): Flowable>
+ fun seeNotifications(notificationIds: Map>): Flowable>
fun changeCustomDayStart(dayStartTime: Int): Flowable
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
index 25154888f..298744c28 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt
@@ -1,113 +1,113 @@
-package com.habitrpg.android.habitica.data.implementation
-
-import android.content.Context
-import android.util.Log
-import androidx.appcompat.app.AlertDialog
-import com.amplitude.api.Amplitude
-import com.google.gson.JsonSyntaxException
-import com.habitrpg.android.habitica.BuildConfig
-import com.habitrpg.android.habitica.HabiticaBaseApplication
-import com.habitrpg.android.habitica.R
-import com.habitrpg.android.habitica.api.ApiService
-import com.habitrpg.android.habitica.api.GSonFactoryCreator
-import com.habitrpg.android.habitica.api.HostConfig
-import com.habitrpg.android.habitica.api.Server
-import com.habitrpg.android.habitica.data.ApiClient
-import com.habitrpg.android.habitica.events.ShowConnectionProblemEvent
-import com.habitrpg.android.habitica.helpers.PopupNotificationsManager
-import com.habitrpg.android.habitica.models.*
-import com.habitrpg.android.habitica.models.auth.UserAuth
-import com.habitrpg.android.habitica.models.auth.UserAuthResponse
-import com.habitrpg.android.habitica.models.auth.UserAuthSocial
-import com.habitrpg.android.habitica.models.auth.UserAuthSocialTokens
-import com.habitrpg.android.habitica.models.inventory.Equipment
-import com.habitrpg.android.habitica.models.inventory.Quest
-import com.habitrpg.android.habitica.models.members.Member
-import com.habitrpg.android.habitica.models.responses.*
-import com.habitrpg.android.habitica.models.shops.Shop
-import com.habitrpg.android.habitica.models.shops.ShopItem
-import com.habitrpg.android.habitica.models.social.Challenge
-import com.habitrpg.android.habitica.models.social.ChatMessage
-import com.habitrpg.android.habitica.models.social.FindUsernameResult
-import com.habitrpg.android.habitica.models.social.Group
-import com.habitrpg.android.habitica.models.tasks.Task
-import com.habitrpg.android.habitica.models.tasks.TaskList
-import com.habitrpg.android.habitica.models.user.Items
-import com.habitrpg.android.habitica.models.user.Stats
-import com.habitrpg.android.habitica.models.user.User
-import com.habitrpg.android.habitica.proxy.CrashlyticsProxy
-import io.reactivex.Flowable
-import io.reactivex.FlowableTransformer
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.functions.BiFunction
-import io.reactivex.functions.Consumer
-import io.reactivex.schedulers.Schedulers
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.logging.HttpLoggingInterceptor
-import org.greenrobot.eventbus.EventBus
-import retrofit2.HttpException
-import retrofit2.Retrofit
-import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
-import retrofit2.converter.gson.GsonConverterFactory
-import java.io.IOException
-import java.net.SocketException
-import java.net.SocketTimeoutException
-import java.net.UnknownHostException
-import java.util.*
-import java.util.concurrent.TimeUnit
-import javax.net.ssl.SSLException
-
-
-class ApiClientImpl//private OnHabitsAPIResult mResultListener;
-//private HostConfig mConfig;
-(private val gsonConverter: GsonConverterFactory, override val hostConfig: HostConfig, private val crashlyticsProxy: CrashlyticsProxy, private val popupNotificationsManager: PopupNotificationsManager, private val context: Context) : Consumer, ApiClient {
-
-
- private lateinit var retrofitAdapter: Retrofit
-
- // I think we don't need the ApiClientImpl anymore we could just use ApiService
- private lateinit var apiService: ApiService
-
- private val apiCallTransformer = FlowableTransformer, Any> { observable ->
- observable
- .filter { it.data != null }
- .map { habitResponse ->
- if (habitResponse.notifications != null) {
- popupNotificationsManager.showNotificationDialog(habitResponse.notifications)
- }
- habitResponse.data
- }
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnError(this)
- }
- private val displayedAlert: AlertDialog? = null
- private var languageCode: String? = null
- private var lastAPICallURL: String? = null
-
- init {
- this.popupNotificationsManager.setApiClient(this)
-
+package com.habitrpg.android.habitica.data.implementation
+
+import android.content.Context
+import android.util.Log
+import androidx.appcompat.app.AlertDialog
+import com.amplitude.api.Amplitude
+import com.google.gson.JsonSyntaxException
+import com.habitrpg.android.habitica.BuildConfig
+import com.habitrpg.android.habitica.HabiticaBaseApplication
+import com.habitrpg.android.habitica.R
+import com.habitrpg.android.habitica.api.ApiService
+import com.habitrpg.android.habitica.api.GSonFactoryCreator
+import com.habitrpg.android.habitica.api.HostConfig
+import com.habitrpg.android.habitica.api.Server
+import com.habitrpg.android.habitica.data.ApiClient
+import com.habitrpg.android.habitica.events.ShowConnectionProblemEvent
+import com.habitrpg.android.habitica.helpers.NotificationsManager
+import com.habitrpg.android.habitica.models.*
+import com.habitrpg.android.habitica.models.auth.UserAuth
+import com.habitrpg.android.habitica.models.auth.UserAuthResponse
+import com.habitrpg.android.habitica.models.auth.UserAuthSocial
+import com.habitrpg.android.habitica.models.auth.UserAuthSocialTokens
+import com.habitrpg.android.habitica.models.inventory.Equipment
+import com.habitrpg.android.habitica.models.inventory.Quest
+import com.habitrpg.android.habitica.models.members.Member
+import com.habitrpg.android.habitica.models.responses.*
+import com.habitrpg.android.habitica.models.shops.Shop
+import com.habitrpg.android.habitica.models.shops.ShopItem
+import com.habitrpg.android.habitica.models.social.Challenge
+import com.habitrpg.android.habitica.models.social.ChatMessage
+import com.habitrpg.android.habitica.models.social.FindUsernameResult
+import com.habitrpg.android.habitica.models.social.Group
+import com.habitrpg.android.habitica.models.tasks.Task
+import com.habitrpg.android.habitica.models.tasks.TaskList
+import com.habitrpg.android.habitica.models.user.Items
+import com.habitrpg.android.habitica.models.user.Stats
+import com.habitrpg.android.habitica.models.user.User
+import com.habitrpg.android.habitica.proxy.CrashlyticsProxy
+import io.reactivex.Flowable
+import io.reactivex.FlowableTransformer
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.functions.BiFunction
+import io.reactivex.functions.Consumer
+import io.reactivex.schedulers.Schedulers
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.logging.HttpLoggingInterceptor
+import org.greenrobot.eventbus.EventBus
+import retrofit2.HttpException
+import retrofit2.Retrofit
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+import retrofit2.converter.gson.GsonConverterFactory
+import java.io.IOException
+import java.net.SocketException
+import java.net.SocketTimeoutException
+import java.net.UnknownHostException
+import java.util.*
+import java.util.concurrent.TimeUnit
+import javax.net.ssl.SSLException
+
+
+class ApiClientImpl//private OnHabitsAPIResult mResultListener;
+//private HostConfig mConfig;
+(private val gsonConverter: GsonConverterFactory, override val hostConfig: HostConfig, private val crashlyticsProxy: CrashlyticsProxy, private val notificationsManager: NotificationsManager, private val context: Context) : Consumer, ApiClient {
+
+
+ private lateinit var retrofitAdapter: Retrofit
+
+ // I think we don't need the ApiClientImpl anymore we could just use ApiService
+ private lateinit var apiService: ApiService
+
+ private val apiCallTransformer = FlowableTransformer, Any> { observable ->
+ observable
+ .filter { it.data != null }
+ .map { habitResponse ->
+ if (habitResponse.notifications != null) {
+ notificationsManager.setNotifications(habitResponse.notifications)
+ }
+ habitResponse.data
+ }
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnError(this)
+ }
+ private val displayedAlert: AlertDialog? = null
+ private var languageCode: String? = null
+ private var lastAPICallURL: String? = null
+
+ init {
+ this.notificationsManager.setApiClient(this)
+
HabiticaBaseApplication.component?.inject(this)
crashlyticsProxy.setUserIdentifier(this.hostConfig.userID)
crashlyticsProxy.setUserName(this.hostConfig.userID)
Amplitude.getInstance().userId = this.hostConfig.userID
buildRetrofit()
}
-
- fun buildRetrofit() {
- val logging = HttpLoggingInterceptor()
- if (BuildConfig.DEBUG) {
- logging.level = HttpLoggingInterceptor.Level.BODY
- }
-
- val userAgent = System.getProperty("http.agent")
-
- val calendar = GregorianCalendar()
- val timeZone = calendar.timeZone
- val timezoneOffset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
-
+
+ fun buildRetrofit() {
+ val logging = HttpLoggingInterceptor()
+ if (BuildConfig.DEBUG) {
+ logging.level = HttpLoggingInterceptor.Level.BODY
+ }
+
+ val userAgent = System.getProperty("http.agent")
+
+ val calendar = GregorianCalendar()
+ val timeZone = calendar.timeZone
+ val timezoneOffset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
+
val client = OkHttpClient.Builder()
.addInterceptor(logging)
.addNetworkInterceptor { chain ->
@@ -134,153 +134,153 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
}
.readTimeout(2400, TimeUnit.SECONDS)
.build()
-
- val server = Server(this.hostConfig.address)
-
- retrofitAdapter = Retrofit.Builder()
- .client(client)
- .baseUrl(server.toString())
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .addConverterFactory(gsonConverter)
- .build()
-
- this.apiService = retrofitAdapter.create(ApiService::class.java)
- }
-
- override fun updateServerUrl(newAddress: String?) {
- if (newAddress != null) {
- hostConfig.address = newAddress
- buildRetrofit()
- }
- }
-
- override fun registerUser(username: String, email: String, password: String, confirmPassword: String): Flowable {
- val auth = UserAuth()
- auth.username = username
- auth.password = password
- auth.confirmPassword = confirmPassword
- auth.email = email
- return this.apiService.registerUser(auth).compose(configureApiCallObserver())
- }
-
- override fun connectUser(username: String, password: String): Flowable {
- val auth = UserAuth()
- auth.username = username
- auth.password = password
- return this.apiService.connectLocal(auth).compose(configureApiCallObserver())
- }
-
- override fun connectSocial(network: String, userId: String, accessToken: String): Flowable {
- val auth = UserAuthSocial()
- auth.network = network
- val authResponse = UserAuthSocialTokens()
- authResponse.client_id = userId
- authResponse.access_token = accessToken
- auth.authResponse = authResponse
-
- return this.apiService.connectSocial(auth).compose(configureApiCallObserver())
- }
-
- override fun accept(throwable: Throwable) {
- val throwableClass = throwable.javaClass
- if (SocketTimeoutException::class.java.isAssignableFrom(throwableClass)) {
- return
- }
- @Suppress("DEPRECATION")
- if (SocketException::class.java.isAssignableFrom(throwableClass) || SSLException::class.java.isAssignableFrom(throwableClass)) {
- this.showConnectionProblemDialog(R.string.internal_error_api)
- } else if (throwableClass == SocketTimeoutException::class.java || UnknownHostException::class.java == throwableClass) {
- this.showConnectionProblemDialog(R.string.network_error_no_network_body)
- } else if (throwableClass == retrofit2.adapter.rxjava2.HttpException::class.java) {
- val error = throwable as HttpException
- val res = getErrorResponse(error)
- val status = error.code()
-
- if (error.response().raw().request().url().toString().endsWith("/user/push-devices")) {
- //workaround for an error that sometimes displays that the user already has this push device
- return
- }
-
- if (status == 404) {
- return
- }
-
- if (status in 400..499) {
- if (res.displayMessage.isNotEmpty()) {
- showConnectionProblemDialog("", res.displayMessage)
- } else if (status == 401) {
- showConnectionProblemDialog(R.string.authentication_error_title, R.string.authentication_error_body)
- }
- } else if (status in 500..599) {
- this.showConnectionProblemDialog(R.string.internal_error_api)
- } else {
- showConnectionProblemDialog(R.string.internal_error_api)
- }
- } else if (JsonSyntaxException::class.java.isAssignableFrom(throwableClass)) {
- crashlyticsProxy.log("Json Error: " + lastAPICallURL + ", " + throwable.message)
- } else {
- crashlyticsProxy.logException(throwable)
- }
- }
-
- override fun getErrorResponse(throwable: HttpException): ErrorResponse {
- val errorResponse = throwable.response().errorBody() ?: return ErrorResponse()
- val errorConverter = gsonConverter
- .responseBodyConverter(ErrorResponse::class.java, arrayOfNulls(0), retrofitAdapter)
- return try {
- errorConverter?.convert(errorResponse) as ErrorResponse
- } catch (e: IOException) {
- ErrorResponse()
- }
-
- }
-
- override fun retrieveUser(withTasks: Boolean): Flowable {
-
- var userObservable = this.user
-
- if (withTasks) {
- val tasksObservable = this.tasks
-
- userObservable = Flowable.zip(userObservable, tasksObservable,
- BiFunction { habitRPGUser, tasks ->
- habitRPGUser.tasks = tasks
- habitRPGUser
- })
- }
- return userObservable
- }
-
- override fun retrieveInboxMessages(): Flowable> {
- return apiService.inboxMessages.compose(configureApiCallObserver())
- }
-
+
+ val server = Server(this.hostConfig.address)
+
+ retrofitAdapter = Retrofit.Builder()
+ .client(client)
+ .baseUrl(server.toString())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .addConverterFactory(gsonConverter)
+ .build()
+
+ this.apiService = retrofitAdapter.create(ApiService::class.java)
+ }
+
+ override fun updateServerUrl(newAddress: String?) {
+ if (newAddress != null) {
+ hostConfig.address = newAddress
+ buildRetrofit()
+ }
+ }
+
+ override fun registerUser(username: String, email: String, password: String, confirmPassword: String): Flowable {
+ val auth = UserAuth()
+ auth.username = username
+ auth.password = password
+ auth.confirmPassword = confirmPassword
+ auth.email = email
+ return this.apiService.registerUser(auth).compose(configureApiCallObserver())
+ }
+
+ override fun connectUser(username: String, password: String): Flowable {
+ val auth = UserAuth()
+ auth.username = username
+ auth.password = password
+ return this.apiService.connectLocal(auth).compose(configureApiCallObserver())
+ }
+
+ override fun connectSocial(network: String, userId: String, accessToken: String): Flowable {
+ val auth = UserAuthSocial()
+ auth.network = network
+ val authResponse = UserAuthSocialTokens()
+ authResponse.client_id = userId
+ authResponse.access_token = accessToken
+ auth.authResponse = authResponse
+
+ return this.apiService.connectSocial(auth).compose(configureApiCallObserver())
+ }
+
+ override fun accept(throwable: Throwable) {
+ val throwableClass = throwable.javaClass
+ if (SocketTimeoutException::class.java.isAssignableFrom(throwableClass)) {
+ return
+ }
+ @Suppress("DEPRECATION")
+ if (SocketException::class.java.isAssignableFrom(throwableClass) || SSLException::class.java.isAssignableFrom(throwableClass)) {
+ this.showConnectionProblemDialog(R.string.internal_error_api)
+ } else if (throwableClass == SocketTimeoutException::class.java || UnknownHostException::class.java == throwableClass) {
+ this.showConnectionProblemDialog(R.string.network_error_no_network_body)
+ } else if (throwableClass == retrofit2.adapter.rxjava2.HttpException::class.java) {
+ val error = throwable as HttpException
+ val res = getErrorResponse(error)
+ val status = error.code()
+
+ if (error.response().raw().request().url().toString().endsWith("/user/push-devices")) {
+ //workaround for an error that sometimes displays that the user already has this push device
+ return
+ }
+
+ if (status == 404) {
+ return
+ }
+
+ if (status in 400..499) {
+ if (res.displayMessage.isNotEmpty()) {
+ showConnectionProblemDialog("", res.displayMessage)
+ } else if (status == 401) {
+ showConnectionProblemDialog(R.string.authentication_error_title, R.string.authentication_error_body)
+ }
+ } else if (status in 500..599) {
+ this.showConnectionProblemDialog(R.string.internal_error_api)
+ } else {
+ showConnectionProblemDialog(R.string.internal_error_api)
+ }
+ } else if (JsonSyntaxException::class.java.isAssignableFrom(throwableClass)) {
+ crashlyticsProxy.log("Json Error: " + lastAPICallURL + ", " + throwable.message)
+ } else {
+ crashlyticsProxy.logException(throwable)
+ }
+ }
+
+ override fun getErrorResponse(throwable: HttpException): ErrorResponse {
+ val errorResponse = throwable.response().errorBody() ?: return ErrorResponse()
+ val errorConverter = gsonConverter
+ .responseBodyConverter(ErrorResponse::class.java, arrayOfNulls(0), retrofitAdapter)
+ return try {
+ errorConverter?.convert(errorResponse) as ErrorResponse
+ } catch (e: IOException) {
+ ErrorResponse()
+ }
+
+ }
+
+ override fun retrieveUser(withTasks: Boolean): Flowable {
+
+ var userObservable = this.user
+
+ if (withTasks) {
+ val tasksObservable = this.tasks
+
+ userObservable = Flowable.zip(userObservable, tasksObservable,
+ BiFunction { habitRPGUser, tasks ->
+ habitRPGUser.tasks = tasks
+ habitRPGUser
+ })
+ }
+ return userObservable
+ }
+
+ override fun retrieveInboxMessages(): Flowable> {
+ return apiService.inboxMessages.compose(configureApiCallObserver())
+ }
+
override fun hasAuthenticationKeys(): Boolean {
return this.hostConfig.userID.isNotEmpty() && hostConfig.apiKey.isNotEmpty()
}
-
+
private fun showConnectionProblemDialog(resourceMessageString: Int) {
showConnectionProblemDialog(null, context.getString(resourceMessageString))
}
-
- private fun showConnectionProblemDialog(resourceTitleString: Int, resourceMessageString: Int) {
- showConnectionProblemDialog(context.getString(resourceTitleString), context.getString(resourceMessageString))
- }
-
+
+ private fun showConnectionProblemDialog(resourceTitleString: Int, resourceMessageString: Int) {
+ showConnectionProblemDialog(context.getString(resourceTitleString), context.getString(resourceMessageString))
+ }
+
private fun showConnectionProblemDialog(resourceTitleString: String?, resourceMessageString: String) {
val event = ShowConnectionProblemEvent(resourceTitleString, resourceMessageString)
EventBus.getDefault().post(event)
- }
-
- /*
- This function is used with Observer.compose to reuse transformers across the application.
- See here for more info: http://blog.danlew.net/2015/03/02/dont-break-the-chain/
- */
-
- override fun configureApiCallObserver(): FlowableTransformer, T> {
- return apiCallTransformer as FlowableTransformer, T>
- }
-
+ }
+
+ /*
+ This function is used with Observer.compose to reuse transformers across the application.
+ See here for more info: http://blog.danlew.net/2015/03/02/dont-break-the-chain/
+ */
+
+ override fun configureApiCallObserver(): FlowableTransformer, T> {
+ return apiCallTransformer as FlowableTransformer, T>
+ }
+
override fun updateAuthenticationCredentials(userID: String?, apiToken: String?) {
this.hostConfig.userID = userID ?: ""
this.hostConfig.apiKey = apiToken ?: ""
@@ -288,473 +288,481 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
crashlyticsProxy.setUserName(this.hostConfig.userID)
Amplitude.getInstance().userId = this.hostConfig.userID
}
-
- override fun setLanguageCode(languageCode: String) {
- this.languageCode = languageCode
- }
-
- override val status: Flowable
- get() = apiService.status.compose(configureApiCallObserver())
-
- override fun getContent(language: String): Flowable {
- return apiService.getContent(language).compose(configureApiCallObserver())
- }
-
- override val user: Flowable
- get() = apiService.user.compose(configureApiCallObserver())
-
- override fun updateUser(updateDictionary: Map): Flowable {
- return apiService.updateUser(updateDictionary).compose(configureApiCallObserver())
- }
-
- override fun registrationLanguage(registrationLanguage: String): Flowable {
- return apiService.registrationLanguage(registrationLanguage).compose(configureApiCallObserver())
- }
-
- override fun retrieveInAppRewards(): Flowable> {
- return apiService.retrieveInAppRewards().compose(configureApiCallObserver())
- }
-
- override fun retrieveOldGear(): Flowable> {
- return apiService.retrieveOldGearRewards().compose(configureApiCallObserver())
- }
-
- override fun equipItem(type: String, itemKey: String): Flowable {
- return apiService.equipItem(type, itemKey).compose(configureApiCallObserver())
- }
-
- override fun buyItem(itemKey: String): Flowable {
- return apiService.buyItem(itemKey).compose(configureApiCallObserver())
- }
-
- override fun purchaseItem(type: String, itemKey: String): Flowable {
- return apiService.purchaseItem(type, itemKey).compose(configureApiCallObserver())
- }
-
- override fun validateSubscription(request: SubscriptionValidationRequest): Flowable {
- return apiService.validateSubscription(request).map { habitResponse ->
- if (habitResponse.notifications != null) {
- popupNotificationsManager.showNotificationDialog(habitResponse.notifications)
- }
- habitResponse.getData()
- }
- }
-
- override fun validateNoRenewSubscription(request: PurchaseValidationRequest): Flowable {
- return apiService.validateNoRenewSubscription(request).map { habitResponse ->
- if (habitResponse.notifications != null) {
- popupNotificationsManager.showNotificationDialog(habitResponse.notifications)
- }
- habitResponse.getData()
- }
- }
-
- override fun purchaseHourglassItem(type: String, itemKey: String): Flowable {
- return apiService.purchaseHourglassItem(type, itemKey).compose(configureApiCallObserver())
- }
-
- override fun purchaseMysterySet(itemKey: String): Flowable {
- return apiService.purchaseMysterySet(itemKey).compose(configureApiCallObserver())
- }
-
- override fun purchaseQuest(key: String): Flowable {
- return apiService.purchaseQuest(key).compose(configureApiCallObserver())
- }
-
- override fun sellItem(itemType: String, itemKey: String): Flowable {
- return apiService.sellItem(itemType, itemKey).compose(configureApiCallObserver())
- }
-
- override fun feedPet(petKey: String, foodKey: String): Flowable {
- return apiService.feedPet(petKey, foodKey).compose(configureApiCallObserver())
- }
-
- override fun hatchPet(eggKey: String, hatchingPotionKey: String): Flowable {
- return apiService.hatchPet(eggKey, hatchingPotionKey).compose(configureApiCallObserver())
- }
-
- override val tasks: Flowable
- get() = apiService.tasks.compose(configureApiCallObserver())
-
- override fun getTasks(type: String): Flowable {
- return apiService.getTasks(type).compose(configureApiCallObserver())
- }
-
-
- override fun getTasks(type: String, dueDate: String): Flowable {
- return apiService.getTasks(type, dueDate).compose(configureApiCallObserver())
- }
-
-
- override fun unlockPath(path: String): Flowable {
- return apiService.unlockPath(path).compose(configureApiCallObserver())
- }
-
- override fun getTask(id: String): Flowable {
- return apiService.getTask(id).compose(configureApiCallObserver())
- }
-
- override fun postTaskDirection(id: String, direction: String): Flowable {
- return apiService.postTaskDirection(id, direction).compose(configureApiCallObserver())
- }
-
- override fun postTaskNewPosition(id: String, position: Int): Flowable> {
- return apiService.postTaskNewPosition(id, position).compose(configureApiCallObserver())
- }
-
- override fun scoreChecklistItem(taskId: String, itemId: String): Flowable {
- return apiService.scoreChecklistItem(taskId, itemId).compose(configureApiCallObserver())
- }
-
- override fun createTask(item: Task): Flowable {
- return apiService.createTask(item).compose(configureApiCallObserver())
- }
-
- override fun createTasks(tasks: List): Flowable> {
- return apiService.createTasks(tasks).compose(configureApiCallObserver())
- }
-
- override fun updateTask(id: String, item: Task): Flowable {
- return apiService.updateTask(id, item).compose(configureApiCallObserver())
- }
-
- override fun deleteTask(id: String): Flowable {
- return apiService.deleteTask(id).compose(configureApiCallObserver())
- }
-
- override fun createTag(tag: Tag): Flowable {
- return apiService.createTag(tag).compose(configureApiCallObserver())
- }
-
- override fun updateTag(id: String, tag: Tag): Flowable {
- return apiService.updateTag(id, tag).compose(configureApiCallObserver())
- }
-
- override fun deleteTag(id: String): Flowable {
- return apiService.deleteTag(id).compose(configureApiCallObserver())
- }
-
- override fun sleep(): Flowable {
- return apiService.sleep().compose(configureApiCallObserver())
- }
-
- override fun revive(): Flowable {
- return apiService.revive().compose(configureApiCallObserver())
- }
-
- override fun useSkill(skillName: String, targetType: String, targetId: String): Flowable {
- return apiService.useSkill(skillName, targetType, targetId).compose(configureApiCallObserver())
- }
-
- override fun useSkill(skillName: String, targetType: String): Flowable {
- return apiService.useSkill(skillName, targetType).compose(configureApiCallObserver())
- }
-
- override fun changeClass(): Flowable {
- return apiService.changeClass().compose(configureApiCallObserver())
- }
-
- override fun changeClass(className: String): Flowable {
- return apiService.changeClass(className).compose(configureApiCallObserver())
- }
-
- override fun disableClasses(): Flowable {
- return apiService.disableClasses().compose(configureApiCallObserver())
- }
-
- override fun markPrivateMessagesRead(): Flowable {
- //This is necessary, because the API call returns weird data.
- return apiService.markPrivateMessagesRead()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .doOnError(this)
- }
-
- override fun listGroups(type: String): Flowable> {
- return apiService.listGroups(type).compose(configureApiCallObserver())
- }
-
- override fun getGroup(groupId: String): Flowable {
- return apiService.getGroup(groupId).compose(configureApiCallObserver())
- }
-
- override fun createGroup(group: Group): Flowable {
- return apiService.createGroup(group).compose(configureApiCallObserver())
- }
-
- override fun updateGroup(id: String, item: Group): Flowable {
- return apiService.updateGroup(id, item).compose(configureApiCallObserver())
- }
-
- override fun listGroupChat(groupId: String): Flowable> {
- return apiService.listGroupChat(groupId).compose(configureApiCallObserver())
- }
-
- override fun joinGroup(groupId: String): Flowable {
- return apiService.joinGroup(groupId).compose(configureApiCallObserver())
- }
-
- override fun leaveGroup(groupId: String): Flowable {
- return apiService.leaveGroup(groupId).compose(configureApiCallObserver())
- }
-
- override fun postGroupChat(groupId: String, message: Map): Flowable {
- return apiService.postGroupChat(groupId, message).compose(configureApiCallObserver())
- }
-
- override fun deleteMessage(groupId: String, messageId: String): Flowable {
- return apiService.deleteMessage(groupId, messageId).compose(configureApiCallObserver())
- }
- override fun deleteInboxMessage(id: String): Flowable {
- return apiService.deleteInboxMessage(id).compose(configureApiCallObserver())
- }
-
- override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): Flowable> {
- return apiService.getGroupMembers(groupId, includeAllPublicFields).compose(configureApiCallObserver())
- }
-
- override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): Flowable> {
- return apiService.getGroupMembers(groupId, includeAllPublicFields, lastId).compose(configureApiCallObserver())
- }
-
- override fun likeMessage(groupId: String, mid: String): Flowable {
- return apiService.likeMessage(groupId, mid).compose(configureApiCallObserver())
- }
-
- override fun flagMessage(groupId: String, mid: String, data: MutableMap): Flowable {
- return apiService.flagMessage(groupId, mid, data).compose(configureApiCallObserver())
- }
-
- override fun seenMessages(groupId: String): Flowable {
- return apiService.seenMessages(groupId).compose(configureApiCallObserver())
- }
-
- override fun inviteToGroup(groupId: String, inviteData: Map): Flowable> {
- return apiService.inviteToGroup(groupId, inviteData).compose(configureApiCallObserver())
- }
-
- override fun rejectGroupInvite(groupId: String): Flowable {
- return apiService.rejectGroupInvite(groupId).compose(configureApiCallObserver())
- }
-
- override fun acceptQuest(groupId: String): Flowable {
- return apiService.acceptQuest(groupId).compose(configureApiCallObserver())
- }
-
- override fun rejectQuest(groupId: String): Flowable {
- return apiService.rejectQuest(groupId).compose(configureApiCallObserver())
- }
-
- override fun cancelQuest(groupId: String): Flowable {
- return apiService.cancelQuest(groupId).compose(configureApiCallObserver())
- }
-
- override fun forceStartQuest(groupId: String, group: Group): Flowable {
- return apiService.forceStartQuest(groupId, group).compose(configureApiCallObserver())
- }
-
- override fun inviteToQuest(groupId: String, questKey: String): Flowable {
- return apiService.inviteToQuest(groupId, questKey).compose(configureApiCallObserver())
- }
-
- override fun abortQuest(groupId: String): Flowable {
- return apiService.abortQuest(groupId).compose(configureApiCallObserver())
- }
-
- override fun leaveQuest(groupId: String): Flowable {
- return apiService.leaveQuest(groupId).compose(configureApiCallObserver())
- }
-
- override fun validatePurchase(request: PurchaseValidationRequest): Flowable {
- return apiService.validatePurchase(request).map { habitResponse ->
- if (habitResponse.notifications != null) {
- popupNotificationsManager.showNotificationDialog(habitResponse.notifications)
- }
- habitResponse.getData()
- }
- }
-
- override fun changeCustomDayStart(updateObject: Map): Flowable {
- return apiService.changeCustomDayStart(updateObject).compose(configureApiCallObserver())
- }
-
- override fun getMember(memberId: String): Flowable {
- return apiService.getMember(memberId).compose(configureApiCallObserver())
- }
-
- override fun getMemberWithUsername(username: String): Flowable {
- return apiService.getMemberWithUsername(username).compose(configureApiCallObserver())
- }
-
+
+ override fun setLanguageCode(languageCode: String) {
+ this.languageCode = languageCode
+ }
+
+ override val status: Flowable
+ get() = apiService.status.compose(configureApiCallObserver())
+
+ override fun getContent(language: String): Flowable {
+ return apiService.getContent(language).compose(configureApiCallObserver())
+ }
+
+ override val user: Flowable
+ get() = apiService.user.compose(configureApiCallObserver())
+
+ override fun updateUser(updateDictionary: Map): Flowable {
+ return apiService.updateUser(updateDictionary).compose(configureApiCallObserver())
+ }
+
+ override fun registrationLanguage(registrationLanguage: String): Flowable {
+ return apiService.registrationLanguage(registrationLanguage).compose(configureApiCallObserver())
+ }
+
+ override fun retrieveInAppRewards(): Flowable> {
+ return apiService.retrieveInAppRewards().compose(configureApiCallObserver())
+ }
+
+ override fun retrieveOldGear(): Flowable> {
+ return apiService.retrieveOldGearRewards().compose(configureApiCallObserver())
+ }
+
+ override fun equipItem(type: String, itemKey: String): Flowable {
+ return apiService.equipItem(type, itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun buyItem(itemKey: String): Flowable {
+ return apiService.buyItem(itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun purchaseItem(type: String, itemKey: String): Flowable {
+ return apiService.purchaseItem(type, itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun validateSubscription(request: SubscriptionValidationRequest): Flowable {
+ return apiService.validateSubscription(request).map { habitResponse ->
+ if (habitResponse.notifications != null) {
+ notificationsManager.setNotifications(habitResponse.notifications)
+ }
+ habitResponse.getData()
+ }
+ }
+
+ override fun validateNoRenewSubscription(request: PurchaseValidationRequest): Flowable {
+ return apiService.validateNoRenewSubscription(request).map { habitResponse ->
+ if (habitResponse.notifications != null) {
+ notificationsManager.setNotifications(habitResponse.notifications)
+ }
+ habitResponse.getData()
+ }
+ }
+
+ override fun purchaseHourglassItem(type: String, itemKey: String): Flowable {
+ return apiService.purchaseHourglassItem(type, itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun purchaseMysterySet(itemKey: String): Flowable {
+ return apiService.purchaseMysterySet(itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun purchaseQuest(key: String): Flowable {
+ return apiService.purchaseQuest(key).compose(configureApiCallObserver())
+ }
+
+ override fun sellItem(itemType: String, itemKey: String): Flowable {
+ return apiService.sellItem(itemType, itemKey).compose(configureApiCallObserver())
+ }
+
+ override fun feedPet(petKey: String, foodKey: String): Flowable {
+ return apiService.feedPet(petKey, foodKey).compose(configureApiCallObserver())
+ }
+
+ override fun hatchPet(eggKey: String, hatchingPotionKey: String): Flowable {
+ return apiService.hatchPet(eggKey, hatchingPotionKey).compose(configureApiCallObserver())
+ }
+
+ override val tasks: Flowable
+ get() = apiService.tasks.compose(configureApiCallObserver())
+
+ override fun getTasks(type: String): Flowable {
+ return apiService.getTasks(type).compose(configureApiCallObserver())
+ }
+
+
+ override fun getTasks(type: String, dueDate: String): Flowable {
+ return apiService.getTasks(type, dueDate).compose(configureApiCallObserver())
+ }
+
+
+ override fun unlockPath(path: String): Flowable {
+ return apiService.unlockPath(path).compose(configureApiCallObserver())
+ }
+
+ override fun getTask(id: String): Flowable {
+ return apiService.getTask(id).compose(configureApiCallObserver())
+ }
+
+ override fun postTaskDirection(id: String, direction: String): Flowable {
+ return apiService.postTaskDirection(id, direction).compose(configureApiCallObserver())
+ }
+
+ override fun postTaskNewPosition(id: String, position: Int): Flowable> {
+ return apiService.postTaskNewPosition(id, position).compose(configureApiCallObserver())
+ }
+
+ override fun scoreChecklistItem(taskId: String, itemId: String): Flowable {
+ return apiService.scoreChecklistItem(taskId, itemId).compose(configureApiCallObserver())
+ }
+
+ override fun createTask(item: Task): Flowable {
+ return apiService.createTask(item).compose(configureApiCallObserver())
+ }
+
+ override fun createTasks(tasks: List): Flowable> {
+ return apiService.createTasks(tasks).compose(configureApiCallObserver())
+ }
+
+ override fun updateTask(id: String, item: Task): Flowable {
+ return apiService.updateTask(id, item).compose(configureApiCallObserver())
+ }
+
+ override fun deleteTask(id: String): Flowable {
+ return apiService.deleteTask(id).compose(configureApiCallObserver())
+ }
+
+ override fun createTag(tag: Tag): Flowable {
+ return apiService.createTag(tag).compose(configureApiCallObserver())
+ }
+
+ override fun updateTag(id: String, tag: Tag): Flowable {
+ return apiService.updateTag(id, tag).compose(configureApiCallObserver())
+ }
+
+ override fun deleteTag(id: String): Flowable {
+ return apiService.deleteTag(id).compose(configureApiCallObserver())
+ }
+
+ override fun sleep(): Flowable {
+ return apiService.sleep().compose(configureApiCallObserver())
+ }
+
+ override fun revive(): Flowable {
+ return apiService.revive().compose(configureApiCallObserver())
+ }
+
+ override fun useSkill(skillName: String, targetType: String, targetId: String): Flowable {
+ return apiService.useSkill(skillName, targetType, targetId).compose(configureApiCallObserver())
+ }
+
+ override fun useSkill(skillName: String, targetType: String): Flowable {
+ return apiService.useSkill(skillName, targetType).compose(configureApiCallObserver())
+ }
+
+ override fun changeClass(): Flowable {
+ return apiService.changeClass().compose(configureApiCallObserver())
+ }
+
+ override fun changeClass(className: String): Flowable {
+ return apiService.changeClass(className).compose(configureApiCallObserver())
+ }
+
+ override fun disableClasses(): Flowable {
+ return apiService.disableClasses().compose(configureApiCallObserver())
+ }
+
+ override fun markPrivateMessagesRead(): Flowable {
+ //This is necessary, because the API call returns weird data.
+ return apiService.markPrivateMessagesRead()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnError(this)
+ }
+
+ override fun listGroups(type: String): Flowable> {
+ return apiService.listGroups(type).compose(configureApiCallObserver())
+ }
+
+ override fun getGroup(groupId: String): Flowable {
+ return apiService.getGroup(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun createGroup(group: Group): Flowable {
+ return apiService.createGroup(group).compose(configureApiCallObserver())
+ }
+
+ override fun updateGroup(id: String, item: Group): Flowable {
+ return apiService.updateGroup(id, item).compose(configureApiCallObserver())
+ }
+
+ override fun listGroupChat(groupId: String): Flowable> {
+ return apiService.listGroupChat(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun joinGroup(groupId: String): Flowable {
+ return apiService.joinGroup(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun leaveGroup(groupId: String): Flowable {
+ return apiService.leaveGroup(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun postGroupChat(groupId: String, message: Map): Flowable {
+ return apiService.postGroupChat(groupId, message).compose(configureApiCallObserver())
+ }
+
+ override fun deleteMessage(groupId: String, messageId: String): Flowable {
+ return apiService.deleteMessage(groupId, messageId).compose(configureApiCallObserver())
+ }
+ override fun deleteInboxMessage(id: String): Flowable {
+ return apiService.deleteInboxMessage(id).compose(configureApiCallObserver())
+ }
+
+ override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?): Flowable> {
+ return apiService.getGroupMembers(groupId, includeAllPublicFields).compose(configureApiCallObserver())
+ }
+
+ override fun getGroupMembers(groupId: String, includeAllPublicFields: Boolean?, lastId: String): Flowable> {
+ return apiService.getGroupMembers(groupId, includeAllPublicFields, lastId).compose(configureApiCallObserver())
+ }
+
+ override fun likeMessage(groupId: String, mid: String): Flowable {
+ return apiService.likeMessage(groupId, mid).compose(configureApiCallObserver())
+ }
+
+ override fun flagMessage(groupId: String, mid: String, data: MutableMap): Flowable {
+ return apiService.flagMessage(groupId, mid, data).compose(configureApiCallObserver())
+ }
+
+ override fun seenMessages(groupId: String): Flowable {
+ return apiService.seenMessages(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun inviteToGroup(groupId: String, inviteData: Map): Flowable> {
+ return apiService.inviteToGroup(groupId, inviteData).compose(configureApiCallObserver())
+ }
+
+ override fun rejectGroupInvite(groupId: String): Flowable {
+ return apiService.rejectGroupInvite(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun acceptQuest(groupId: String): Flowable {
+ return apiService.acceptQuest(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun rejectQuest(groupId: String): Flowable {
+ return apiService.rejectQuest(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun cancelQuest(groupId: String): Flowable {
+ return apiService.cancelQuest(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun forceStartQuest(groupId: String, group: Group): Flowable {
+ return apiService.forceStartQuest(groupId, group).compose(configureApiCallObserver())
+ }
+
+ override fun inviteToQuest(groupId: String, questKey: String): Flowable {
+ return apiService.inviteToQuest(groupId, questKey).compose(configureApiCallObserver())
+ }
+
+ override fun abortQuest(groupId: String): Flowable {
+ return apiService.abortQuest(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun leaveQuest(groupId: String): Flowable {
+ return apiService.leaveQuest(groupId).compose(configureApiCallObserver())
+ }
+
+ override fun validatePurchase(request: PurchaseValidationRequest): Flowable {
+ return apiService.validatePurchase(request).map { habitResponse ->
+ if (habitResponse.notifications != null) {
+ notificationsManager.setNotifications(habitResponse.notifications)
+ }
+ habitResponse.getData()
+ }
+ }
+
+ override fun changeCustomDayStart(updateObject: Map): Flowable {
+ return apiService.changeCustomDayStart(updateObject).compose(configureApiCallObserver())
+ }
+
+ override fun getMember(memberId: String): Flowable {
+ return apiService.getMember(memberId).compose(configureApiCallObserver())
+ }
+
+ override fun getMemberWithUsername(username: String): Flowable {
+ return apiService.getMemberWithUsername(username).compose(configureApiCallObserver())
+ }
+
override fun getMemberAchievements(memberId: String): Flowable> {
return apiService.getMemberAchievements(memberId).compose(configureApiCallObserver())
}
-
- override fun findUsernames(username: String, context: String?, id: String?): Flowable> {
- return apiService.findUsernames(username, context, id).compose(configureApiCallObserver())
- }
-
- override fun postPrivateMessage(messageDetails: Map): Flowable {
- return apiService.postPrivateMessage(messageDetails).compose(configureApiCallObserver())
- }
-
- override fun retrieveShopIventory(identifier: String): Flowable {
- return apiService.retrieveShopInventory(identifier).compose(configureApiCallObserver())
- }
-
- override fun addPushDevice(pushDeviceData: Map): Flowable> {
- return apiService.addPushDevice(pushDeviceData).compose(configureApiCallObserver())
- }
-
- override fun deletePushDevice(regId: String): Flowable> {
- return apiService.deletePushDevice(regId).compose(configureApiCallObserver())
- }
-
- override fun getUserChallenges(page: Int, memberOnly: Boolean): Flowable> {
- return if (memberOnly) {
- apiService.getUserChallenges(page, memberOnly).compose(configureApiCallObserver())
- } else {
- apiService.getUserChallenges(page).compose(configureApiCallObserver())
- }
- }
-
- override fun getChallengeTasks(challengeId: String): Flowable {
- return apiService.getChallengeTasks(challengeId).compose(configureApiCallObserver())
- }
-
- override fun getChallenge(challengeId: String): Flowable {
- return apiService.getChallenge(challengeId).compose(configureApiCallObserver())
- }
-
- override fun joinChallenge(challengeId: String): Flowable {
- return apiService.joinChallenge(challengeId).compose(configureApiCallObserver())
- }
-
- override fun leaveChallenge(challengeId: String, body: LeaveChallengeBody): Flowable {
- return apiService.leaveChallenge(challengeId, body).compose(configureApiCallObserver())
- }
-
-
- override fun createChallenge(challenge: Challenge): Flowable {
- return apiService.createChallenge(challenge).compose(configureApiCallObserver())
- }
-
- override fun createChallengeTasks(challengeId: String, tasks: List): Flowable> {
- return apiService.createChallengeTasks(challengeId, tasks).compose(configureApiCallObserver())
- }
-
- override fun createChallengeTask(challengeId: String, task: Task): Flowable {
- return apiService.createChallengeTask(challengeId, task).compose(configureApiCallObserver())
- }
-
- override fun updateChallenge(challenge: Challenge): Flowable {
- return apiService.updateChallenge(challenge.id, challenge).compose(configureApiCallObserver())
- }
-
- override fun deleteChallenge(challengeId: String): Flowable {
- return apiService.deleteChallenge(challengeId).compose(configureApiCallObserver())
- }
-
- override fun debugAddTenGems(): Flowable {
- return apiService.debugAddTenGems().compose(configureApiCallObserver())
- }
-
- override fun readNotification(notificationId: String): Flowable> {
- return apiService.readNotification(notificationId).compose(configureApiCallObserver())
- }
-
- override val content: Flowable
- get() = apiService.getContent(languageCode).compose(configureApiCallObserver())
-
- override fun openMysteryItem(): Flowable {
- return apiService.openMysteryItem().compose(configureApiCallObserver())
- }
-
- override fun runCron(): Flowable {
- return apiService.runCron().compose(configureApiCallObserver())
- }
-
- override fun resetAccount(): Flowable {
- return apiService.resetAccount().compose(configureApiCallObserver())
- }
-
- override fun deleteAccount(password: String): Flowable {
- val updateObject = HashMap()
- updateObject["password"] = password
- return apiService.deleteAccount(updateObject).compose(configureApiCallObserver())
- }
-
- override fun togglePinnedItem(pinType: String, path: String): Flowable {
- return apiService.togglePinnedItem(pinType, path).compose(configureApiCallObserver())
- }
-
- override fun sendPasswordResetEmail(email: String): Flowable {
- val data = HashMap()
- data["email"] = email
- return apiService.sendPasswordResetEmail(data).compose(configureApiCallObserver())
- }
-
- override fun updateLoginName(newLoginName: String, password: String): Flowable {
- val updateObject = HashMap()
- updateObject["username"] = newLoginName
- updateObject["password"] = password
- return apiService.updateLoginName(updateObject).compose(configureApiCallObserver())
- }
-
- override fun updateUsername(newLoginName: String): Flowable {
- val updateObject = HashMap()
- updateObject["username"] = newLoginName
- return apiService.updateLoginName(updateObject).compose(configureApiCallObserver())
- }
-
- override fun verifyUsername(username: String): Flowable {
- val updateObject = HashMap()
- updateObject["username"] = username
- return this.apiService.verifyUsername(updateObject).compose(configureApiCallObserver())
- }
-
- override fun updateEmail(newEmail: String, password: String): Flowable {
- val updateObject = HashMap()
- updateObject["newEmail"] = newEmail
- updateObject["password"] = password
- return apiService.updateEmail(updateObject).compose(configureApiCallObserver())
- }
-
- override fun updatePassword(oldPassword: String, newPassword: String, newPasswordConfirmation: String): Flowable {
- val updateObject = HashMap()
- updateObject["password"] = oldPassword
- updateObject["newPassword"] = newPassword
- updateObject["confirmPassword"] = newPasswordConfirmation
- return apiService.updatePassword(updateObject).compose(configureApiCallObserver())
- }
-
- override fun allocatePoint(stat: String): Flowable {
- return apiService.allocatePoint(stat).compose(configureApiCallObserver())
- }
-
- override fun bulkAllocatePoints(strength: Int, intelligence: Int, constitution: Int, perception: Int): Flowable {
- val body = HashMap>()
- val stats = HashMap()
- stats["str"] = strength
- stats["int"] = intelligence
- stats["con"] = constitution
- stats["per"] = perception
- body["stats"] = stats
- return apiService.bulkAllocatePoints(body).compose(configureApiCallObserver())
- }
-
- override fun retrieveMarketGear(): Flowable {
- return apiService.retrieveMarketGear().compose(configureApiCallObserver())
- }
-
- override val worldState: Flowable
- get() = apiService.worldState.compose(configureApiCallObserver())
-
- companion object {
- private const val TAG = "ApiClientImpl"
-
- fun createGsonFactory(): GsonConverterFactory {
- return GSonFactoryCreator.create()
- }
- }
-}
+
+ override fun findUsernames(username: String, context: String?, id: String?): Flowable> {
+ return apiService.findUsernames(username, context, id).compose(configureApiCallObserver())
+ }
+
+ override fun postPrivateMessage(messageDetails: Map): Flowable {
+ return apiService.postPrivateMessage(messageDetails).compose(configureApiCallObserver())
+ }
+
+ override fun retrieveShopIventory(identifier: String): Flowable {
+ return apiService.retrieveShopInventory(identifier).compose(configureApiCallObserver())
+ }
+
+ override fun addPushDevice(pushDeviceData: Map): Flowable> {
+ return apiService.addPushDevice(pushDeviceData).compose(configureApiCallObserver())
+ }
+
+ override fun deletePushDevice(regId: String): Flowable> {
+ return apiService.deletePushDevice(regId).compose(configureApiCallObserver())
+ }
+
+ override fun getUserChallenges(page: Int, memberOnly: Boolean): Flowable> {
+ return if (memberOnly) {
+ apiService.getUserChallenges(page, memberOnly).compose(configureApiCallObserver())
+ } else {
+ apiService.getUserChallenges(page).compose(configureApiCallObserver())
+ }
+ }
+
+ override fun getChallengeTasks(challengeId: String): Flowable {
+ return apiService.getChallengeTasks(challengeId).compose(configureApiCallObserver())
+ }
+
+ override fun getChallenge(challengeId: String): Flowable {
+ return apiService.getChallenge(challengeId).compose(configureApiCallObserver())
+ }
+
+ override fun joinChallenge(challengeId: String): Flowable {
+ return apiService.joinChallenge(challengeId).compose(configureApiCallObserver())
+ }
+
+ override fun leaveChallenge(challengeId: String, body: LeaveChallengeBody): Flowable {
+ return apiService.leaveChallenge(challengeId, body).compose(configureApiCallObserver())
+ }
+
+
+ override fun createChallenge(challenge: Challenge): Flowable {
+ return apiService.createChallenge(challenge).compose(configureApiCallObserver())
+ }
+
+ override fun createChallengeTasks(challengeId: String, tasks: List): Flowable> {
+ return apiService.createChallengeTasks(challengeId, tasks).compose(configureApiCallObserver())
+ }
+
+ override fun createChallengeTask(challengeId: String, task: Task): Flowable {
+ return apiService.createChallengeTask(challengeId, task).compose(configureApiCallObserver())
+ }
+
+ override fun updateChallenge(challenge: Challenge): Flowable {
+ return apiService.updateChallenge(challenge.id, challenge).compose(configureApiCallObserver())
+ }
+
+ override fun deleteChallenge(challengeId: String): Flowable {
+ return apiService.deleteChallenge(challengeId).compose(configureApiCallObserver())
+ }
+
+ override fun debugAddTenGems(): Flowable {
+ return apiService.debugAddTenGems().compose(configureApiCallObserver())
+ }
+
+ override fun readNotification(notificationId: String): Flowable> {
+ return apiService.readNotification(notificationId).compose(configureApiCallObserver())
+ }
+
+ override fun readNotifications(notificationIds: Map