From 246926f23fbb0b920d11312cd10b295066fabe6b Mon Sep 17 00:00:00 2001 From: Negue Date: Wed, 3 Aug 2016 00:12:15 +0200 Subject: [PATCH 01/21] fullprofile: show avatar / stats / attributes / equipment --- Habitica/AndroidManifest.xml | 10 + Habitica/res/layout/activity_full_profile.xml | 240 +++++++++++ .../layout/fullprofile_attributetablerow.xml | 20 + ...rofile_attributetablerow_two_textviews.xml | 17 + .../layout/fullprofile_equipment_tablerow.xml | 19 + .../fullprofile_tablerow_two_textviews.xml | 16 + Habitica/res/menu/menu_full_profile.xml | 11 + .../habitrpg/android/habitica/APIHelper.java | 5 + .../android/habitica/ContentCache.java | 13 +- .../android/habitica/HabiticaApplication.java | 4 +- .../habitica/components/AppComponent.java | 3 + .../commands/OpenFullProfileCommand.java | 9 + .../habitica/ui/AvatarWithBarsViewModel.java | 10 + .../ui/activities/FullProfileActivity.java | 372 ++++++++++++++++++ .../habitica/ui/activities/IntroActivity.java | 2 +- .../habitica/ui/activities/MainActivity.java | 2 +- .../PartyMemberRecyclerViewAdapter.java | 14 + .../tasks/RewardsRecyclerViewAdapter.java | 3 +- .../customization/AvatarOverviewFragment.java | 2 +- .../ui/fragments/social/TavernFragment.java | 4 +- .../fragments/social/party/PartyFragment.java | 18 +- .../habitrpgwrapper/lib/api/ApiService.java | 5 +- .../habitrpgwrapper/lib/models/Stats.java | 2 +- 23 files changed, 789 insertions(+), 12 deletions(-) create mode 100644 Habitica/res/layout/activity_full_profile.xml create mode 100644 Habitica/res/layout/fullprofile_attributetablerow.xml create mode 100644 Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml create mode 100644 Habitica/res/layout/fullprofile_equipment_tablerow.xml create mode 100644 Habitica/res/layout/fullprofile_tablerow_two_textviews.xml create mode 100644 Habitica/res/menu/menu_full_profile.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/OpenFullProfileCommand.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 832b03c34..82496d97e 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -110,6 +110,16 @@ tools:ignore="UnusedAttribute" android:label="@string/invite_users"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_attributetablerow.xml b/Habitica/res/layout/fullprofile_attributetablerow.xml new file mode 100644 index 000000000..5c503aac6 --- /dev/null +++ b/Habitica/res/layout/fullprofile_attributetablerow.xml @@ -0,0 +1,20 @@ + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml b/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml new file mode 100644 index 000000000..34efeb799 --- /dev/null +++ b/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_equipment_tablerow.xml b/Habitica/res/layout/fullprofile_equipment_tablerow.xml new file mode 100644 index 000000000..92f2fdbed --- /dev/null +++ b/Habitica/res/layout/fullprofile_equipment_tablerow.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml b/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml new file mode 100644 index 000000000..4c3af311e --- /dev/null +++ b/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/Habitica/res/menu/menu_full_profile.xml b/Habitica/res/menu/menu_full_profile.xml new file mode 100644 index 000000000..2cf30c415 --- /dev/null +++ b/Habitica/res/menu/menu_full_profile.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file 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 122b4cb6d..1b5926217 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/APIHelper.java @@ -82,6 +82,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.net.ssl.SSLException; @@ -120,6 +121,8 @@ public class APIHelper implements Action1 { private final Retrofit retrofitAdapter; private AlertDialog displayedAlert; + public String languageCode; + //private OnHabitsAPIResult mResultListener; //private HostConfig mConfig; public APIHelper(GsonConverterFactory gsonConverter, HostConfig hostConfig) { @@ -129,6 +132,8 @@ public class APIHelper implements Action1 { Crashlytics.getInstance().core.setUserName(this.hostConfig.getUser()); Amplitude.getInstance().setUserId(this.hostConfig.getUser()); + languageCode = Locale.getDefault().getLanguage(); + Interceptor remove_data_interceptor = chain -> { Response response = chain.proceed(chain.request()); String stringJson = response.body().string(); 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 dc8c09b25..7413c5b22 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ContentCache.java @@ -19,10 +19,17 @@ import rx.schedulers.Schedulers; public class ContentCache { private ApiService apiService; + private String language; + public ContentCache(ApiService apiService) { - this.apiService = apiService; + this.language = "en"; + } + + public ContentCache(ApiService apiService, String language) { + this.apiService = apiService; + this.language = language; } public void GetQuestContent(final String key, final QuestContentCallback cb) { @@ -73,7 +80,7 @@ public class ContentCache { } private void getContentAndSearchFor(final String typeOfSearch, final String searchKey, final GotContentEntryCallback gotEntry) { - apiService.getContent() + apiService.getContent(language) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(contentResult -> { @@ -117,7 +124,7 @@ public class ContentCache { private void getContentAndSearchForList(final String typeOfSearch, final List searchKeys, final GotContentEntryCallback> gotEntry) { List resultList = new ArrayList<>(); - apiService.getContent() + apiService.getContent(language) .flatMap(contentResult -> { List itemList = new ArrayList(contentResult.gear.flat); itemList.add(contentResult.potion); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaApplication.java b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaApplication.java index 80871a2f9..21b755a6f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaApplication.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaApplication.java @@ -150,7 +150,9 @@ public class HabiticaApplication extends MultiDexApplication { int lastInstalledVersion = sharedPrefs.getInt("last_installed_version", 0); if (lastInstalledVersion < info.versionCode) { sharedPrefs.edit().putInt("last_installed_version", info.versionCode).apply(); - this.lazyApiHelper.get().apiService.getContent() + APIHelper apiHelper = this.lazyApiHelper.get(); + + apiHelper.apiService.getContent(apiHelper.languageCode) .compose(this.lazyApiHelper.get().configureApiCallObserver()) .subscribe(contentResult -> { }, throwable -> { 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 1f4a1450e..0527d3509 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 @@ -5,6 +5,7 @@ import com.habitrpg.android.habitica.modules.ApiModule; import com.habitrpg.android.habitica.modules.AppModule; import com.habitrpg.android.habitica.ui.activities.AboutActivity; import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity; +import com.habitrpg.android.habitica.ui.activities.FullProfileActivity; import com.habitrpg.android.habitica.ui.activities.GroupFormActivity; import com.habitrpg.android.habitica.ui.activities.IntroActivity; import com.habitrpg.android.habitica.ui.activities.LoginActivity; @@ -156,4 +157,6 @@ public interface AppComponent { void inject(ShopsFragment shopsFragment); void inject(ShopFragment shopFragment); + + void inject(FullProfileActivity fullProfileActivity); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/OpenFullProfileCommand.java b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/OpenFullProfileCommand.java new file mode 100644 index 000000000..2b288b741 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/events/commands/OpenFullProfileCommand.java @@ -0,0 +1,9 @@ +package com.habitrpg.android.habitica.events.commands; + +public class OpenFullProfileCommand { + public String MemberId; + + public OpenFullProfileCommand(String memberId){ + MemberId = memberId; + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.java index a82a4a0f0..8d5005b8d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.java @@ -193,4 +193,14 @@ public class AvatarWithBarsViewModel implements View.OnClickListener { EventBus.getDefault().post(new OpenGemPurchaseFragmentCommand()); } + + public void hideGems() { + gemsText.setVisibility(View.GONE); + } + + public void valueBarLabelsToBlack() { + hpBar.setPartyMembers(true); + mpBar.setPartyMembers(true); + xpBar.setPartyMembers(true); + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java new file mode 100644 index 000000000..399864509 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -0,0 +1,372 @@ +package com.habitrpg.android.habitica.ui.activities; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; + +import com.habitrpg.android.habitica.APIHelper; +import com.habitrpg.android.habitica.ContentCache; +import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.components.AppComponent; +import com.habitrpg.android.habitica.ui.AvatarView; +import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; +import com.magicmicky.habitrpgwrapper.lib.models.Buffs; +import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; +import com.magicmicky.habitrpgwrapper.lib.models.Outfit; +import com.magicmicky.habitrpgwrapper.lib.models.Profile; +import com.magicmicky.habitrpgwrapper.lib.models.Stats; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import butterknife.BindView; + +public class FullProfileActivity extends BaseActivity { + private String userId; + private ContentCache contentCache; + + @Inject + APIHelper apiHelper; + + @BindView(R.id.profile_image) + ImageView profile_image; + + @BindView(R.id.profile_blurb) + TextView blurbTextView; + + @BindView(R.id.avatarView) + AvatarView avatarView; + + @BindView(R.id.attributes_table) + TableLayout attributesTableLayout; + + @BindView(R.id.equipment_table) + TableLayout equipmentTableLayout; + + @BindView(R.id.avatar_attributes_progress) + ProgressBar attributesProgress; + + @BindView(R.id.avatar_equip_progress) + ProgressBar equipmentProgress; + + @BindView(R.id.avatar_with_bars) + View avatar_with_bars; + private AvatarWithBarsViewModel avatarWithBars; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + Bundle bundle = intent.getExtras(); + this.userId = bundle.getString("userId"); + + setTitle("loading member data.."); + + apiHelper.apiService.GetMember(this.userId) + .compose(apiHelper.configureApiCallObserver()) + .subscribe(habitRPGUser -> updateView(habitRPGUser), + throwable -> {}); + + this.contentCache = new ContentCache(apiHelper.apiService, apiHelper.languageCode); + + avatarWithBars = new AvatarWithBarsViewModel(this, avatar_with_bars); + avatarWithBars.hideGems(); + avatarWithBars.valueBarLabelsToBlack(); + + avatar_with_bars.setBackgroundColor(getResources().getColor(R.color.transparent)); + } + + private void updateView(HabitRPGUser user) { + Profile profile = user.getProfile(); + Stats stats = user.getStats(); + + setTitle(profile.getName()); + + String imageUrl = profile.getImageUrl(); + if (imageUrl == null || imageUrl.isEmpty()) { + profile_image.setVisibility(View.INVISIBLE); + } else { + profile_image.setImageURI(Uri.parse(imageUrl)); + } + + String blurbText = profile.getBlurb(); + if (blurbText != null && !blurbText.isEmpty()) { + blurbTextView.setText(blurbText); + } + + avatarView.setUser(user); + avatarWithBars.updateData(user); + + addLevelAttributes(stats, user); + } + + // region Utils + + private String upperCaseFirstLetter(String s){ + return Character.toUpperCase(s.charAt(0)) + s.substring(1); + } + + private void stopAndHideProgress(ProgressBar bar){ + bar.setIndeterminate(false); + bar.setVisibility(View.GONE); + } + + private String getCeiledValue(float val){ + return ((int)Math.ceil(val)) + ""; + } + + private void addAttributeRow(TableLayout table, String key, float val){ + int intVal = (int) Math.ceil(val); + + if(intVal == 0) + return; + + addTableRow(table, key, intVal+"", R.layout.fullprofile_attributetablerow_two_textviews); + } + + private void addTableRow(TableLayout table, String key, float val){ + int intVal = (int) Math.ceil(val); + + if(intVal == 0) + return; + + addTableRow(table, key, intVal+"", R.layout.fullprofile_tablerow_two_textviews); + } + + private void addTableRow(TableLayout table, String key, String value){ + addTableRow(table, key, value, R.layout.fullprofile_tablerow_two_textviews); + } + + private void addTableRow(TableLayout table, String key, String value, int resourceId){ + TableRow tableRow = (TableRow)getLayoutInflater().inflate(resourceId, null); + + TextView keyTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView1); + keyTextView.setText(key); + + TextView valueTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView2); + valueTextView.setText(value); + + table.addView(tableRow); + } + + // endregion + + // region Stats + + StatHelper strHelper; + StatHelper intHelper; + StatHelper conHelper; + StatHelper perHelper; + + private void addLevelAttributes(Stats stats, HabitRPGUser user) + { + float byLevelStat = stats.getLvl()/2.0f; + + strHelper = getStatHelper("Strength: "); + strHelper.add("Level: ", byLevelStat); + + intHelper = getStatHelper("Intelligence:"); + intHelper.add("Level: ", byLevelStat); + + conHelper = getStatHelper("Constitution:"); + conHelper.add("Level: ", byLevelStat); + + perHelper = getStatHelper("Perception:"); + perHelper.add("Level: ", byLevelStat); + + Outfit outfit = user.getItems().getGear().getEquipped(); + + ArrayList outfitList = new ArrayList<>(); + outfitList.add(outfit.getArmor()); + outfitList.add(outfit.getBack()); + outfitList.add(outfit.getBody()); + outfitList.add(outfit.getEyeWear()); + outfitList.add(outfit.getHead()); + outfitList.add(outfit.getHeadAccessory()); + outfitList.add(outfit.getShield()); + outfitList.add(outfit.getWeapon()); + + contentCache.GetItemDataList(outfitList, obj ->{ + GotGear(obj, user); + addNormalAddBuffAttributes(stats); + + stopAndHideProgress(attributesProgress); + attributesTableLayout.setVisibility(View.VISIBLE); + }); + } + + public void GotGear(List obj, HabitRPGUser user) { + float strAttributes = 0; + float intAttributes = 0; + float conAttributes = 0; + float perAttributes = 0; + + // Summarize stats and fill equipment table + for (ItemData i : obj){ + int str_ = (int)i.getStr(); + int int_ = (int)i.get_int(); + int con_ = (int)i.getCon(); + int per_ = (int) i.getPer(); + + strAttributes+= str_; + intAttributes+= int_; + conAttributes+= con_; + perAttributes+= per_; + + StringBuilder sb = new StringBuilder(); + + if(str_ != 0){ + sb.append("STR "+str_+", "); + } + if(int_ != 0){ + sb.append("INT "+int_+", "); + } + if(con_ != 0){ + sb.append("CON "+con_+", "); + } + if(per_ != 0){ + sb.append("PER "+per_+", "); + } + + // remove the last comma + if(sb.length() > 2) + { + sb.delete(sb.length()-2, sb.length()); + } + + addTableRow(equipmentTableLayout,i.getText(), sb.toString(), R.layout.fullprofile_equipment_tablerow); + } + + stopAndHideProgress(equipmentProgress); + equipmentTableLayout.setVisibility(View.VISIBLE); + + strHelper.add("Equipment: ", strAttributes); + intHelper.add("Equipment: ", intAttributes); + conHelper.add("Equipment: ", conAttributes); + perHelper.add("Equipment: ", perAttributes); + + if(!user.getPreferences().isDisableClasses()){ + float strClassBonus = 0; + float intClassBonus = 0; + float conClassBonus = 0; + float perClassBonus = 0; + + switch(user.getStats().get_class()){ + case rogue: + strClassBonus = strAttributes * 0.5f; + perClassBonus = perAttributes * 0.5f; + break; + case healer: + conClassBonus = conAttributes * 0.5f; + intClassBonus = intClassBonus * 0.5f; + break; + case warrior: + strClassBonus = strAttributes * 0.5f; + conClassBonus = conAttributes * 0.5f; + break; + case wizard: + intClassBonus = intClassBonus * 0.5f; + perClassBonus = perAttributes * 0.5f; + break; + } + + strHelper.add("Class-Bonus: ", strClassBonus); + intHelper.add("Class-Bonus: ", intClassBonus); + conHelper.add("Class-Bonus: ", conClassBonus); + perHelper.add("Class-Bonus: ", perClassBonus); + } + } + + + private void addNormalAddBuffAttributes(Stats stats){ + Buffs buffs = stats.getBuffs(); + + strHelper.add("Allocated: ", stats.getStr()); + strHelper.add("Boosts: ", buffs.getStr()); + + intHelper.add("Allocated: ", stats.get_int()); + intHelper.add("Boosts: ", buffs.get_int()); + + conHelper.add("Allocated: ", stats.getCon()); + conHelper.add("Boosts: ", buffs.getCon()); + + perHelper.add("Allocated: ", stats.getPer()); + perHelper.add("Boosts: ", buffs.getPer()); + } + + private StatHelper getStatHelper(String label){ + TableRow tableRow = (TableRow)getLayoutInflater().inflate(R.layout.fullprofile_attributetablerow, null); + TextView keyTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView1); + + attributesTableLayout.addView(tableRow); + + TableLayout layout = (TableLayout)tableRow.findViewById(R.id.tableRowAttributesTable); + + return new StatHelper(layout, keyTextView, label); + } + + public class StatHelper + { + private TableLayout layout; + private TextView textViewLabel; + private String attributeName; + + public float currentStatCount = 0; + + public StatHelper(TableLayout layout, TextView label, String attributeName){ + this.layout = layout; + this.textViewLabel = label; + this.attributeName = attributeName; + } + + public void add(String label, float value){ + addAttributeRow(layout, label, value); + + currentStatCount += value; + + textViewLabel.setText(attributeName+" "+ getCeiledValue(currentStatCount)); + } + } + + // endregion + + // region Navigation + + @Override + public boolean onSupportNavigateUp() { + finish(); + return true; + } + + @Override + public void onBackPressed() { + finish(); + } + + // endregion + + // region BaseActivity-Overrides + + @Override + protected int getLayoutResId() { + return R.layout.activity_full_profile; + } + + @Override + protected void injectActivity(AppComponent component) { + component.inject(this); + } + + // endregion +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java index 7f8fda910..c8d4b797a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/IntroActivity.java @@ -49,7 +49,7 @@ public class IntroActivity extends BaseActivity implements View.OnClickListener, this.skipButton.setOnClickListener(this); this.finishButton.setOnClickListener(this); - apiHelper.apiService.getContent() + apiHelper.apiService.getContent(apiHelper.languageCode) .compose(apiHelper.configureApiCallObserver()) .subscribe(contentResult -> { }, throwable -> { 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 7c685e246..e92d26178 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 @@ -1096,7 +1096,7 @@ public class MainActivity extends BaseActivity implements Action1, Ha public void reloadContent(ReloadContentEvent event) { if (!this.isloadingContent) { this.isloadingContent = true; - this.apiHelper.apiService.getContent() + this.apiHelper.apiService.getContent(apiHelper.languageCode) .compose(apiHelper.configureApiCallObserver()) .subscribe(contentResult -> { isloadingContent = false; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java index ee5785daf..c2dfff0d6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java @@ -2,12 +2,15 @@ package com.habitrpg.android.habitica.ui.adapter.social; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.databinding.ValueBarBinding; +import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand; import com.habitrpg.android.habitica.ui.AvatarView; import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; +import com.habitrpg.android.habitica.ui.activities.SetupActivity; import com.habitrpg.android.habitica.ui.helpers.ViewHelper; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; import android.content.Context; +import android.content.Intent; import android.content.res.Resources; import android.databinding.DataBindingUtil; import android.support.v4.content.ContextCompat; @@ -17,6 +20,8 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import org.greenrobot.eventbus.EventBus; + import java.util.List; import butterknife.BindView; @@ -121,6 +126,15 @@ public class PartyMemberRecyclerViewAdapter extends RecyclerView.Adapter { + OpenFullProfileCommand cmd = new OpenFullProfileCommand(user.getId()); + + EventBus.getDefault().post(cmd); + }); } + + } } 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 3c4f5e3df..7eda76223 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 @@ -16,6 +16,7 @@ import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import rx.Observable; @@ -29,7 +30,7 @@ public class RewardsRecyclerViewAdapter extends BaseTasksRecyclerViewAdapter { }, throwable -> { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java index 28aa7ccea..9e93d1719 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.java @@ -14,6 +14,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import java.util.Locale; + public class TavernFragment extends BaseMainFragment { public ViewPager viewPager; @@ -60,7 +62,7 @@ public class TavernFragment extends BaseMainFragment { TavernFragment.this.tabLayout.setupWithViewPager(TavernFragment.this.viewPager); } - ContentCache contentCache = new ContentCache(apiHelper.apiService); + ContentCache contentCache = new ContentCache(apiHelper.apiService, apiHelper.languageCode); contentCache.GetQuestContent(group.quest.key, content -> { if (questInfoFragment != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java index 793b4221c..6eba7f258 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java @@ -3,6 +3,8 @@ package com.habitrpg.android.habitica.ui.fragments.social.party; import com.habitrpg.android.habitica.ContentCache; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.components.AppComponent; +import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand; +import com.habitrpg.android.habitica.ui.activities.FullProfileActivity; import com.habitrpg.android.habitica.ui.activities.GroupFormActivity; import com.habitrpg.android.habitica.ui.activities.PartyInviteActivity; import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment; @@ -25,6 +27,8 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import org.greenrobot.eventbus.Subscribe; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -53,7 +57,7 @@ public class PartyFragment extends BaseMainFragment { viewPager.setCurrentItem(0); - contentCache = new ContentCache(apiHelper.apiService); + contentCache = new ContentCache(apiHelper.apiService, apiHelper.languageCode); // Get the full group data if (this.user != null && this.user.getParty() != null && this.user.getParty().id != null) { @@ -338,4 +342,16 @@ public class PartyFragment extends BaseMainFragment { tabLayout.setupWithViewPager(viewPager); } } + + @Subscribe + public void onEvent(OpenFullProfileCommand cmd) + { + Bundle bundle = new Bundle(); + bundle.putString("userId", cmd.MemberId); + + Intent intent = new Intent(activity, FullProfileActivity.class); + intent.putExtras(bundle); + intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(intent); + } } 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 8a0a5f4ef..9c283b46e 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 @@ -47,7 +47,7 @@ public interface ApiService { Observable getStatus(); @GET("content") - Observable getContent(); + Observable getContent(@Query("language") String language); /* user API */ @@ -230,6 +230,9 @@ public interface ApiService { Observable validatePurchase(@Body PurchaseValidationRequest request); //Members URL + @GET("members/{mid}") + Observable GetMember(@Path("mid") String memberId); + @POST("members/send-private-message") Observable postPrivateMessage(@Body HashMap messageDetails); diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/Stats.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/Stats.java index 7a32284fa..9deb2cf18 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/Stats.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/Stats.java @@ -26,7 +26,7 @@ public class Stats extends PlayerMinStats { } public Integer getMaxHealth() { - return maxHealth != null ? maxHealth : Integer.valueOf(0); + return maxHealth != null ? maxHealth : Integer.valueOf(50); } public void setMaxHealth(Integer maxHealth) { From 3896d73e431b2fe947a187baece2d76362d47397 Mon Sep 17 00:00:00 2001 From: jjbillings Date: Wed, 3 Aug 2016 21:04:17 -0400 Subject: [PATCH 02/21] Add guild search bar --- .../layout/fragment_guild_recyclerview.xml | 35 +++++++++++++++ Habitica/res/values/strings.xml | 1 + .../PublicGuildsRecyclerViewAdapter.java | 43 ++++++++++++++++++- .../social/PublicGuildsFragment.java | 21 ++++++++- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 Habitica/res/layout/fragment_guild_recyclerview.xml diff --git a/Habitica/res/layout/fragment_guild_recyclerview.xml b/Habitica/res/layout/fragment_guild_recyclerview.xml new file mode 100644 index 000000000..2596c3177 --- /dev/null +++ b/Habitica/res/layout/fragment_guild_recyclerview.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 390d4b3b9..01c332fdb 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -243,6 +243,7 @@ To start, which parts of your life do you want to improve? Privacy Write Message Post + Search for guilds Due: %s current streak: %d diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java index 927526881..6677330e4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java @@ -13,21 +13,26 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.Filter; +import android.widget.Filterable; import android.widget.TextView; +import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; -public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter { +public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter implements Filterable{ public APIHelper apiHelper; private List publicGuildList; private List memberGuildIDs; + private List publicGuildListCopy; public void setPublicGuildList(List publicGuildList) { this.publicGuildList = publicGuildList; + this.publicGuildListCopy = new ArrayList<>(publicGuildList); this.notifyDataSetChanged(); } @@ -93,6 +98,42 @@ public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter filteredGuilds = null; + if(constraint.length() == 0) { + filteredGuilds = publicGuildListCopy; + } else { + filteredGuilds = getFilteredResults(constraint.toString().toLowerCase()); + } + + FilterResults results = new FilterResults(); + results.values = filteredGuilds; + return results; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + publicGuildList = (List) results.values; + PublicGuildsRecyclerViewAdapter.this.notifyDataSetChanged(); + } + }; + } + + protected List getFilteredResults(String constraint) { + List filteredGuilds = new ArrayList<>(); + + for(Group guild : publicGuildListCopy) { + if(guild.name.toLowerCase().contains(constraint)) { + filteredGuilds.add(guild); + } + } + + return filteredGuilds; + } static class GuildViewHolder extends RecyclerView.ViewHolder { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java index e58de9d6a..50a98adea 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java @@ -14,13 +14,14 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.SearchView; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; -public class PublicGuildsFragment extends BaseMainFragment { +public class PublicGuildsFragment extends BaseMainFragment implements SearchView.OnQueryTextListener { List memberGuildIDs; List guilds; @@ -30,13 +31,17 @@ public class PublicGuildsFragment extends BaseMainFragment { private View view; private PublicGuildsRecyclerViewAdapter viewAdapter; + private SearchView guildSearchView; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); if (view == null) { - view = inflater.inflate(R.layout.fragment_recyclerview, container, false); + view = inflater.inflate(R.layout.fragment_guild_recyclerview, container, false); + + guildSearchView = (SearchView)view.findViewById(R.id.guild_search_view); + guildSearchView.setOnQueryTextListener(this); unbinder = ButterKnife.bind(this, view); recyclerView.setLayoutManager(new LinearLayoutManager(this.activity)); @@ -76,4 +81,16 @@ public class PublicGuildsFragment extends BaseMainFragment { }); } } + + @Override + public boolean onQueryTextSubmit(String s) { + viewAdapter.getFilter().filter(s); + return true; + } + + @Override + public boolean onQueryTextChange(String s) { + viewAdapter.getFilter().filter(s); + return true; + } } From 66ffcece3de225b4993dd64bb170f4783e4f01ea Mon Sep 17 00:00:00 2001 From: Negue Date: Thu, 4 Aug 2016 23:11:39 +0200 Subject: [PATCH 03/21] Equipment / Costume Gear with Image, Attributes as grid --- Habitica/res/layout/activity_full_profile.xml | 138 ++++++--- .../layout/fullprofile_attributetablerow.xml | 33 +- ...rofile_attributetablerow_two_textviews.xml | 17 -- .../layout/fullprofile_equipment_tablerow.xml | 19 -- .../res/layout/fullprofile_gear_tablerow.xml | 39 +++ .../fullprofile_tablerow_two_textviews.xml | 16 - .../ui/activities/FullProfileActivity.java | 287 ++++++++++-------- 7 files changed, 302 insertions(+), 247 deletions(-) delete mode 100644 Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml delete mode 100644 Habitica/res/layout/fullprofile_equipment_tablerow.xml create mode 100644 Habitica/res/layout/fullprofile_gear_tablerow.xml delete mode 100644 Habitica/res/layout/fullprofile_tablerow_two_textviews.xml diff --git a/Habitica/res/layout/activity_full_profile.xml b/Habitica/res/layout/activity_full_profile.xml index 51752bd6c..075a828c7 100644 --- a/Habitica/res/layout/activity_full_profile.xml +++ b/Habitica/res/layout/activity_full_profile.xml @@ -1,6 +1,7 @@ @@ -9,37 +10,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - - - - - - - - - + + + + + @@ -194,11 +179,43 @@ + android:layout_height="wrap_content" + android:shrinkColumns="1" + android:stretchColumns="0" /> + + + - + + + + + + @@ -211,29 +228,54 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="5dp"> + android:padding="5dp" + android:weightSum="1"> - + android:stretchColumns="0,1,2,3,4" + android:id="@+id/attributes_table"> + + + + + + + + + + + + + + + + + - - - - diff --git a/Habitica/res/layout/fullprofile_attributetablerow.xml b/Habitica/res/layout/fullprofile_attributetablerow.xml index 5c503aac6..eea653cb4 100644 --- a/Habitica/res/layout/fullprofile_attributetablerow.xml +++ b/Habitica/res/layout/fullprofile_attributetablerow.xml @@ -1,20 +1,27 @@ + android:layout_marginBottom="5dp" + android:layout_marginTop="5dp"> + android:id="@+id/tv_attribute_type" + android:layout_margin="5dp" + android:gravity="left" /> - + + + + + + + - \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml b/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml deleted file mode 100644 index 34efeb799..000000000 --- a/Habitica/res/layout/fullprofile_attributetablerow_two_textviews.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_equipment_tablerow.xml b/Habitica/res/layout/fullprofile_equipment_tablerow.xml deleted file mode 100644 index 92f2fdbed..000000000 --- a/Habitica/res/layout/fullprofile_equipment_tablerow.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_gear_tablerow.xml b/Habitica/res/layout/fullprofile_gear_tablerow.xml new file mode 100644 index 000000000..f4acb571e --- /dev/null +++ b/Habitica/res/layout/fullprofile_gear_tablerow.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml b/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml deleted file mode 100644 index 4c3af311e..000000000 --- a/Habitica/res/layout/fullprofile_tablerow_two_textviews.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java index 399864509..7f72bda5a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -1,15 +1,24 @@ package com.habitrpg.android.habitica.ui.activities; import android.content.Intent; +import android.graphics.Typeface; +import android.graphics.drawable.Animatable; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.Nullable; import android.view.View; +import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; +import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.drawee.controller.BaseControllerListener; +import com.facebook.drawee.view.SimpleDraweeView; +import com.facebook.imagepipeline.image.ImageInfo; import com.habitrpg.android.habitica.APIHelper; import com.habitrpg.android.habitica.ContentCache; import com.habitrpg.android.habitica.R; @@ -38,7 +47,7 @@ public class FullProfileActivity extends BaseActivity { APIHelper apiHelper; @BindView(R.id.profile_image) - ImageView profile_image; + SimpleDraweeView profile_image; @BindView(R.id.profile_blurb) TextView blurbTextView; @@ -52,12 +61,18 @@ public class FullProfileActivity extends BaseActivity { @BindView(R.id.equipment_table) TableLayout equipmentTableLayout; + @BindView(R.id.costume_table) + TableLayout costumeTableLayout; + @BindView(R.id.avatar_attributes_progress) ProgressBar attributesProgress; @BindView(R.id.avatar_equip_progress) ProgressBar equipmentProgress; + @BindView(R.id.avatar_costume_progress) + ProgressBar costumeProgress; + @BindView(R.id.avatar_with_bars) View avatar_with_bars; private AvatarWithBarsViewModel avatarWithBars; @@ -76,7 +91,8 @@ public class FullProfileActivity extends BaseActivity { apiHelper.apiService.GetMember(this.userId) .compose(apiHelper.configureApiCallObserver()) .subscribe(habitRPGUser -> updateView(habitRPGUser), - throwable -> {}); + throwable -> { + }); this.contentCache = new ContentCache(apiHelper.apiService, apiHelper.languageCode); @@ -95,9 +111,17 @@ public class FullProfileActivity extends BaseActivity { String imageUrl = profile.getImageUrl(); if (imageUrl == null || imageUrl.isEmpty()) { - profile_image.setVisibility(View.INVISIBLE); + profile_image.setVisibility(View.GONE); } else { - profile_image.setImageURI(Uri.parse(imageUrl)); + profile_image.setController(Fresco.newDraweeControllerBuilder() + .setUri(imageUrl) + .setControllerListener(new BaseControllerListener() { + @Override + public void onFailure(String id, Throwable throwable) { + profile_image.setVisibility(View.GONE); + } + }) + .build()); } String blurbText = profile.getBlurb(); @@ -113,80 +137,85 @@ public class FullProfileActivity extends BaseActivity { // region Utils - private String upperCaseFirstLetter(String s){ - return Character.toUpperCase(s.charAt(0)) + s.substring(1); - } - - private void stopAndHideProgress(ProgressBar bar){ + private void stopAndHideProgress(ProgressBar bar) { bar.setIndeterminate(false); bar.setVisibility(View.GONE); } - private String getCeiledValue(float val){ - return ((int)Math.ceil(val)) + ""; + private String getCeiledValue(float val) { + return ((int) Math.ceil(val)) + ""; } - private void addAttributeRow(TableLayout table, String key, float val){ - int intVal = (int) Math.ceil(val); + private void addTableRow(TableLayout table, String key, String value, int resourceId) { + TableRow tableRow = (TableRow) getLayoutInflater().inflate(resourceId, null); - if(intVal == 0) - return; - - addTableRow(table, key, intVal+"", R.layout.fullprofile_attributetablerow_two_textviews); - } - - private void addTableRow(TableLayout table, String key, float val){ - int intVal = (int) Math.ceil(val); - - if(intVal == 0) - return; - - addTableRow(table, key, intVal+"", R.layout.fullprofile_tablerow_two_textviews); - } - - private void addTableRow(TableLayout table, String key, String value){ - addTableRow(table, key, value, R.layout.fullprofile_tablerow_two_textviews); - } - - private void addTableRow(TableLayout table, String key, String value, int resourceId){ - TableRow tableRow = (TableRow)getLayoutInflater().inflate(resourceId, null); - - TextView keyTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView1); + TextView keyTextView = (TextView) tableRow.findViewById(R.id.tableRowTextView1); keyTextView.setText(key); - TextView valueTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView2); + TextView valueTextView = (TextView) tableRow.findViewById(R.id.tableRowTextView2); valueTextView.setText(value); table.addView(tableRow); } + private TableRow addEquipmentRow(TableLayout table, String gearKey, String text, String stats) { + TableRow gearRow = (TableRow) getLayoutInflater().inflate(R.layout.fullprofile_gear_tablerow, null); + + SimpleDraweeView draweeView = (SimpleDraweeView) gearRow.findViewById(R.id.gear_drawee); + + draweeView.setController(Fresco.newDraweeControllerBuilder() + .setUri(AvatarView.IMAGE_URI_ROOT + "shop_" + gearKey + ".png") + .setControllerListener(new BaseControllerListener() { + @Override + public void onFailure(String id, Throwable throwable) { + draweeView.setVisibility(View.GONE); + } + }) + .build()); + + TextView keyTextView = (TextView) gearRow.findViewById(R.id.tableRowTextView1); + keyTextView.setText(text); + + table.addView(gearRow); + + TextView valueTextView = (TextView) gearRow.findViewById(R.id.tableRowTextView2); + + if (!stats.isEmpty()) { + valueTextView.setText(stats); + } else { + valueTextView.setVisibility(View.GONE); + } + + return gearRow; + } + // endregion // region Stats - StatHelper strHelper; - StatHelper intHelper; - StatHelper conHelper; - StatHelper perHelper; + private float attributeStrSum = 0; + private float attributeIntSum = 0; + private float attributeConSum = 0; + private float attributePerSum = 0; - private void addLevelAttributes(Stats stats, HabitRPGUser user) - { - float byLevelStat = stats.getLvl()/2.0f; + private void addLevelAttributes(Stats stats, HabitRPGUser user) { + float byLevelStat = stats.getLvl() / 2.0f; - strHelper = getStatHelper("Strength: "); - strHelper.add("Level: ", byLevelStat); + addAttributeRow("Level: ", byLevelStat, byLevelStat, byLevelStat, byLevelStat, false); - intHelper = getStatHelper("Intelligence:"); - intHelper.add("Level: ", byLevelStat); + LoadItemDataByOutfit(user.getItems().getGear().getEquipped(), obj -> { + GotGear(obj, user); + addNormalAddBuffAttributes(stats); - conHelper = getStatHelper("Constitution:"); - conHelper.add("Level: ", byLevelStat); + stopAndHideProgress(attributesProgress); + }); - perHelper = getStatHelper("Perception:"); - perHelper.add("Level: ", byLevelStat); - - Outfit outfit = user.getItems().getGear().getEquipped(); + LoadItemDataByOutfit(user.getItems().getGear().getCostume(), obj -> { + GotCostume(obj); + }); + } + private void LoadItemDataByOutfit(Outfit outfit, ContentCache.GotContentEntryCallback> gotEntries) { ArrayList outfitList = new ArrayList<>(); outfitList.add(outfit.getArmor()); outfitList.add(outfit.getBack()); @@ -197,13 +226,7 @@ public class FullProfileActivity extends BaseActivity { outfitList.add(outfit.getShield()); outfitList.add(outfit.getWeapon()); - contentCache.GetItemDataList(outfitList, obj ->{ - GotGear(obj, user); - addNormalAddBuffAttributes(stats); - - stopAndHideProgress(attributesProgress); - attributesTableLayout.setVisibility(View.VISIBLE); - }); + contentCache.GetItemDataList(outfitList, gotEntries); } public void GotGear(List obj, HabitRPGUser user) { @@ -213,56 +236,52 @@ public class FullProfileActivity extends BaseActivity { float perAttributes = 0; // Summarize stats and fill equipment table - for (ItemData i : obj){ - int str_ = (int)i.getStr(); - int int_ = (int)i.get_int(); - int con_ = (int)i.getCon(); + for (ItemData i : obj) { + int str_ = (int) i.getStr(); + int int_ = (int) i.get_int(); + int con_ = (int) i.getCon(); int per_ = (int) i.getPer(); - strAttributes+= str_; - intAttributes+= int_; - conAttributes+= con_; - perAttributes+= per_; + strAttributes += str_; + intAttributes += int_; + conAttributes += con_; + perAttributes += per_; StringBuilder sb = new StringBuilder(); - if(str_ != 0){ - sb.append("STR "+str_+", "); + if (str_ != 0) { + sb.append("STR " + str_ + ", "); } - if(int_ != 0){ - sb.append("INT "+int_+", "); + if (int_ != 0) { + sb.append("INT " + int_ + ", "); } - if(con_ != 0){ - sb.append("CON "+con_+", "); + if (con_ != 0) { + sb.append("CON " + con_ + ", "); } - if(per_ != 0){ - sb.append("PER "+per_+", "); + if (per_ != 0) { + sb.append("PER " + per_ + ", "); } // remove the last comma - if(sb.length() > 2) - { - sb.delete(sb.length()-2, sb.length()); + if (sb.length() > 2) { + sb.delete(sb.length() - 2, sb.length()); } - addTableRow(equipmentTableLayout,i.getText(), sb.toString(), R.layout.fullprofile_equipment_tablerow); + addEquipmentRow(equipmentTableLayout, i.getKey(), i.getText(), sb.toString()); } stopAndHideProgress(equipmentProgress); equipmentTableLayout.setVisibility(View.VISIBLE); - strHelper.add("Equipment: ", strAttributes); - intHelper.add("Equipment: ", intAttributes); - conHelper.add("Equipment: ", conAttributes); - perHelper.add("Equipment: ", perAttributes); + addAttributeRow("Equipment: ", strAttributes, intAttributes, conAttributes, perAttributes, false); - if(!user.getPreferences().isDisableClasses()){ + if (!user.getPreferences().isDisableClasses()) { float strClassBonus = 0; float intClassBonus = 0; float conClassBonus = 0; float perClassBonus = 0; - switch(user.getStats().get_class()){ + switch (user.getStats().get_class()) { case rogue: strClassBonus = strAttributes * 0.5f; perClassBonus = perAttributes * 0.5f; @@ -281,62 +300,62 @@ public class FullProfileActivity extends BaseActivity { break; } - strHelper.add("Class-Bonus: ", strClassBonus); - intHelper.add("Class-Bonus: ", intClassBonus); - conHelper.add("Class-Bonus: ", conClassBonus); - perHelper.add("Class-Bonus: ", perClassBonus); + addAttributeRow("Class-Bonus: ", strClassBonus, intClassBonus, conClassBonus, perClassBonus, false); } } + public void GotCostume(List obj) { + // fill costume table + for (ItemData i : obj) { + addEquipmentRow(costumeTableLayout, i.getKey(), i.getText(), ""); + } - private void addNormalAddBuffAttributes(Stats stats){ - Buffs buffs = stats.getBuffs(); - - strHelper.add("Allocated: ", stats.getStr()); - strHelper.add("Boosts: ", buffs.getStr()); - - intHelper.add("Allocated: ", stats.get_int()); - intHelper.add("Boosts: ", buffs.get_int()); - - conHelper.add("Allocated: ", stats.getCon()); - conHelper.add("Boosts: ", buffs.getCon()); - - perHelper.add("Allocated: ", stats.getPer()); - perHelper.add("Boosts: ", buffs.getPer()); + stopAndHideProgress(costumeProgress); } - private StatHelper getStatHelper(String label){ - TableRow tableRow = (TableRow)getLayoutInflater().inflate(R.layout.fullprofile_attributetablerow, null); - TextView keyTextView = (TextView)tableRow.findViewById(R.id.tableRowTextView1); + + private void addNormalAddBuffAttributes(Stats stats) { + Buffs buffs = stats.getBuffs(); + + addAttributeRow("Allocated: ", stats.getStr(), stats.get_int(), stats.getCon(), stats.getPer(), false); + addAttributeRow("Boosts: ", buffs.getStr(), buffs.get_int(), buffs.getCon(), buffs.getPer(), false); + + addAttributeRow("", attributeStrSum, attributeIntSum, attributeConSum, attributePerSum, true); + } + + private TableRow addAttributeRow(String label, float strVal, float intVal, float conVal, float perVal, boolean isSummary) { + TableRow tableRow = (TableRow) getLayoutInflater().inflate(R.layout.fullprofile_attributetablerow, null); + TextView keyTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_type); + keyTextView.setText(label); + + TextView strTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_str); + strTextView.setText(getCeiledValue(strVal)); + + TextView intTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_int); + intTextView.setText(getCeiledValue(intVal)); + + TextView conTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_con); + conTextView.setText(getCeiledValue(conVal)); + + TextView perTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_per); + perTextView.setText(getCeiledValue(perVal)); + + + if (isSummary) { + strTextView.setTypeface(null, Typeface.BOLD); + intTextView.setTypeface(null, Typeface.BOLD); + conTextView.setTypeface(null, Typeface.BOLD); + perTextView.setTypeface(null, Typeface.BOLD); + } else { + attributeStrSum += strVal; + attributeIntSum += intVal; + attributeConSum += conVal; + attributePerSum += perVal; + } attributesTableLayout.addView(tableRow); - TableLayout layout = (TableLayout)tableRow.findViewById(R.id.tableRowAttributesTable); - - return new StatHelper(layout, keyTextView, label); - } - - public class StatHelper - { - private TableLayout layout; - private TextView textViewLabel; - private String attributeName; - - public float currentStatCount = 0; - - public StatHelper(TableLayout layout, TextView label, String attributeName){ - this.layout = layout; - this.textViewLabel = label; - this.attributeName = attributeName; - } - - public void add(String label, float value){ - addAttributeRow(layout, label, value); - - currentStatCount += value; - - textViewLabel.setText(attributeName+" "+ getCeiledValue(currentStatCount)); - } + return tableRow; } // endregion From 1629c8cde68346a51d90b71f274f90e07f398350 Mon Sep 17 00:00:00 2001 From: Negue Date: Sat, 6 Aug 2016 16:32:15 +0200 Subject: [PATCH 04/21] Send messages to members from profile view --- Habitica/res/layout/activity_full_profile.xml | 3 +- .../layout/fullprofile_new_message_dialog.xml | 41 ++++++++ Habitica/res/menu/menu_full_profile.xml | 1 + .../ui/activities/FullProfileActivity.java | 95 ++++++++++++++++--- 4 files changed, 127 insertions(+), 13 deletions(-) create mode 100644 Habitica/res/layout/fullprofile_new_message_dialog.xml diff --git a/Habitica/res/layout/activity_full_profile.xml b/Habitica/res/layout/activity_full_profile.xml index 075a828c7..ac46afd9f 100644 --- a/Habitica/res/layout/activity_full_profile.xml +++ b/Habitica/res/layout/activity_full_profile.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:id="@+id/fullprofile_scrollview"> + + + + + + + + + + + + + + diff --git a/Habitica/res/menu/menu_full_profile.xml b/Habitica/res/menu/menu_full_profile.xml index 2cf30c415..cef8c90ac 100644 --- a/Habitica/res/menu/menu_full_profile.xml +++ b/Habitica/res/menu/menu_full_profile.xml @@ -5,6 +5,7 @@ tools:context=".ui.activities.TaskFormActivity"> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java index 7f72bda5a..e9ccbba4a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -6,11 +6,19 @@ import android.graphics.drawable.Animatable; import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; +import android.support.v4.util.ArrayMap; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.ScrollView; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; @@ -21,10 +29,15 @@ import com.facebook.drawee.view.SimpleDraweeView; import com.facebook.imagepipeline.image.ImageInfo; import com.habitrpg.android.habitica.APIHelper; import com.habitrpg.android.habitica.ContentCache; +import com.habitrpg.android.habitica.HabiticaApplication; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.components.AppComponent; +import com.habitrpg.android.habitica.events.commands.SendNewInboxMessageCommand; import com.habitrpg.android.habitica.ui.AvatarView; import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; +import com.habitrpg.android.habitica.ui.fragments.social.InboxMessageListFragment; +import com.habitrpg.android.habitica.ui.helpers.EmojiKeyboard; +import com.habitrpg.android.habitica.ui.helpers.UiUtils; import com.magicmicky.habitrpgwrapper.lib.models.Buffs; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; import com.magicmicky.habitrpgwrapper.lib.models.Outfit; @@ -32,7 +45,12 @@ import com.magicmicky.habitrpgwrapper.lib.models.Profile; import com.magicmicky.habitrpgwrapper.lib.models.Stats; import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; +import net.pherth.android.emoji_library.EmojiEditText; + +import org.greenrobot.eventbus.EventBus; + import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import javax.inject.Inject; @@ -41,6 +59,7 @@ import butterknife.BindView; public class FullProfileActivity extends BaseActivity { private String userId; + private String userName; private ContentCache contentCache; @Inject @@ -77,6 +96,8 @@ public class FullProfileActivity extends BaseActivity { View avatar_with_bars; private AvatarWithBarsViewModel avatarWithBars; + @BindView(R.id.fullprofile_scrollview) + ScrollView fullprofile_scrollview; @Override protected void onCreate(Bundle savedInstanceState) { @@ -103,10 +124,65 @@ public class FullProfileActivity extends BaseActivity { avatar_with_bars.setBackgroundColor(getResources().getColor(R.color.transparent)); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id == R.id.private_message) { + LayoutInflater factory = LayoutInflater.from(this); + final View newMessageView = factory.inflate( + R.layout.fullprofile_new_message_dialog, null); + + EmojiEditText emojiEditText = (EmojiEditText)newMessageView.findViewById(R.id.edit_new_message_text); + + TextView newMessageTitle = (TextView)newMessageView.findViewById(R.id.new_message_title); + newMessageTitle.setText("Send message to "+userName); + + final AlertDialog addMessageDialog = new AlertDialog.Builder(this) + .setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { + HashMap messageObject = new HashMap<>(); + messageObject.put("message", emojiEditText.getText().toString()); + messageObject.put("toUserId", userId); + + apiHelper.apiService.postPrivateMessage(messageObject) + .compose(apiHelper.configureApiCallObserver()) + .subscribe(postChatMessageResult -> { + UiUtils.showSnackbar(FullProfileActivity.this, FullProfileActivity.this.fullprofile_scrollview, + "Message sent to "+userName, UiUtils.SnackbarDisplayType.NORMAL); + }, throwable -> { + }); + + UiUtils.dismissKeyboard(HabiticaApplication.currentActivity); + }) + .setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> { + + UiUtils.dismissKeyboard(HabiticaApplication.currentActivity); + }) + + .create(); + + addMessageDialog.setView(newMessageView); + + addMessageDialog.show(); + + return true; + } + + if (id == android.R.id.home) { + // app icon in action bar clicked; goto parent activity. + this.finish(); + return true; + } + + return super.onOptionsItemSelected(item); + } + private void updateView(HabitRPGUser user) { Profile profile = user.getProfile(); Stats stats = user.getStats(); + userName = profile.getName(); + setTitle(profile.getName()); String imageUrl = profile.getImageUrl(); @@ -146,18 +222,6 @@ public class FullProfileActivity extends BaseActivity { return ((int) Math.ceil(val)) + ""; } - private void addTableRow(TableLayout table, String key, String value, int resourceId) { - TableRow tableRow = (TableRow) getLayoutInflater().inflate(resourceId, null); - - TextView keyTextView = (TextView) tableRow.findViewById(R.id.tableRowTextView1); - keyTextView.setText(key); - - TextView valueTextView = (TextView) tableRow.findViewById(R.id.tableRowTextView2); - valueTextView.setText(value); - - table.addView(tableRow); - } - private TableRow addEquipmentRow(TableLayout table, String gearKey, String text, String stats) { TableRow gearRow = (TableRow) getLayoutInflater().inflate(R.layout.fullprofile_gear_tablerow, null); @@ -387,5 +451,12 @@ public class FullProfileActivity extends BaseActivity { component.inject(this); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_full_profile, menu); + return true; + } + // endregion } From b85a30de0acfbe380e3c2d646d4f6c120f88068e Mon Sep 17 00:00:00 2001 From: Jack Billings Date: Sun, 7 Aug 2016 19:30:40 -0500 Subject: [PATCH 05/21] Add guild search bar --- .../res/layout/fragment_guild_recyclerview.xml | 2 +- .../social/PublicGuildsRecyclerViewAdapter.java | 14 ++++++++------ .../ui/fragments/social/PublicGuildsFragment.java | 8 ++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Habitica/res/layout/fragment_guild_recyclerview.xml b/Habitica/res/layout/fragment_guild_recyclerview.xml index 2596c3177..96ef26ad3 100644 --- a/Habitica/res/layout/fragment_guild_recyclerview.xml +++ b/Habitica/res/layout/fragment_guild_recyclerview.xml @@ -8,7 +8,7 @@ + android:queryHint="@string/guild_search_hint"/> publicGuildList; + private List fullPublicGuildList; private List memberGuildIDs; - private List publicGuildListCopy; public void setPublicGuildList(List publicGuildList) { this.publicGuildList = publicGuildList; - this.publicGuildListCopy = new ArrayList<>(publicGuildList); + this.fullPublicGuildList = new ArrayList<>(publicGuildList); this.notifyDataSetChanged(); } @@ -98,14 +98,16 @@ public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter filteredGuilds = null; + if(constraint.length() == 0) { - filteredGuilds = publicGuildListCopy; + filteredGuilds = fullPublicGuildList; } else { filteredGuilds = getFilteredResults(constraint.toString().toLowerCase()); } @@ -123,11 +125,11 @@ public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter getFilteredResults(String constraint) { + protected List getFilteredResults(String query) { List filteredGuilds = new ArrayList<>(); - for(Group guild : publicGuildListCopy) { - if(guild.name.toLowerCase().contains(constraint)) { + for(Group guild : fullPublicGuildList) { + if(guild.name.toLowerCase().contains(query)) { filteredGuilds.add(guild); } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java index 50a98adea..8004cc613 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.java @@ -83,14 +83,14 @@ public class PublicGuildsFragment extends BaseMainFragment implements SearchView } @Override - public boolean onQueryTextSubmit(String s) { - viewAdapter.getFilter().filter(s); + public boolean onQueryTextSubmit(String query) { + viewAdapter.getFilter().filter(query); return true; } @Override - public boolean onQueryTextChange(String s) { - viewAdapter.getFilter().filter(s); + public boolean onQueryTextChange(String query) { + viewAdapter.getFilter().filter(query); return true; } } From 2af95690b80fe46f128b531b7cec81d82ff54370 Mon Sep 17 00:00:00 2001 From: Negue Date: Mon, 8 Aug 2016 18:09:26 +0200 Subject: [PATCH 06/21] Pet / Mount Counts --- Habitica/res/layout/activity_full_profile.xml | 26 +++++++++++++- .../ui/activities/FullProfileActivity.java | 36 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Habitica/res/layout/activity_full_profile.xml b/Habitica/res/layout/activity_full_profile.xml index f73142c29..b6196d221 100644 --- a/Habitica/res/layout/activity_full_profile.xml +++ b/Habitica/res/layout/activity_full_profile.xml @@ -303,10 +303,34 @@ + android:stretchColumns="0,1"> + + + + + + + + + + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java index e9ccbba4a..18a0088e4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -52,6 +52,7 @@ import org.greenrobot.eventbus.EventBus; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.inject.Inject; @@ -99,6 +100,12 @@ public class FullProfileActivity extends BaseActivity { @BindView(R.id.fullprofile_scrollview) ScrollView fullprofile_scrollview; + @BindView(R.id.profile_pet_count) + TextView petCount; + + @BindView(R.id.profile_mount_count) + TextView mountCount; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -209,6 +216,35 @@ public class FullProfileActivity extends BaseActivity { avatarWithBars.updateData(user); addLevelAttributes(stats, user); + + petCount.setText(CountEntries(user.getItems().getPets())+""); + mountCount.setText(CountEntriesBool(user.getItems().getMounts())+""); + } + + private int CountEntries(HashMap hashMap) { + int _count = 0; + + for (Map.Entry e : hashMap.entrySet()) { + if(e.getValue() == -1) + continue; + + _count += e.getValue(); + } + + return _count; + } + + private int CountEntriesBool(HashMap hashMap) { + int _count = 0; + + for (Map.Entry e : hashMap.entrySet()) { + if(e.getValue() == null) + continue; + + _count += 1; + } + + return _count; } // region Utils From 9f3d67419b76fe9dfd559509530793a6bf341720 Mon Sep 17 00:00:00 2001 From: Negue Date: Tue, 9 Aug 2016 22:29:05 +0200 Subject: [PATCH 07/21] rename sub-layouts to profile_* , extract resources, toggle attributes, hide costume card if the user doesn't activated it --- Habitica/res/layout/activity_full_profile.xml | 19 +++-- ...erow.xml => profile_attributetablerow.xml} | 0 ...tablerow.xml => profile_gear_tablerow.xml} | 0 ...log.xml => profile_new_message_dialog.xml} | 2 +- Habitica/res/values/strings.profile.xml | 13 ++++ .../ui/activities/FullProfileActivity.java | 74 +++++++++++-------- 6 files changed, 70 insertions(+), 38 deletions(-) rename Habitica/res/layout/{fullprofile_attributetablerow.xml => profile_attributetablerow.xml} (100%) rename Habitica/res/layout/{fullprofile_gear_tablerow.xml => profile_gear_tablerow.xml} (100%) rename Habitica/res/layout/{fullprofile_new_message_dialog.xml => profile_new_message_dialog.xml} (97%) create mode 100644 Habitica/res/values/strings.profile.xml diff --git a/Habitica/res/layout/activity_full_profile.xml b/Habitica/res/layout/activity_full_profile.xml index b6196d221..d7d19d942 100644 --- a/Habitica/res/layout/activity_full_profile.xml +++ b/Habitica/res/layout/activity_full_profile.xml @@ -167,7 +167,7 @@ @@ -187,7 +187,7 @@ @@ -201,7 +201,7 @@ @@ -222,8 +222,11 @@ + android:layout_height="wrap_content" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true"> @@ -296,7 +299,7 @@ @@ -310,7 +313,7 @@ + android:text="@string/profile_pets_found" /> + android:text="@string/profile_mounts_tamed" /> diff --git a/Habitica/res/values/strings.profile.xml b/Habitica/res/values/strings.profile.xml new file mode 100644 index 000000000..155084894 --- /dev/null +++ b/Habitica/res/values/strings.profile.xml @@ -0,0 +1,13 @@ + + + Pets & Mounts + Pets Found + Mounts Tamed + loading member data.. + Send message to %s + Message sent to %s + Level: + Class-Bonus: + Allocated: + Boosts: + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java index 18a0088e4..d3936bf3a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -2,21 +2,13 @@ package com.habitrpg.android.habitica.ui.activities; import android.content.Intent; import android.graphics.Typeface; -import android.graphics.drawable.Animatable; -import android.net.Uri; import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.FragmentManager; -import android.support.v4.util.ArrayMap; -import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; +import android.support.v7.widget.CardView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.ScrollView; import android.widget.TableLayout; @@ -32,11 +24,8 @@ import com.habitrpg.android.habitica.ContentCache; import com.habitrpg.android.habitica.HabiticaApplication; import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.components.AppComponent; -import com.habitrpg.android.habitica.events.commands.SendNewInboxMessageCommand; import com.habitrpg.android.habitica.ui.AvatarView; import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; -import com.habitrpg.android.habitica.ui.fragments.social.InboxMessageListFragment; -import com.habitrpg.android.habitica.ui.helpers.EmojiKeyboard; import com.habitrpg.android.habitica.ui.helpers.UiUtils; import com.magicmicky.habitrpgwrapper.lib.models.Buffs; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; @@ -47,8 +36,6 @@ import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData; import net.pherth.android.emoji_library.EmojiEditText; -import org.greenrobot.eventbus.EventBus; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -75,6 +62,9 @@ public class FullProfileActivity extends BaseActivity { @BindView(R.id.avatarView) AvatarView avatarView; + @BindView(R.id.profile_attributes_card) + CardView attributesCardView; + @BindView(R.id.attributes_table) TableLayout attributesTableLayout; @@ -93,6 +83,9 @@ public class FullProfileActivity extends BaseActivity { @BindView(R.id.avatar_costume_progress) ProgressBar costumeProgress; + @BindView(R.id.profile_costume_card) + CardView costumeCard; + @BindView(R.id.avatar_with_bars) View avatar_with_bars; private AvatarWithBarsViewModel avatarWithBars; @@ -114,7 +107,7 @@ public class FullProfileActivity extends BaseActivity { Bundle bundle = intent.getExtras(); this.userId = bundle.getString("userId"); - setTitle("loading member data.."); + setTitle(R.string.profile_loading_data); apiHelper.apiService.GetMember(this.userId) .compose(apiHelper.configureApiCallObserver()) @@ -129,6 +122,9 @@ public class FullProfileActivity extends BaseActivity { avatarWithBars.valueBarLabelsToBlack(); avatar_with_bars.setBackgroundColor(getResources().getColor(R.color.transparent)); + + attributeRows.clear(); + attributesCardView.setOnClickListener(view -> toggleAttributeDetails()); } @Override @@ -138,12 +134,12 @@ public class FullProfileActivity extends BaseActivity { if (id == R.id.private_message) { LayoutInflater factory = LayoutInflater.from(this); final View newMessageView = factory.inflate( - R.layout.fullprofile_new_message_dialog, null); + R.layout.profile_new_message_dialog, null); EmojiEditText emojiEditText = (EmojiEditText)newMessageView.findViewById(R.id.edit_new_message_text); TextView newMessageTitle = (TextView)newMessageView.findViewById(R.id.new_message_title); - newMessageTitle.setText("Send message to "+userName); + newMessageTitle.setText(String.format(getString(R.string.profile_send_message_to), userName)); final AlertDialog addMessageDialog = new AlertDialog.Builder(this) .setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { @@ -155,7 +151,7 @@ public class FullProfileActivity extends BaseActivity { .compose(apiHelper.configureApiCallObserver()) .subscribe(postChatMessageResult -> { UiUtils.showSnackbar(FullProfileActivity.this, FullProfileActivity.this.fullprofile_scrollview, - "Message sent to "+userName, UiUtils.SnackbarDisplayType.NORMAL); + String.format(getString(R.string.profile_message_sent_to), userName), UiUtils.SnackbarDisplayType.NORMAL); }, throwable -> { }); @@ -259,7 +255,7 @@ public class FullProfileActivity extends BaseActivity { } private TableRow addEquipmentRow(TableLayout table, String gearKey, String text, String stats) { - TableRow gearRow = (TableRow) getLayoutInflater().inflate(R.layout.fullprofile_gear_tablerow, null); + TableRow gearRow = (TableRow) getLayoutInflater().inflate(R.layout.profile_gear_tablerow, null); SimpleDraweeView draweeView = (SimpleDraweeView) gearRow.findViewById(R.id.gear_drawee); @@ -291,7 +287,7 @@ public class FullProfileActivity extends BaseActivity { // endregion - // region Stats + // region Attributes private float attributeStrSum = 0; private float attributeIntSum = 0; @@ -301,7 +297,7 @@ public class FullProfileActivity extends BaseActivity { private void addLevelAttributes(Stats stats, HabitRPGUser user) { float byLevelStat = stats.getLvl() / 2.0f; - addAttributeRow("Level: ", byLevelStat, byLevelStat, byLevelStat, byLevelStat, false); + addAttributeRow(getString(R.string.profile_level), byLevelStat, byLevelStat, byLevelStat, byLevelStat, false); LoadItemDataByOutfit(user.getItems().getGear().getEquipped(), obj -> { GotGear(obj, user); @@ -310,9 +306,13 @@ public class FullProfileActivity extends BaseActivity { stopAndHideProgress(attributesProgress); }); - LoadItemDataByOutfit(user.getItems().getGear().getCostume(), obj -> { - GotCostume(obj); - }); + if(user.getPreferences().getCostume()){ + LoadItemDataByOutfit(user.getItems().getGear().getCostume(), obj -> { + GotCostume(obj); + }); + } else { + costumeCard.setVisibility(View.GONE); + } } private void LoadItemDataByOutfit(Outfit outfit, ContentCache.GotContentEntryCallback> gotEntries) { @@ -373,7 +373,7 @@ public class FullProfileActivity extends BaseActivity { stopAndHideProgress(equipmentProgress); equipmentTableLayout.setVisibility(View.VISIBLE); - addAttributeRow("Equipment: ", strAttributes, intAttributes, conAttributes, perAttributes, false); + addAttributeRow(getString(R.string.battle_gear) +": ", strAttributes, intAttributes, conAttributes, perAttributes, false); if (!user.getPreferences().isDisableClasses()) { float strClassBonus = 0; @@ -400,7 +400,7 @@ public class FullProfileActivity extends BaseActivity { break; } - addAttributeRow("Class-Bonus: ", strClassBonus, intClassBonus, conClassBonus, perClassBonus, false); + addAttributeRow(getString(R.string.profile_class_bonus), strClassBonus, intClassBonus, conClassBonus, perClassBonus, false); } } @@ -417,14 +417,15 @@ public class FullProfileActivity extends BaseActivity { private void addNormalAddBuffAttributes(Stats stats) { Buffs buffs = stats.getBuffs(); - addAttributeRow("Allocated: ", stats.getStr(), stats.get_int(), stats.getCon(), stats.getPer(), false); - addAttributeRow("Boosts: ", buffs.getStr(), buffs.get_int(), buffs.getCon(), buffs.getPer(), false); + addAttributeRow(getString(R.string.profile_allocated), stats.getStr(), stats.get_int(), stats.getCon(), stats.getPer(), false); + addAttributeRow(getString(R.string.profile_boosts), buffs.getStr(), buffs.get_int(), buffs.getCon(), buffs.getPer(), false); + // Summary row addAttributeRow("", attributeStrSum, attributeIntSum, attributeConSum, attributePerSum, true); } private TableRow addAttributeRow(String label, float strVal, float intVal, float conVal, float perVal, boolean isSummary) { - TableRow tableRow = (TableRow) getLayoutInflater().inflate(R.layout.fullprofile_attributetablerow, null); + TableRow tableRow = (TableRow) getLayoutInflater().inflate(R.layout.profile_attributetablerow, null); TextView keyTextView = (TextView) tableRow.findViewById(R.id.tv_attribute_type); keyTextView.setText(label); @@ -451,6 +452,9 @@ public class FullProfileActivity extends BaseActivity { attributeIntSum += intVal; attributeConSum += conVal; attributePerSum += perVal; + + attributeRows.add(tableRow); + tableRow.setVisibility(View.GONE); } attributesTableLayout.addView(tableRow); @@ -458,6 +462,18 @@ public class FullProfileActivity extends BaseActivity { return tableRow; } + private boolean attributeDetailsHidden = true; + + private ArrayList attributeRows = new ArrayList<>(); + + private void toggleAttributeDetails(){ + attributeDetailsHidden = !attributeDetailsHidden; + + for (TableRow row : attributeRows){ + row.setVisibility(attributeDetailsHidden ? View.GONE : View.VISIBLE); + } + } + // endregion // region Navigation From 2a9e6baa8147548e00d05e5ec23961d73db4518e Mon Sep 17 00:00:00 2001 From: Negue Date: Tue, 9 Aug 2016 23:07:49 +0200 Subject: [PATCH 08/21] fix dexOptions in build.gradle --- Habitica/build.gradle | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 6639214d8..42bd0d92a 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -161,11 +161,6 @@ android { release } - dexOptions{ - javaMaxHeapSize "4g" - preDexLibraries = false - } - buildTypes { debug { applicationIdSuffix ".debug" @@ -206,8 +201,8 @@ android { } dexOptions { - preDexLibraries true - javaMaxHeapSize "2g" // Use gig increments depending on needs + preDexLibraries false + javaMaxHeapSize "4g" // Use gig increments depending on needs incremental true } From 8f654566776a250133ce44f8c7b55fac6a6d14d3 Mon Sep 17 00:00:00 2001 From: Negue Date: Tue, 9 Aug 2016 23:09:01 +0200 Subject: [PATCH 09/21] parse Markdown for member's blurb message, move event subscribe to MainActivity, open profile from the chat too --- .../ui/activities/FullProfileActivity.java | 3 ++- .../habitica/ui/activities/MainActivity.java | 16 ++++++++++++++++ .../adapter/social/ChatRecyclerViewAdapter.java | 8 ++++++++ .../ui/fragments/social/party/PartyFragment.java | 12 ------------ 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java index d3936bf3a..0bff780c5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.java @@ -26,6 +26,7 @@ import com.habitrpg.android.habitica.R; import com.habitrpg.android.habitica.components.AppComponent; import com.habitrpg.android.habitica.ui.AvatarView; import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; import com.habitrpg.android.habitica.ui.helpers.UiUtils; import com.magicmicky.habitrpgwrapper.lib.models.Buffs; import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser; @@ -205,7 +206,7 @@ public class FullProfileActivity extends BaseActivity { String blurbText = profile.getBlurb(); if (blurbText != null && !blurbText.isEmpty()) { - blurbTextView.setText(blurbText); + blurbTextView.setText(MarkdownParser.parseMarkdown(blurbText)); } avatarView.setUser(user); 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 a893d5615..b8c2736ff 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 @@ -27,6 +27,7 @@ import com.habitrpg.android.habitica.events.commands.DeleteTaskCommand; import com.habitrpg.android.habitica.events.commands.EquipCommand; import com.habitrpg.android.habitica.events.commands.FeedCommand; import com.habitrpg.android.habitica.events.commands.HatchingCommand; +import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand; import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand; import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand; import com.habitrpg.android.habitica.events.commands.SellItemCommand; @@ -1511,4 +1512,19 @@ public class MainActivity extends BaseActivity implements Action1, Ha public void addFilterDrawerItem(IDrawerItem item) { this.filterDrawer.addItem(item); } + + + @Subscribe + public void onEvent(OpenFullProfileCommand cmd) { + if(cmd.MemberId.equals("system")) + return; + + Bundle bundle = new Bundle(); + bundle.putString("userId", cmd.MemberId); + + Intent intent = new Intent(this, FullProfileActivity.class); + intent.putExtras(bundle); + intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(intent); + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java index 31a39fc0d..e15f90335 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java @@ -6,6 +6,7 @@ import com.habitrpg.android.habitica.events.commands.CopyChatAsTodoCommand; import com.habitrpg.android.habitica.events.commands.CopyChatMessageCommand; import com.habitrpg.android.habitica.events.commands.DeleteChatMessageCommand; import com.habitrpg.android.habitica.events.commands.FlagChatMessageCommand; +import com.habitrpg.android.habitica.events.commands.OpenFullProfileCommand; import com.habitrpg.android.habitica.events.commands.OpenNewPMActivityCommand; import com.habitrpg.android.habitica.events.commands.SendNewGroupMessageCommand; import com.habitrpg.android.habitica.events.commands.SendNewInboxMessageCommand; @@ -261,6 +262,13 @@ public class ChatRecyclerViewAdapter extends RecyclerView.Adapter { + OpenFullProfileCommand cmd = new OpenFullProfileCommand(msg.uuid); + + EventBus.getDefault().post(cmd); + }); } DataBindingUtils.setForegroundTintColor(userLabel, msg.getContributorForegroundColor()); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java index 6eba7f258..f382ab4e3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.java @@ -342,16 +342,4 @@ public class PartyFragment extends BaseMainFragment { tabLayout.setupWithViewPager(viewPager); } } - - @Subscribe - public void onEvent(OpenFullProfileCommand cmd) - { - Bundle bundle = new Bundle(); - bundle.putString("userId", cmd.MemberId); - - Intent intent = new Intent(activity, FullProfileActivity.class); - intent.putExtras(bundle); - intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - startActivity(intent); - } } From d89609d56210d6ca553587a19987696e39ed756f Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 11 Aug 2016 18:06:55 +0200 Subject: [PATCH 10/21] spacing and icon tweaks --- Habitica/AndroidManifest.xml | 2 +- Habitica/res/drawable-hdpi/minus.png | Bin 0 -> 93 bytes Habitica/res/drawable-hdpi/plus.png | Bin 0 -> 179 bytes Habitica/res/drawable-mdpi/minus.png | Bin 0 -> 90 bytes Habitica/res/drawable-mdpi/plus.png | Bin 0 -> 126 bytes Habitica/res/drawable-xhdpi/minus.png | Bin 0 -> 93 bytes Habitica/res/drawable-xhdpi/plus.png | Bin 0 -> 158 bytes Habitica/res/drawable-xxhdpi/minus.png | Bin 0 -> 102 bytes Habitica/res/drawable-xxhdpi/plus.png | Bin 0 -> 243 bytes Habitica/res/drawable-xxxhdpi/minus.png | Bin 0 -> 109 bytes Habitica/res/drawable-xxxhdpi/plus.png | Bin 0 -> 308 bytes Habitica/res/layout/activity_main.xml | 4 +-- Habitica/res/layout/avatar_with_bars.xml | 22 ++++++++++----- Habitica/res/layout/daily_item_card.xml | 9 ++++--- Habitica/res/layout/habit_item_card.xml | 25 +++++++++++++----- Habitica/res/layout/reward_item_card.xml | 4 ++- Habitica/res/layout/todo_item_card.xml | 7 ++--- Habitica/res/layout/value_bar.xml | 7 ++--- Habitica/res/values/dimens.xml | 9 +++++-- .../habitrpg/android/habitica/APIHelper.java | 7 ++++- .../ui/viewHolders/tasks/HabitViewHolder.java | 5 ++++ 21 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 Habitica/res/drawable-hdpi/minus.png create mode 100644 Habitica/res/drawable-hdpi/plus.png create mode 100644 Habitica/res/drawable-mdpi/minus.png create mode 100644 Habitica/res/drawable-mdpi/plus.png create mode 100644 Habitica/res/drawable-xhdpi/minus.png create mode 100644 Habitica/res/drawable-xhdpi/plus.png create mode 100644 Habitica/res/drawable-xxhdpi/minus.png create mode 100644 Habitica/res/drawable-xxhdpi/plus.png create mode 100644 Habitica/res/drawable-xxxhdpi/minus.png create mode 100644 Habitica/res/drawable-xxxhdpi/plus.png diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index be974feca..b6b3cd25b 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -2,7 +2,7 @@ diff --git a/Habitica/res/drawable-hdpi/minus.png b/Habitica/res/drawable-hdpi/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..eeb18c4ed9ff8086b8b26df014a9f9a4dffcb076 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^5PAd977}| plmGCu@R+dpn3zcCn4HyRU}$n?Fp6Tbie literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-hdpi/plus.png b/Habitica/res/drawable-hdpi/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..323ab83b5bad9a2a6635f3ca3831d7bb05673850 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|ay?xfLp*qs z6BLC0{QtjSt|M{5Jda!+pCei-;dfWCvN-3NbhtSP7&2{E+qm}mU^(*g40qRC9;u@E=z9m@GRKD#HucGMR@hZXO1RWj0aap@GcS* baACN!N{jWynypbliy1s!{an^LB{Ts5A>=s~ literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-mdpi/minus.png b/Habitica/res/drawable-mdpi/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..15e038eca9a48663c19fd7d98cd5f6ff81108720 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~f!3HD)-^P3dQjEnx?oJHr&dIz4azs2`978x{ mlmGCu@Q5&|aeZmp%Ea(@ItxQlubC21p25@A&t;ucLK6Tcz!Zc4 literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-mdpi/plus.png b/Habitica/res/drawable-mdpi/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..252184097e52df4fd6630759f58bf4014704f5f1 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|EIeHtLo5W7 z6Am!{b7quNUQHk?k_@FTPAd978lj plmGCu@Gx`CV7rjF;p$>O1_q8c7MAs_RWU#%44$rjF6*2UngC?_6-odA literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-xhdpi/plus.png b/Habitica/res/drawable-xhdpi/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..97f906df2f9d18a3135681081590c1474507c66e GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}5uPrNArYK! zr#W%~Rk3XT|9|HjwI-FOikY@kBTnpCu&K*R>vu@Vw|TbjbCSa4SRELc1R5Avj`(j~ zw@~=6H}^5lDcfdT_kS;Iw&=vu{XcfFYd{p}aa`oFdR4sM6le#7r>mdKI;Vst0E>e( ADnqIo{*yc=1CmZPK%POAIe%*Hj1p;~5EE z%f2L3GWW-Sz55_N-fX?t;V8ZRPWv1-MD>~k9F=X$RB%}7Cbi-b-(eGh1tH43A%*RU pQXB!RCbF&CaoB*DMdRuV7B5boDA&B3kwAwtc)I$ztaD0e0sxPPRSp0E literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-xxxhdpi/minus.png b/Habitica/res/drawable-xxxhdpi/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..0421caf607fa827694a4c8ed986edd0d4b792bf3 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^4nWMo!3HEflYZU@QjEnx?oJHr&dIz4a@0Lt978;K zlmGCu@F+_d^d{_Y-fJhtuvjyprTsvLn8ZWQhQuSwfu;zt@N6mY*$C9a;OXk;vd$@? F2>?s69Etz{ literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-xxxhdpi/plus.png b/Habitica/res/drawable-xxxhdpi/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..6b2770d450ad240c52e18c91f331c509db4d74f3 GIT binary patch literal 308 zcmV-40n7f0P)Px#?ny*JRCodHnn4PKKmY@4|Nm!eKcJT|BshB&l90@TpvMP3=XLHZkL%n$Pe1#n z1=sW}U~REg*(-ZW1_<1i*#Y*-1d%Byb=JfD5m)lYqKO;6M@p z7hY#40dL!5$NdR1Uot*^KO#%mcJpn)eJq&sWABWBW0000 @@ -38,21 +38,31 @@ + layout="@layout/value_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/header_bar_spacing" /> + layout="@layout/value_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/header_bar_spacing" /> + layout="@layout/value_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:paddingTop="6dp" + android:paddingBottom="6dp"> diff --git a/Habitica/res/layout/habit_item_card.xml b/Habitica/res/layout/habit_item_card.xml index 74095d34c..fbc85f880 100644 --- a/Habitica/res/layout/habit_item_card.xml +++ b/Habitica/res/layout/habit_item_card.xml @@ -21,11 +21,17 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/btnPlusBackground"/> +