diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java b/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java index 8c468f1d6..a0a1a8dc8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java @@ -17,6 +17,9 @@ import com.magicmicky.habitrpgwrapper.lib.models.Customization; import com.magicmicky.habitrpgwrapper.lib.models.FAQArticle; import com.magicmicky.habitrpgwrapper.lib.models.Group; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest; +import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import com.magicmicky.habitrpgwrapper.lib.models.Purchases; import com.magicmicky.habitrpgwrapper.lib.models.Skill; import com.magicmicky.habitrpgwrapper.lib.models.TutorialStep; @@ -66,7 +69,9 @@ import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; +import android.os.Build; import android.support.v7.app.AlertDialog; +import android.util.Log; import java.io.IOException; import java.lang.annotation.Annotation; @@ -98,6 +103,7 @@ import retrofit2.converter.gson.GsonConverterFactory; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; +import rx.functions.Func1; import rx.schedulers.Schedulers; @@ -108,7 +114,13 @@ public class APIHelper implements Action1 { // I think we don't need the APIHelper anymore we could just use ApiService public final ApiService apiService; final Observable.Transformer apiCallTransformer = - observable -> ((Observable) observable).subscribeOn(Schedulers.io()) + observable -> ((Observable) observable) + .map(new Func1() { + @Override public Object call(HabitResponse habitResponse) { + return habitResponse.getData(); + } + }) + .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(this); private final GsonConverterFactory gsonConverter; @@ -128,31 +140,6 @@ public class APIHelper implements Action1 { crashlyticsProxy.setUserName(this.hostConfig.getUser()); Amplitude.getInstance().setUserId(this.hostConfig.getUser()); - Interceptor remove_data_interceptor = chain -> { - Response response = chain.proceed(chain.request()); - String stringJson = response.body().string(); - JSONObject jsonObject = null; - String dataString = null; - try { - jsonObject = new JSONObject(stringJson); - if (jsonObject.has("data")) { - dataString = jsonObject.getString("data"); - } - } catch (JSONException e) { - e.printStackTrace(); - } - MediaType contentType = response.body().contentType(); - ResponseBody body = null; - - if (dataString != null) { - body = ResponseBody.create(contentType, dataString); - } else { - body = ResponseBody.create(contentType, stringJson); - } - crashlyticsProxy.setString("last_api_call",response.request().url().toString()); - return response.newBuilder().body(body).build(); - }; - HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); if (BuildConfig.DEBUG) { logging.setLevel(HttpLoggingInterceptor.Level.BODY); @@ -161,7 +148,6 @@ public class APIHelper implements Action1 { String userAgent = System.getProperty("http.agent"); OkHttpClient client = new OkHttpClient.Builder() - .addInterceptor(remove_data_interceptor) .addInterceptor(logging) .addNetworkInterceptor(chain -> { Request original = chain.request(); @@ -183,12 +169,14 @@ public class APIHelper implements Action1 { .build(); Server server = new Server(this.hostConfig.getAddress()); + retrofitAdapter = new Retrofit.Builder() .client(client) .baseUrl(server.toString()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(gsonConverter) .build(); + this.apiService = retrofitAdapter.create(ApiService.class); } @@ -261,7 +249,7 @@ public class APIHelper implements Action1 { return GsonConverterFactory.create(gson); } - public Observable registerUser(String username, String email, String password, String confirmPassword) { + public Observable> registerUser(String username, String email, String password, String confirmPassword) { UserAuth auth = new UserAuth(); auth.setUsername(username); auth.setPassword(password); @@ -270,14 +258,14 @@ public class APIHelper implements Action1 { return this.apiService.registerUser(auth); } - public Observable connectUser(String username, String password) { + public Observable> connectUser(String username, String password) { UserAuth auth = new UserAuth(); auth.setUsername(username); auth.setPassword(password); return this.apiService.connectLocal(auth); } - public Observable connectSocial(String network, String userId, String accessToken) { + public Observable> connectSocial(String network, String userId, String accessToken) { UserAuthSocial auth = new UserAuthSocial(); auth.setNetwork(network); UserAuthSocialTokens authResponse = new UserAuthSocialTokens(); @@ -333,32 +321,32 @@ public class APIHelper implements Action1 { } } - public Observable retrieveUser(boolean withTasks) { - Observable userObservable = apiService.getUser(); + public Observable> retrieveUser(boolean withTasks) { + Observable> userObservable = apiService.getUser(); if (withTasks) { - Observable tasksObservable = apiService.getTasks(); + Observable> tasksObservable = apiService.getTasks(); userObservable = Observable.zip(userObservable, tasksObservable, (habitRPGUser, tasks) -> { - habitRPGUser.setHabits(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getHabits())); - habitRPGUser.setDailys(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getDailys())); - habitRPGUser.setTodos(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getTodos())); - habitRPGUser.setRewards(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getRewards())); - for (Task task : tasks.tasks.values()) { - switch (task.getType()) { - case "habit": - habitRPGUser.getHabits().add(task); - break; - case "daily": - habitRPGUser.getDailys().add(task); - break; - case "todo": - habitRPGUser.getTodos().add(task); - break; - case "reward": - habitRPGUser.getRewards().add(task); - break; - } - } +// habitRPGUser.setHabits(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getHabits())); +// habitRPGUser.setDailys(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getDailys())); +// habitRPGUser.setTodos(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getTodos())); +// habitRPGUser.setRewards(sortTasks(tasks.tasks, habitRPGUser.getTasksOrder().getRewards())); +// for (Task task : tasks.tasks.values()) { +// switch (task.getType()) { +// case "habit": +// habitRPGUser.getHabits().add(task); +// break; +// case "daily": +// habitRPGUser.getDailys().add(task); +// break; +// case "todo": +// habitRPGUser.getTodos().add(task); +// break; +// case "reward": +// habitRPGUser.getRewards().add(task); +// break; +// } +// } return habitRPGUser; }); } @@ -414,9 +402,33 @@ public class APIHelper implements Action1 { }); } +// private void showNotificationDialog(final List notifications) { +// HabiticaApplication.currentActivity.runOnUiThread(() -> { +// if (!(HabiticaApplication.currentActivity).isFinishing() && displayedAlert == null) { +// AlertDialog.Builder builder = new AlertDialog.Builder(HabiticaApplication.currentActivity) +// .setTitle(resourceTitleString) +// .setMessage(resourceMessageString) +// .setNeutralButton(android.R.string.ok, (dialog, which) -> { +// displayedAlert = null; +// }); +// +// if (!resourceTitleString.isEmpty()) { +// builder.setIcon(R.drawable.ic_warning_black); +// } +// +// displayedAlert = builder.show(); +// } +// }); +// } + + /* + 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/ + */ + @SuppressWarnings("unchecked") - public Observable.Transformer configureApiCallObserver() { - return (Observable.Transformer) apiCallTransformer; + public Observable.Transformer, T> configureApiCallObserver() { + return (Observable.Transformer, T>) apiCallTransformer; } public void updateAuthenticationCredentials(String userID, String apiToken) { @@ -431,7 +443,7 @@ public class APIHelper implements Action1 { public String message; } - public Observable getContent() { + public Observable>getContent() { return apiService.getContent(languageCode); } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java index 1c7593604..a728f0b4d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java @@ -72,8 +72,7 @@ public class ContentCache { private void getContentAndSearchFor(final String typeOfSearch, final String searchKey, final GotContentEntryCallback gotEntry) { apiHelper.getContent() - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .compose(apiHelper.configureApiCallObserver()) .subscribe(contentResult -> { switch (typeOfSearch) { case "quest": { @@ -116,6 +115,7 @@ public class ContentCache { private void getContentAndSearchForList(final String typeOfSearch, final List searchKeys, final GotContentEntryCallback> gotEntry) { List resultList = new ArrayList<>(); apiHelper.getContent() + .compose(apiHelper.configureApiCallObserver()) .flatMap(contentResult -> { List itemList = new ArrayList(contentResult.gear.flat); itemList.add(contentResult.potion); @@ -123,8 +123,6 @@ public class ContentCache { return Observable.from(itemList); }) .filter(item -> searchKeys.contains(item.key)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) .subscribe(resultList::add, throwable -> { }, () -> gotEntry.GotObject(resultList)); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.java index c0e6eb99c..cfb8b2753 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.java @@ -10,6 +10,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.Hair; import com.magicmicky.habitrpgwrapper.lib.models.Items; import com.magicmicky.habitrpgwrapper.lib.models.Outfit; import com.magicmicky.habitrpgwrapper.lib.models.Preferences; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import android.app.ProgressDialog; import android.content.Intent; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java index 5cd342f17..27ffa9ebd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java @@ -74,6 +74,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.inventory.HatchingPotion; import com.magicmicky.habitrpgwrapper.lib.models.inventory.Item; import com.magicmicky.habitrpgwrapper.lib.models.inventory.Pet; import com.magicmicky.habitrpgwrapper.lib.models.inventory.QuestContent; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.MaintenanceResponse; import com.magicmicky.habitrpgwrapper.lib.models.tasks.ChecklistItem; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Days; @@ -940,7 +941,7 @@ public class MainActivity extends BaseActivity implements Action1, Ha @Subscribe public void onEvent(final BuyGemItemCommand event) { if (event.item.canBuy(user) || !event.item.getCurrency().equals("gems")) { - Observable observable; + Observable> observable; if (event.shopIdentifier.equals(Shop.TIME_TRAVELERS_SHOP)) { if (event.item.purchaseType.equals("gear")) { observable = apiHelper.apiService.purchaseMysterySet(event.item.categoryIdentifier); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.java index 9cac5a5ef..8e5f9fb1a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.java @@ -42,6 +42,7 @@ public class RewardsRecyclerViewAdapter extends BaseTasksRecyclerViewAdapter { // get itemdata list ArrayList itemKeys = new ArrayList<>(); @@ -84,7 +85,6 @@ public class RewardsRecyclerViewAdapter extends BaseTasksRecyclerViewAdapter { this.filteredContent.addAll(items); notifyDataSetChanged(); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.java index 12d654c7a..77b71663f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.java @@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.ui.helpers.UiUtils; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; import com.magicmicky.habitrpgwrapper.lib.models.Skill; import com.magicmicky.habitrpgwrapper.lib.models.SpecialItems; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.SkillResponse; import com.raizlabs.android.dbflow.sql.builder.Condition; import com.raizlabs.android.dbflow.sql.language.Select; @@ -205,7 +206,7 @@ public class SkillsFragment extends BaseMainFragment { private void useSkill(Skill skill, String taskId) { displayProgressDialog(); - Observable observable; + Observable> observable; if (taskId != null) { observable = apiHelper.apiService.useSkill(skill.key, skill.target, taskId); } else { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/UpdateWidgetService.java b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/UpdateWidgetService.java new file mode 100644 index 000000000..625a396af --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/UpdateWidgetService.java @@ -0,0 +1,120 @@ +package com.habitrpg.android.habitica.widget; + +import com.habitrpg.android.habitica.APIHelper; +import com.habitrpg.android.habitica.HabiticaApplication; +import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback; +import com.habitrpg.android.habitica.ui.activities.MainActivity; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; + +import android.app.PendingIntent; +import android.app.Service; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Intent; +import android.os.IBinder; +import android.widget.RemoteViews; + +import javax.inject.Inject; + +/** + * The service that should update the simple widget + * + * @see com.habitrpg.android.habitica.widget.SimpleWidget + * Created by Mickael on 01/11/13. + */ +public class UpdateWidgetService extends Service implements HabitRPGUserCallback.OnUserReceived { + private static final String LOG = ".simplewidget.service"; + @Inject + public APIHelper apiHelper; + private AppWidgetManager appWidgetManager; + + public UpdateWidgetService() { + super(); + ((HabiticaApplication) getApplication()).getComponent().inject(this); + } + + @Override + public int onStartCommand(final Intent intent, int flags, int startId) { + this.appWidgetManager = AppWidgetManager.getInstance(this); + int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); + ComponentName thisWidget = new ComponentName(this, + SimpleWidget.class); + int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget); + + if (apiHelper != null) { + apiHelper.retrieveUser(true) + .compose(apiHelper.configureApiCallObserver()) + .subscribe(new HabitRPGUserCallback(this)); + for (int widgetId : allWidgetIds) { + RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget); + appWidgetManager.updateAppWidget(widgetId, remoteViews); + } + } else { + for (int widgetId : allWidgetIds) { + RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget); + RemoteViews textConnect = new RemoteViews(this.getPackageName(), R.layout.simple_textview); + textConnect.setTextViewText(R.id.TV_simple_textview, getString(R.string.please_connect)); + remoteViews.removeAllViews(R.id.LL_header); + remoteViews.addView(R.id.LL_header, textConnect); + + + Intent clickIntent = new Intent(this.getApplicationContext(), SimpleWidget.class); + clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds); + PendingIntent updateIntent = PendingIntent.getBroadcast(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); + remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent); + + Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class); + PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp); + appWidgetManager.updateAppWidget(widgetId, remoteViews); + + } + } + stopSelf(); + + return START_STICKY; + } + + private void updateData(HabitRPGUser user, AppWidgetManager appWidgetManager) { + ComponentName thisWidget = new ComponentName(this, SimpleWidget.class); + int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); + for (int widgetId : allWidgetIds) { + RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget); + remoteViews.setTextViewText(R.id.TV_HP, "" + user.getStats().getHp().intValue() + "/" + (int) user.getStats().getMaxHealth() + " " + this.getString(R.string.HP_default)); + remoteViews.setTextViewText(R.id.TV_XP, "" + user.getStats().getExp().intValue() + "/" + (int) user.getStats().getToNextLevel() + " " + this.getString(R.string.XP_default)); + //remoteViews.setImageViewBitmap(R.id.IMG_ProfilePicture, dealWithUserPicture(user,this)); + remoteViews.setProgressBar(R.id.V_HPBar, (int) user.getStats().getMaxHealth(), user.getStats().getHp().intValue(), false); + remoteViews.setProgressBar(R.id.V_XPBar, (int) user.getStats().getToNextLevel(), user.getStats().getExp().intValue(), false); + + // If user click on refresh: refresh + Intent clickIntent = new Intent(this.getApplicationContext(), SimpleWidget.class); + clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds); + PendingIntent updateIntent = PendingIntent.getBroadcast(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); + remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent); + + //If user click on life and xp: open the app + Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class); + PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT); + remoteViews.setOnClickPendingIntent(R.id.LL_header, openApp); + remoteViews.setOnClickPendingIntent(R.id.IMG_ProfilePicture, openApp); + + appWidgetManager.updateAppWidget(widgetId, remoteViews); + } + + + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onUserReceived(HabitRPGUser user) { + this.updateData(user, appWidgetManager); + + } +} diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java index f7223349e..dbd743366 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java @@ -18,6 +18,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.UserAuthResponse; import com.magicmicky.habitrpgwrapper.lib.models.UserAuthSocial; import com.magicmicky.habitrpgwrapper.lib.models.responses.BuyResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.FeedResponse; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.SkillResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.UnlockResponse; import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; @@ -44,222 +45,222 @@ import rx.Observable; */ public interface ApiService { @GET("status") - Observable getStatus(); + Observable> getStatus(); @GET("content") - Observable getContent(@Query("language") String language); + Observable> getContent(@Query("language") String language); /* user API */ @GET("user/") - Observable getUser(); + Observable> getUser(); @PUT("user/") - Observable updateUser(@Body Map updateDictionary); + Observable> updateUser(@Body Map updateDictionary); @PUT("user/") Observable registrationLanguage(@Header("Accept-Language") String registrationLanguage); @GET("user/inventory/buy") - Observable> getInventoryBuyableGear(); + Observable>> getInventoryBuyableGear(); @POST("user/equip/{type}/{key}") - Observable equipItem(@Path("type") String type, @Path("key") String itemKey); + Observable> equipItem(@Path("type") String type, @Path("key") String itemKey); @POST("user/buy/{key}") - Observable buyItem(@Path("key") String itemKey); + Observable> buyItem(@Path("key") String itemKey); @POST("user/purchase/{type}/{key}") - Observable purchaseItem(@Path("type") String type, @Path("key") String itemKey); + Observable> purchaseItem(@Path("type") String type, @Path("key") String itemKey); @POST("user/purchase-hourglass/{type}/{key}") - Observable purchaseHourglassItem(@Path("type") String type, @Path("key") String itemKey); + Observable> purchaseHourglassItem(@Path("type") String type, @Path("key") String itemKey); @POST("user/buy-mystery-set/{key}") - Observable purchaseMysterySet(@Path("key") String itemKey); + Observable> purchaseMysterySet(@Path("key") String itemKey); @POST("user/buy-quest/{key}") - Observable purchaseQuest(@Path("key") String key); + Observable> purchaseQuest(@Path("key") String key); @POST("user/sell/{type}/{key}") - Observable sellItem(@Path("type") String itemType, @Path("key") String itemKey); + Observable> sellItem(@Path("type") String itemType, @Path("key") String itemKey); @POST("user/feed/{pet}/{food}") - Observable feedPet(@Path("pet") String petKey, @Path("food") String foodKey); + Observable> feedPet(@Path("pet") String petKey, @Path("food") String foodKey); @POST("user/hatch/{egg}/{hatchingPotion}") - Observable hatchPet(@Path("egg") String eggKey, @Path("hatchingPotion") String hatchingPotionKey); + Observable> hatchPet(@Path("egg") String eggKey, @Path("hatchingPotion") String hatchingPotionKey); @GET("tasks/user") - Observable getTasks(); + Observable> getTasks(); @POST("user/unlock") - Observable unlockPath(@Query("path") String path); + Observable> unlockPath(@Query("path") String path); @GET("tasks/{id}") - Observable getTask(@Path("id") String id); + Observable> getTask(@Path("id") String id); @POST("tasks/{id}/score/{direction}") - Observable postTaskDirection(@Path("id") String id, @Path("direction") String direction); + Observable> postTaskDirection(@Path("id") String id, @Path("direction") String direction); @POST("tasks/{id}/move/to/{position}") - Observable postTaskNewPosition(@Path("id") String id, @Path("position") String position); + Observable> postTaskNewPosition(@Path("id") String id, @Path("position") String position); @POST("tasks/{taskId}/checklist/{itemId}/score") - Observable scoreChecklistItem(@Path("taskId") String taskId, @Path("itemId") String itemId); + Observable> scoreChecklistItem(@Path("taskId") String taskId, @Path("itemId") String itemId); @POST("tasks/user") - Observable createItem(@Body Task item); + Observable> createItem(@Body Task item); @POST("tasks/user") - Observable> createTasks(@Body List tasks); + Observable>> createTasks(@Body List tasks); @PUT("tasks/{id}") - Observable updateTask(@Path("id") String id, @Body Task item); + Observable> updateTask(@Path("id") String id, @Body Task item); @DELETE("tasks/{id}") - Observable deleteTask(@Path("id") String id); + Observable> deleteTask(@Path("id") String id); @POST("tags") - Observable createTag(@Body Tag tag); + Observable> createTag(@Body Tag tag); @PUT("tags/{id}") - Observable updateTag(@Path("id") String id, @Body Tag tag); + Observable> updateTag(@Path("id") String id, @Body Tag tag); @DELETE("tags/{id}") - Observable deleteTag(@Path("id") String id); + Observable> deleteTag(@Path("id") String id); @POST("user/auth/local/register") - Observable registerUser(@Body UserAuth auth); + Observable> registerUser(@Body UserAuth auth); @POST("user/auth/local/login") - Observable connectLocal(@Body UserAuth auth); + Observable> connectLocal(@Body UserAuth auth); @POST("user/auth/social") - Observable connectSocial(@Body UserAuthSocial auth); + Observable> connectSocial(@Body UserAuthSocial auth); @POST("user/sleep") - Observable sleep(); + Observable> sleep(); @POST("user/revive") - Observable revive(); + Observable> revive(); @POST("user/class/cast/{skill}") - Observable useSkill(@Path("skill") String skillName, @Query("targetType") String targetType, @Query("targetId") String targetId); + Observable> useSkill(@Path("skill") String skillName, @Query("targetType") String targetType, @Query("targetId") String targetId); @POST("user/class/cast/{skill}") - Observable useSkill(@Path("skill") String skillName, @Query("targetType") String targetType); + Observable> useSkill(@Path("skill") String skillName, @Query("targetType") String targetType); @POST("user/change-class") - Observable changeClass(); + Observable> changeClass(); @POST("user/change-class") - Observable changeClass(@Query("class") String className); + Observable> changeClass(@Query("class") String className); @POST("user/disable-classes") - Observable disableClasses(); + Observable> disableClasses(); @POST("user/mark-pms-read") - Observable markPrivateMessagesRead(); + Observable> markPrivateMessagesRead(); /* Group API */ @GET("groups") - Observable> listGroups(@Query("type") String type); + Observable>> listGroups(@Query("type") String type); @GET("groups/{gid}") - Observable getGroup(@Path("gid") String groupId); + Observable> getGroup(@Path("gid") String groupId); @PUT("groups/{id}") - Observable updateGroup(@Path("id") String id, @Body Group item); + Observable> updateGroup(@Path("id") String id, @Body Group item); @GET("groups/{gid}/chat") - Observable> listGroupChat(@Path("gid") String groupId); + Observable>> listGroupChat(@Path("gid") String groupId); @POST("groups/{gid}/join") - Observable joinGroup(@Path("gid") String groupId); + Observable> joinGroup(@Path("gid") String groupId); @POST("groups/{gid}/leave") - Observable leaveGroup(@Path("gid") String groupId); + Observable> leaveGroup(@Path("gid") String groupId); @POST("groups/{gid}/chat") - Observable postGroupChat(@Path("gid") String groupId, @Body HashMap message); + Observable> postGroupChat(@Path("gid") String groupId, @Body HashMap message); @DELETE("groups/{gid}/chat/{messageId}") - Observable deleteMessage(@Path("gid") String groupId, @Path("messageId") String messageId); + Observable> deleteMessage(@Path("gid") String groupId, @Path("messageId") String messageId); @GET("groups/{gid}/members") - Observable> getGroupMembers(@Path("gid") String groupId, @Query("includeAllPublicFields") Boolean includeAllPublicFields); + Observable>> getGroupMembers(@Path("gid") String groupId, @Query("includeAllPublicFields") Boolean includeAllPublicFields); @GET("groups/{gid}/members") - Observable> getGroupMembers(@Path("gid") String groupId, @Query("includeAllPublicFields") Boolean includeAllPublicFields, @Query("lastId") String lastId); + Observable>> getGroupMembers(@Path("gid") String groupId, @Query("includeAllPublicFields") Boolean includeAllPublicFields, @Query("lastId") String lastId); // Like returns the full chat list @POST("groups/{gid}/chat/{mid}/like") - Observable likeMessage(@Path("gid") String groupId, @Path("mid") String mid); + Observable> likeMessage(@Path("gid") String groupId, @Path("mid") String mid); @POST("groups/{gid}/chat/{mid}/flag") - Observable flagMessage(@Path("gid") String groupId, @Path("mid") String mid); + Observable> flagMessage(@Path("gid") String groupId, @Path("mid") String mid); @POST("groups/{gid}/chat/seen") - Observable seenMessages(@Path("gid") String groupId); + Observable> seenMessages(@Path("gid") String groupId); @POST("groups/{gid}/invite") - Observable inviteToGroup(@Path("gid") String groupId, @Body Map inviteData); + Observable> inviteToGroup(@Path("gid") String groupId, @Body Map inviteData); @POST("groups/{gid}/reject-invite") - Observable rejectGroupInvite(@Path("gid") String groupId); + Observable> rejectGroupInvite(@Path("gid") String groupId); @POST("groups/{gid}/quests/accept") - Observable acceptQuest(@Path("gid") String groupId); + Observable> acceptQuest(@Path("gid") String groupId); @POST("groups/{gid}/quests/reject") - Observable rejectQuest(@Path("gid") String groupId); + Observable> rejectQuest(@Path("gid") String groupId); @POST("groups/{gid}/quests/cancel") - Observable cancelQuest(@Path("gid") String groupId); + Observable> cancelQuest(@Path("gid") String groupId); @POST("groups/{gid}/quests/force-start") - Observable forceStartQuest(@Path("gid") String groupId, @Body Group group); + Observable> forceStartQuest(@Path("gid") String groupId, @Body Group group); @POST("groups/{gid}/quests/invite/{questKey}") - Observable inviteToQuest(@Path("gid") String groupId, @Path("questKey") String questKey); + Observable> inviteToQuest(@Path("gid") String groupId, @Path("questKey") String questKey); @POST("groups/{gid}/quests/abort") - Observable abortQuest(@Path("gid") String groupId); + Observable> abortQuest(@Path("gid") String groupId); @POST("groups/{gid}/quests/leave") - Observable leaveQuest(@Path("gid") String groupId); + Observable> leaveQuest(@Path("gid") String groupId); @POST("/iap/android/verify") - Observable validatePurchase(@Body PurchaseValidationRequest request); + Observable> validatePurchase(@Body PurchaseValidationRequest request); @POST("user/custom-day-start") Observable changeCustomDayStart(@Body Map updateObject); //Members URL @GET("members/{mid}") - Observable GetMember(@Path("mid") String memberId); + Observable> GetMember(@Path("mid") String memberId); @POST("members/send-private-message") - Observable postPrivateMessage(@Body HashMap messageDetails); - + Observable> postPrivateMessage(@Body HashMap messageDetails); + @GET("shops/{identifier}") - Observable fetchShopInventory(@Path("identifier") String identifier); + Observable> fetchShopInventory(@Path("identifier") String identifier); //Push notifications @POST("user/push-devices") - Observable addPushDevice(@Body Map pushDeviceData); + Observable> addPushDevice(@Body Map pushDeviceData); @DELETE("user/push-devices/{regId}") - Observable deletePushDevice(@Path("regId") String regId); + Observable> deletePushDevice(@Path("regId") String regId); //DEBUG: These calls only work on a local development server @POST("debug/add-ten-gems") - Observable debugAddTenGems(); + Observable> debugAddTenGems(); } diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/MaintenanceApiService.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/MaintenanceApiService.java index 12cd681d2..a2b23b3a1 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/MaintenanceApiService.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/MaintenanceApiService.java @@ -1,5 +1,6 @@ package com.magicmicky.habitrpgwrapper.lib.api; +import com.magicmicky.habitrpgwrapper.lib.models.responses.HabitResponse; import com.magicmicky.habitrpgwrapper.lib.models.responses.MaintenanceResponse; import retrofit2.http.GET; @@ -8,9 +9,9 @@ import rx.Observable; public interface MaintenanceApiService { @GET("maintenance-android.json") - Observable getMaintenanceStatus(); + Observable> getMaintenanceStatus(); @GET("deprecation-android.json") - Observable getDepricationStatus(); + Observable> getDepricationStatus(); } diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/responses/HabitResponse.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/responses/HabitResponse.java new file mode 100644 index 000000000..7abdd9b40 --- /dev/null +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/responses/HabitResponse.java @@ -0,0 +1,42 @@ +package com.magicmicky.habitrpgwrapper.lib.models.responses; + +import java.util.List; + +/** + * Created by krh12 on 11/23/2016. + */ + +public class HabitResponse { + + private Boolean success; + public T data; + public List notifications; + + /** + * + * @return + * The success + */ + public Boolean getSuccess() { + return success; + } + + /** + * + * @param success + * The success + */ + public void setSuccess(Boolean success) { + this.success = success; + } + + /** + * + * @return + * The data + */ + public T getData() { + return data; + } +} + diff --git a/build.gradle b/build.gradle index 56bc166c2..744edbc25 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.android.databinding:dataBinder:1.0-rc4' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.google.gms:google-services:3.0.0' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 88a8ab1ee..89c1861e7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -4,3 +4,4 @@ distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip +