From ff70591cc5dc47b87c96e55c5039c856ff4ec537 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 12 May 2016 13:44:29 +0200 Subject: [PATCH] performance improvements for task list --- Habitica/res/layout/daily_item_card.xml | 161 ++++++++---------- Habitica/res/layout/habit_item_card.xml | 33 ++-- Habitica/res/layout/todo_item_card.xml | 126 ++++++-------- .../habitrpg/android/habitica/APIHelper.java | 2 +- .../android/habitica/ContentCache.java | 129 ++++++-------- .../tasks/BaseTasksRecyclerViewAdapter.java | 11 +- .../ui/fragments/PreferencesFragment.java | 20 ++- .../viewHolders/tasks/BaseTaskViewHolder.java | 18 +- .../tasks/ChecklistedViewHolder.java | 4 +- .../ui/viewHolders/tasks/DailyViewHolder.java | 12 ++ .../viewHolders/tasks/RewardViewHolder.java | 12 +- .../ui/viewHolders/tasks/TodoViewHolder.java | 18 +- .../lib/api/InAppPurchasesApiService.java | 2 +- .../lib/api/MaintenanceApiService.java | 4 +- .../lib/models/tasks/Task.java | 3 + 15 files changed, 274 insertions(+), 281 deletions(-) diff --git a/Habitica/res/layout/daily_item_card.xml b/Habitica/res/layout/daily_item_card.xml index dd02ec7a9..1f1ce83aa 100644 --- a/Habitica/res/layout/daily_item_card.xml +++ b/Habitica/res/layout/daily_item_card.xml @@ -1,115 +1,96 @@ - - + - - - - - - - - - - - - - - - - - + android:layout_gravity="center" /> + + + + + + + + + + + + - - - + diff --git a/Habitica/res/layout/habit_item_card.xml b/Habitica/res/layout/habit_item_card.xml index c924509e2..8fcfa7a2d 100644 --- a/Habitica/res/layout/habit_item_card.xml +++ b/Habitica/res/layout/habit_item_card.xml @@ -1,14 +1,16 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/white" + android:orientation="horizontal"> + android:layout_width="80dp" + android:layout_height="match_parent" + android:orientation="horizontal" + android:id="@+id/btnLayout" + android:baselineAligned="false"> - - - + android:gravity="center" /> + diff --git a/Habitica/res/layout/todo_item_card.xml b/Habitica/res/layout/todo_item_card.xml index e314fcbac..acc6d1606 100644 --- a/Habitica/res/layout/todo_item_card.xml +++ b/Habitica/res/layout/todo_item_card.xml @@ -10,7 +10,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> - @@ -18,81 +18,65 @@ android:id="@+id/checkBox" android:layout_width="@dimen/checkbox_size" android:layout_height="@dimen/checkbox_size" - android:layout_centerInParent="true" android:gravity="center" android:button="@drawable/todo_checkbox" - android:layout_gravity="center_horizontal" /> - - - + + + + + + + + + - - - - - - - - - - + android:textColor="@color/white" + android:gravity="center"/> - - + android:id="@+id/checklistDivider" + android:layout_width="@dimen/checklist_divider_width" + android:layout_height="@dimen/hairline_height" + android:background="@color/white"/> + + + { private final Retrofit retrofitAdapter; private HostConfig cfg; - final Observable.Transformer apiCallTransformer = observable -> ((Observable)observable).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(this); + private AlertDialog displayedAlert; //private OnHabitsAPIResult mResultListener; 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 5254646d3..ddd8bbdbc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java @@ -13,6 +13,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Func1; +import rx.schedulers.Schedulers; + public class ContentCache { public interface GotContentEntryCallback { @@ -78,92 +83,60 @@ public class ContentCache { } } - private void getContentAndSearchFor(final String typeOfSearch, final String searchKey, final GotContentEntryCallback gotEntry) { - apiService.getContent().subscribe(contentResult -> { - switch (typeOfSearch) { - case "quest": { - Collection questList = contentResult.quests; + private void getContentAndSearchFor(final String typeOfSearch, final String searchKey, final GotContentEntryCallback gotEntry) { + apiService.getContent() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(contentResult -> { + switch (typeOfSearch) { + case "quest": { + Collection questList = contentResult.quests; - for (QuestContent quest : questList) { - if (quest.getKey() == searchKey) { - gotEntry.GotObject((T) quest); - } - } - - break; - } - case "item": { - T searchedItem = null; - - if (searchKey == "potion") { - searchedItem = (T) contentResult.potion; - } else if (searchKey == "armoire") { - searchedItem = (T) contentResult.armoire; - } else { - Collection itemList = contentResult.gear.flat; - - for (ItemData item : itemList) { - if (item.key.equals(searchKey)) { - searchedItem = (T) item; + for (QuestContent quest : questList) { + if (quest.getKey().equals(searchKey)) { + gotEntry.GotObject((T) quest); + } } + + break; + } + case "item": { + T searchedItem = null; + + if (searchKey.equals("potion")) { + searchedItem = (T) contentResult.potion; + } else if (searchKey == "armoire") { + searchedItem = (T) contentResult.armoire; + } else { + Collection itemList = contentResult.gear.flat; + + for (ItemData item : itemList) { + if (item.key.equals(searchKey)) { + searchedItem = (T) item; + } + } + } + + gotEntry.GotObject(searchedItem); + + break; } } - - gotEntry.GotObject((T) searchedItem); - - break; - } - } - - saveContentResultToDb(contentResult); - }, throwable -> {}); + }, throwable -> {}); } - private void getContentAndSearchForList(final String typeOfSearch, final List searchKeys, final GotContentEntryCallback> gotEntry) { - apiService.getContent().subscribe(contentResult -> { - switch (typeOfSearch) { - case "item": { - List resultList = new ArrayList(); - + private void getContentAndSearchForList(final String typeOfSearch, final List searchKeys, final GotContentEntryCallback> gotEntry) { + List resultList = new ArrayList<>(); + apiService.getContent() + .flatMap(contentResult -> { List itemList = new ArrayList(contentResult.gear.flat); itemList.add(contentResult.potion); itemList.add(contentResult.armoire); - - for (ItemData item : itemList) { - if (searchKeys.contains(item.key)) { - resultList.add((T) item); - } - } - - gotEntry.GotObject(resultList); - - break; - } - } - - saveContentResultToDb(contentResult); - }, throwable -> {}); - } - - - private void saveContentResultToDb(ContentResult contentResult) { - Collection questList = contentResult.quests; - - for (QuestContent quest : questList) { - quest.save(); - - if (quest.boss != null) { - quest.boss.key = quest.getKey(); - quest.boss.async().save(); - } - } - - Collection itemList = new ArrayList<>(contentResult.gear.flat); - itemList.add(contentResult.armoire); - itemList.add(contentResult.potion); - - for (ItemData item : itemList) { - item.async().save(); - } + 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/adapter/tasks/BaseTasksRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.java index 11565233c..141908617 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/BaseTasksRecyclerViewAdapter.java @@ -6,6 +6,7 @@ import com.habitrpg.android.habitica.events.TaskUpdatedEvent; import com.habitrpg.android.habitica.events.commands.FilterTasksByTagsCommand; import com.habitrpg.android.habitica.events.commands.TaskCheckedCommand; import com.habitrpg.android.habitica.helpers.TagsHelper; +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; import com.habitrpg.android.habitica.ui.viewHolders.tasks.BaseTaskViewHolder; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; import com.raizlabs.android.dbflow.runtime.transaction.BaseTransaction; @@ -31,6 +32,7 @@ import java.util.List; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Func0; +import rx.functions.Func1; import rx.schedulers.Schedulers; public abstract class BaseTasksRecyclerViewAdapter @@ -173,6 +175,7 @@ public abstract class BaseTasksRecyclerViewAdapter tasks = new ArrayList<>(); Observable.defer(() -> Observable.just(new Select().from(Task.class) .where(Condition.column("type").eq(this.taskType)) .and(Condition.CombinedCondition @@ -181,9 +184,15 @@ public abstract class BaseTasksRecyclerViewAdapter { + task.parsedText = MarkdownParser.parseMarkdown(task.getText()); + task.parsedNotes = MarkdownParser.parseMarkdown(task.getNotes()); + return task; + }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(this::setTasks, throwable -> {}); + .subscribe(tasks::add, throwable -> {}, () -> setTasks(tasks)); } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PreferencesFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PreferencesFragment.java index 37d74af0e..35b9a158a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PreferencesFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PreferencesFragment.java @@ -177,17 +177,19 @@ public class PreferencesFragment extends BasePreferencesFragment implements public void setUser(HabitRPGUser user) { this.user = user; - if (user.getFlags().getClassSelected()) { - if (user.getPreferences().getDisableClasses()) { - classSelectionPreference.setTitle(getString(R.string.enable_class)); + if (user != null && user.getFlags() != null) { + if (user.getFlags().getClassSelected()) { + if (user.getPreferences().getDisableClasses()) { + classSelectionPreference.setTitle(getString(R.string.enable_class)); + } else { + classSelectionPreference.setTitle(getString(R.string.change_class)); + classSelectionPreference.setSummary(getString(R.string.change_class_description)); + } + classSelectionPreference.setVisible(true); } else { - classSelectionPreference.setTitle(getString(R.string.change_class)); - classSelectionPreference.setSummary(getString(R.string.change_class_description)); + classSelectionPreference.setTitle(getString(R.string.enable_class)); + classSelectionPreference.setVisible(true); } - classSelectionPreference.setVisible(true); - } else { - classSelectionPreference.setTitle(getString(R.string.enable_class)); - classSelectionPreference.setVisible(true); } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.java index e4a6823a5..f65857e7d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.java @@ -8,7 +8,6 @@ import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; import org.greenrobot.eventbus.EventBus; import android.content.Context; -import android.graphics.Color; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.View; @@ -17,6 +16,10 @@ import android.widget.TextView; import butterknife.BindColor; import butterknife.BindView; import butterknife.ButterKnife; +import hugo.weaving.DebugLog; +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; public class BaseTaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { @@ -54,9 +57,14 @@ public class BaseTaskViewHolder extends RecyclerView.ViewHolder implements View. public void bindHolder(Task newTask, int position) { this.task = newTask; - this.titleTextView.setText(MarkdownParser.parseMarkdown(this.task.getText())); + if (this.canContainMarkdown()) { + this.titleTextView.setText(this.task.parsedText); + this.notesTextView.setText(this.task.parsedNotes); + } else { + this.titleTextView.setText(this.task.getText()); + this.notesTextView.setText(this.task.getNotes()); + } if (this.task.getNotes().length() > 0) { - this.notesTextView.setText(MarkdownParser.parseMarkdown(this.task.getNotes())); this.notesTextView.setVisibility(View.VISIBLE); } else { this.notesTextView.setVisibility(View.GONE); @@ -78,4 +86,8 @@ public class BaseTaskViewHolder extends RecyclerView.ViewHolder implements View. EventBus.getDefault().post(event); } + + public boolean canContainMarkdown() { + return true; + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.java index c6c915533..f26eb4c47 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/ChecklistedViewHolder.java @@ -29,7 +29,7 @@ import butterknife.OnClick; public abstract class ChecklistedViewHolder extends BaseTaskViewHolder implements CompoundButton.OnCheckedChangeListener { @BindView(R.id.checkBoxHolder) - RelativeLayout checkboxHolder; + ViewGroup checkboxHolder; @BindView(R.id.checkBox) CheckBox checkbox; @@ -42,7 +42,7 @@ public abstract class ChecklistedViewHolder extends BaseTaskViewHolder implement View checklistBottomSpace; @BindView(R.id.checklistIndicatorWrapper) - RelativeLayout checklistIndicatorWrapper; + ViewGroup checklistIndicatorWrapper; @BindView(R.id.checkListCompletedTextView) TextView checklistCompletedTextView; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.java index 0c2240657..243e346aa 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.java @@ -4,9 +4,15 @@ import com.habitrpg.android.habitica.R; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; import android.view.View; +import android.widget.TextView; + +import butterknife.BindView; public class DailyViewHolder extends ChecklistedViewHolder { + @BindView(R.id.streakTextView) + TextView streakTextView; + public final int dailyResetOffset; public DailyViewHolder(View itemView, int dailyResetOffset) { @@ -22,6 +28,12 @@ public class DailyViewHolder extends ChecklistedViewHolder { } else { this.checklistIndicatorWrapper.setBackgroundColor(this.taskGray); } + if (task.streak != null && task.streak > 0) { + this.streakTextView.setText(itemView.getContext().getString(R.string.daily_streak, task.streak)); + this.streakTextView.setVisibility(View.VISIBLE); + } else { + this.streakTextView.setVisibility(View.GONE); + } } @Override diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.java index 836d87557..a8c0b6314 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.java @@ -8,6 +8,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; import org.greenrobot.eventbus.EventBus; +import android.os.Trace; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; @@ -44,7 +45,7 @@ public class RewardViewHolder extends BaseTaskViewHolder { this.rewardButton.setText(this.priceFormat.format(this.task.value)); - if (this.task.specialTag != null && this.task.specialTag.equals("item")) { + if (this.isItem()) { this.rewardImageView.setVisibility(View.VISIBLE); DataBindingUtils.loadImage(this.rewardImageView, "shop_" + this.task.getId()); } else { @@ -52,6 +53,15 @@ public class RewardViewHolder extends BaseTaskViewHolder { } } + private boolean isItem() { + return this.task.specialTag != null && this.task.specialTag.equals("item"); + } + + @Override + public boolean canContainMarkdown() { + return !isItem(); + } + @OnClick(R.id.btnReward) public void buyReward() { BuyRewardCommand event = new BuyRewardCommand(); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.java index 43d291062..edb633383 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/TodoViewHolder.java @@ -4,9 +4,15 @@ import com.habitrpg.android.habitica.R; import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; import android.view.View; +import android.widget.TextView; + +import butterknife.BindView; public class TodoViewHolder extends ChecklistedViewHolder { + @BindView(R.id.duedateTextView) + TextView duedateTextView; + public TodoViewHolder(View itemView) { super(itemView); } @@ -15,14 +21,20 @@ public class TodoViewHolder extends ChecklistedViewHolder { public void bindHolder(Task newTask, int position) { super.bindHolder(newTask, position); if (this.task.getCompleted()) { - this.checklistIndicatorWrapper.setBackgroundResource(this.task.getLightTaskColor()); - } else { this.checklistIndicatorWrapper.setBackgroundColor(this.taskGray); + } else { + this.checklistIndicatorWrapper.setBackgroundResource(this.task.getLightTaskColor()); + } + if (task.duedate != null) { + this.duedateTextView.setText(itemView.getContext().getString(R.string.todo_due, task.streak)); + this.duedateTextView.setVisibility(View.VISIBLE); + } else { + this.duedateTextView.setVisibility(View.GONE); } } @Override public Boolean shouldDisplayAsActive() { - return this.task.getCompleted(); + return !this.task.getCompleted(); } } diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/InAppPurchasesApiService.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/InAppPurchasesApiService.java index 9b1bff19f..2fa64a8b1 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/InAppPurchasesApiService.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/api/InAppPurchasesApiService.java @@ -13,6 +13,6 @@ import retrofit2.http.Query; * Created by Negue on 27.11.2015. */ public interface InAppPurchasesApiService { - @POST("/iap/android/verify") + @POST("iap/android/verify") Call validatePurchase(@Query("_id") String id, @Query("apiToken") String apiToken, @Body PurchaseValidationRequest request); } 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 fba1dd32d..12cd681d2 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 @@ -7,10 +7,10 @@ import rx.Observable; public interface MaintenanceApiService { - @GET("/maintenance-android.json") + @GET("maintenance-android.json") Observable getMaintenanceStatus(); - @GET("/deprecation-android.json") + @GET("deprecation-android.json") Observable getDepricationStatus(); } diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java index bd91441cd..bd482c0cf 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java @@ -106,6 +106,9 @@ public class Task extends BaseModel { // used for buyable items public String specialTag; + public CharSequence parsedText; + public CharSequence parsedNotes; + /** * @return the id */