From a98eeb347d4333ffb5d9ef41083b10d1418c8501 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Fri, 6 Jul 2018 16:32:08 +0200 Subject: [PATCH] Refactor all views and adapters to kotlin --- .../habitica/ui/GemPurchaseOptionsView.java | 72 ---- .../habitica/ui/GemPurchaseOptionsView.kt | 47 +++ .../android/habitica/ui/SpeechBubbleView.java | 97 ------ .../android/habitica/ui/SpeechBubbleView.kt | 80 +++++ .../android/habitica/ui/TutorialView.java | 108 ------ .../android/habitica/ui/TutorialView.kt | 86 +++++ .../habitica/ui/activities/MainActivity.java | 6 +- .../adapter/FAQOverviewRecyclerAdapter.java | 116 ------- .../ui/adapter/FAQOverviewRecyclerAdapter.kt | 102 ++++++ .../SkillTasksRecyclerViewAdapter.java | 103 ------ .../adapter/SkillTasksRecyclerViewAdapter.kt | 83 +++++ .../ui/adapter/SkillsRecyclerViewAdapter.java | 130 ------- .../ui/adapter/SkillsRecyclerViewAdapter.kt | 101 ++++++ .../inventory/ItemRecyclerAdapter.java | 223 ------------ .../adapter/inventory/ItemRecyclerAdapter.kt | 194 +++++++++++ .../inventory/MountDetailRecyclerAdapter.java | 110 ------ .../inventory/MountDetailRecyclerAdapter.kt | 81 +++++ .../inventory/PetDetailRecyclerAdapter.java | 154 --------- .../inventory/PetDetailRecyclerAdapter.kt | 124 +++++++ .../setup/CustomizationSetupAdapter.java | 184 ---------- .../setup/CustomizationSetupAdapter.kt | 147 ++++++++ .../ui/adapter/setup/TaskSetupAdapter.java | 104 ------ .../ui/adapter/setup/TaskSetupAdapter.kt | 85 +++++ .../ui/adapter/social/AchievementAdapter.java | 152 --------- .../ui/adapter/social/AchievementAdapter.kt | 116 +++++++ .../social/ChallengesListViewAdapter.java | 182 ---------- .../social/ChallengesListViewAdapter.kt | 133 ++++++++ .../social/ChatRecyclerViewAdapter.java | 316 ------------------ .../adapter/social/ChatRecyclerViewAdapter.kt | 263 +++++++++++++++ .../PartyMemberRecyclerViewAdapter.java | 138 -------- .../social/PartyMemberRecyclerViewAdapter.kt | 89 +++++ .../PublicGuildsRecyclerViewAdapter.java | 151 --------- .../social/PublicGuildsRecyclerViewAdapter.kt | 125 +++++++ .../ChallengesFilterRecyclerViewAdapter.java | 100 ------ .../ChallengesFilterRecyclerViewAdapter.kt | 86 +++++ .../ui/adapter/tasks/CheckListAdapter.java | 144 -------- .../ui/adapter/tasks/CheckListAdapter.kt | 114 +++++++ .../ui/adapter/tasks/RemindersAdapter.java | 142 -------- .../ui/adapter/tasks/RemindersAdapter.kt | 112 +++++++ .../ui/fragments/GemsPurchaseFragment.java | 2 +- .../ui/fragments/faq/FAQOverviewFragment.kt | 2 +- .../inventory/items/ItemRecyclerFragment.kt | 4 +- .../stable/MountDetailRecyclerFragment.java | 5 +- .../stable/PetDetailRecyclerFragment.kt | 2 +- .../stable/StableRecyclerFragment.kt | 2 +- .../ui/fragments/setup/AvatarSetupFragment.kt | 2 +- .../ui/fragments/setup/TaskSetupFragment.kt | 2 +- .../ui/fragments/setup/WelcomeFragment.kt | 2 +- .../ui/fragments/skills/SkillsFragment.kt | 4 +- .../ui/fragments/social/ChatListFragment.kt | 12 +- .../social/InboxMessageListFragment.kt | 10 +- .../fragments/social/PublicGuildsFragment.kt | 2 +- .../challenges/ChallengeFilterDialogHolder.kt | 3 +- .../challenges/ChallengeListFragment.kt | 3 +- .../yesterdailies/YesterdailyDialog.java | 176 ---------- .../views/yesterdailies/YesterdailyDialog.kt | 161 +++++++++ .../yesterdailies/YesterdailyDialogTests.java | 14 +- 57 files changed, 2366 insertions(+), 2942 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.java deleted file mode 100644 index 6f670ad43..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.habitrpg.android.habitica.ui; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import android.widget.Button; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; - -import butterknife.BindView; -import butterknife.ButterKnife; - - -public class GemPurchaseOptionsView extends FrameLayout { - - @BindView(R.id.seedsImageButton) - public - ImageButton seedsImageButton; - @BindView(R.id.gem_image) - ImageView gemImageView; - @BindView(R.id.gem_amount) - TextView gemAmountTextView; - @BindView(R.id.purchase_button) - Button purchaseButton; - private String sku; - - public GemPurchaseOptionsView(Context context, AttributeSet attrs) { - super(context, attrs); - - inflate(context, R.layout.purchase_gem_view, this); - - ButterKnife.bind(this); - - TypedArray a = context.getTheme().obtainStyledAttributes( - attrs, - R.styleable.GemPurchaseOptionsView, - 0, 0); - - gemAmountTextView.setText(a.getText(R.styleable.GemPurchaseOptionsView_gemAmount)); - - Drawable iconRes = a.getDrawable(R.styleable.GemPurchaseOptionsView_gemDrawable); - if (iconRes != null) { - gemImageView.setImageDrawable(iconRes); - } - - if (a.getBoolean(R.styleable.GemPurchaseOptionsView_showSeedsPromo, false)) { - seedsImageButton.setVisibility(View.VISIBLE); - } - } - - public void setOnPurchaseClickListener(Button.OnClickListener listener) { - purchaseButton.setOnClickListener(listener); - } - - public void setPurchaseButtonText(String price) { - purchaseButton.setText(price); - } - - public String getSku() { - return sku; - } - - public void setSku(String sku) { - this.sku = sku; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt new file mode 100644 index 000000000..5f694cb47 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt @@ -0,0 +1,47 @@ +package com.habitrpg.android.habitica.ui + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.* +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.ui.helpers.bindView + + +class GemPurchaseOptionsView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) { + + val seedsImageButton: ImageButton by bindView(R.id.seedsImageButton) + private val gemImageView: ImageView by bindView(R.id.gem_image) + private val gemAmountTextView: TextView by bindView(R.id.gem_amount) + private val purchaseButton: Button by bindView(R.id.purchase_button) + var sku: String? = null + + init { + inflate(R.layout.purchase_gem_view) + + val a = context.theme.obtainStyledAttributes( + attrs, + R.styleable.GemPurchaseOptionsView, + 0, 0) + + gemAmountTextView.text = a.getText(R.styleable.GemPurchaseOptionsView_gemAmount) + + val iconRes = a.getDrawable(R.styleable.GemPurchaseOptionsView_gemDrawable) + if (iconRes != null) { + gemImageView.setImageDrawable(iconRes) + } + + if (a.getBoolean(R.styleable.GemPurchaseOptionsView_showSeedsPromo, false)) { + seedsImageButton.visibility = View.VISIBLE + } + } + + fun setOnPurchaseClickListener(listener: OnClickListener) { + purchaseButton.setOnClickListener(listener) + } + + fun setPurchaseButtonText(price: String) { + purchaseButton.text = price + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.java deleted file mode 100644 index e893bcb5f..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.habitrpg.android.habitica.ui; - - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.ui.views.Typewriter; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class SpeechBubbleView extends FrameLayout implements View.OnClickListener { - - @BindView(R.id.name_plate) - TextView namePlate; - - @BindView(R.id.textView) - Typewriter textView; - - @BindView(R.id.npc_image_view) - ImageView npcImageView; - - @BindView(R.id.confirmation_buttons) - ViewGroup confirmationButtons; - - @BindView(R.id.continue_indicator) - View continueIndicator; - private ShowNextListener showNextListener; - - public SpeechBubbleView(Context context, AttributeSet attrs) { - super(context, attrs); - - inflate(context, R.layout.speechbubble, this); - ButterKnife.bind(this); - - TypedArray attributes = context.getTheme().obtainStyledAttributes( - attrs, - R.styleable.SpeechBubbleView, - 0, 0); - - namePlate.setText(attributes.getString(R.styleable.SpeechBubbleView_namePlate)); - textView.setText(attributes.getString(R.styleable.SpeechBubbleView_text)); - - Drawable iconRes = attributes.getDrawable(R.styleable.SpeechBubbleView_npcDrawable); - if (iconRes != null) { - npcImageView.setImageDrawable(iconRes); - } - - confirmationButtons.setVisibility(View.GONE); - - this.setOnClickListener(this); - } - - - public void setConfirmationButtonVisibility(int visibility) { - confirmationButtons.setVisibility(visibility); - } - - public void animateText(String text) { - this.textView.animateText(text); - } - - public void setText(String text) { - this.textView.setText(text); - } - - public void setHasMoreContent(Boolean hasMoreContent) { - continueIndicator.setVisibility(hasMoreContent ? View.VISIBLE : View.GONE); - } - - public void setShowNextListener(ShowNextListener listener) { - showNextListener = listener; - } - - @Override - public void onClick(View v) { - if (textView.isAnimating()) { - textView.stopTextAnimation(); - } else { - if (showNextListener != null) { - showNextListener.showNextStep(); - } - } - } - - public interface ShowNextListener { - void showNextStep(); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.kt new file mode 100644 index 000000000..50c34f592 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/SpeechBubbleView.kt @@ -0,0 +1,80 @@ +package com.habitrpg.android.habitica.ui + + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.views.Typewriter + +class SpeechBubbleView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs), View.OnClickListener { + + private val namePlate: TextView by bindView(R.id.name_plate) + private val textView: Typewriter by bindView(R.id.textView) + private val npcImageView: ImageView by bindView(R.id.npc_image_view) + private val confirmationButtons: ViewGroup by bindView(R.id.confirmation_buttons) + private val continueIndicator: View by bindView(R.id.continue_indicator) + private var showNextListener: ShowNextListener? = null + + init { + inflate(R.layout.speechbubble) + + val attributes = context.theme.obtainStyledAttributes( + attrs, + R.styleable.SpeechBubbleView, + 0, 0) + + namePlate.text = attributes.getString(R.styleable.SpeechBubbleView_namePlate) + textView.text = attributes.getString(R.styleable.SpeechBubbleView_text) + + val iconRes = attributes.getDrawable(R.styleable.SpeechBubbleView_npcDrawable) + if (iconRes != null) { + npcImageView.setImageDrawable(iconRes) + } + + confirmationButtons.visibility = View.GONE + + this.setOnClickListener(this) + } + + + fun setConfirmationButtonVisibility(visibility: Int) { + confirmationButtons.visibility = visibility + } + + fun animateText(text: String) { + this.textView.animateText(text) + } + + fun setText(text: String) { + this.textView.text = text + } + + fun setHasMoreContent(hasMoreContent: Boolean) { + continueIndicator.visibility = if (hasMoreContent) View.VISIBLE else View.GONE + } + + fun setShowNextListener(listener: ShowNextListener) { + showNextListener = listener + } + + override fun onClick(v: View) { + if (textView.isAnimating) { + textView.stopTextAnimation() + } else { + if (showNextListener != null) { + showNextListener!!.showNextStep() + } + } + } + + interface ShowNextListener { + fun showNextStep() + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.java deleted file mode 100644 index 44faa2402..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.habitrpg.android.habitica.ui; - -import android.content.Context; -import android.support.annotation.Nullable; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.Button; -import android.widget.FrameLayout; -import android.widget.RelativeLayout; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.TutorialStep; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; - -public class TutorialView extends FrameLayout { - - public TutorialStep step; - @Nullable - public OnTutorialReaction onReaction; - @BindView(R.id.speech_bubble) - SpeechBubbleView speechBubbleView; - @BindView(R.id.background) - RelativeLayout background; - @BindView(R.id.dismissButton) - Button dismissButton; - @BindView(R.id.completeButton) - Button completeButton; - - private List tutorialTexts; - private int currentTextIndex; - - public TutorialView(Context context, TutorialStep step, @Nullable OnTutorialReaction onReaction) { - super(context); - LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mInflater.inflate(R.layout.overlay_tutorial, this, true); - ButterKnife.bind(this); - speechBubbleView.setConfirmationButtonVisibility(View.GONE); - speechBubbleView.setShowNextListener(this::displayNextTutorialText); - this.step = step; - this.onReaction = onReaction; - } - - public void setTutorialText(String text) { - this.speechBubbleView.animateText(text); - speechBubbleView.setConfirmationButtonVisibility(View.VISIBLE); - } - - public void setTutorialTexts(List texts) { - tutorialTexts = texts; - currentTextIndex = -1; - displayNextTutorialText(); - } - - public void setCanBeDeferred(boolean canBeDeferred) { - dismissButton.setVisibility(canBeDeferred ? View.VISIBLE : View.GONE); - } - - private void displayNextTutorialText() { - currentTextIndex++; - if (tutorialTexts != null && currentTextIndex < tutorialTexts.size()) { - speechBubbleView.animateText(tutorialTexts.get(currentTextIndex)); - if (isDisplayingLastStep()) { - speechBubbleView.setConfirmationButtonVisibility(View.VISIBLE); - speechBubbleView.setHasMoreContent(false); - } else { - speechBubbleView.setHasMoreContent(true); - } - } else { - if (this.onReaction != null) { - this.onReaction.onTutorialCompleted(this.step); - } - } - } - - @OnClick(R.id.completeButton) - public void completeButtonClicked() { - if (this.onReaction != null) { - this.onReaction.onTutorialCompleted(this.step); - } - } - - @OnClick(R.id.dismissButton) - public void dismissButtonClicked() { - if (this.onReaction != null) { - this.onReaction.onTutorialDeferred(this.step); - } - } - - @OnClick(R.id.background) - public void backgroundClicked() { - speechBubbleView.onClick(speechBubbleView); - } - - private boolean isDisplayingLastStep() { - return currentTextIndex == (tutorialTexts.size()-1); - } - - public interface OnTutorialReaction { - void onTutorialCompleted(TutorialStep step); - - void onTutorialDeferred(TutorialStep step); - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.kt new file mode 100644 index 000000000..304d8a855 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/TutorialView.kt @@ -0,0 +1,86 @@ +package com.habitrpg.android.habitica.ui + +import android.content.Context +import android.view.View +import android.widget.Button +import android.widget.FrameLayout +import android.widget.RelativeLayout +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.models.TutorialStep +import com.habitrpg.android.habitica.ui.helpers.bindView + +class TutorialView(context: Context, var step: TutorialStep, var onReaction: OnTutorialReaction?) : FrameLayout(context) { + private val speechBubbleView: SpeechBubbleView by bindView(R.id.speech_bubble) + private val background: RelativeLayout by bindView(R.id.background) + private val dismissButton: Button by bindView(R.id.dismissButton) + private val completeButton: Button by bindView(R.id.completeButton) + + private var tutorialTexts: List = emptyList() + private var currentTextIndex: Int = 0 + + private val isDisplayingLastStep: Boolean + get() = currentTextIndex == tutorialTexts.size - 1 + + init { + inflate(R.layout.overlay_tutorial) + speechBubbleView.setConfirmationButtonVisibility(View.GONE) + speechBubbleView.setShowNextListener(object : SpeechBubbleView.ShowNextListener { + override fun showNextStep() { + displayNextTutorialText() + } + }) + + completeButton.setOnClickListener { completeButtonClicked() } + dismissButton.setOnClickListener { dismissButtonClicked() } + background.setOnClickListener { backgroundClicked() } + } + + fun setTutorialText(text: String) { + this.speechBubbleView.animateText(text) + speechBubbleView.setConfirmationButtonVisibility(View.VISIBLE) + } + + fun setTutorialTexts(texts: List) { + tutorialTexts = texts + currentTextIndex = -1 + displayNextTutorialText() + } + + fun setCanBeDeferred(canBeDeferred: Boolean) { + dismissButton.visibility = if (canBeDeferred) View.VISIBLE else View.GONE + } + + private fun displayNextTutorialText() { + currentTextIndex++ + if (currentTextIndex < tutorialTexts.size) { + speechBubbleView.animateText(tutorialTexts[currentTextIndex]) + if (isDisplayingLastStep) { + speechBubbleView.setConfirmationButtonVisibility(View.VISIBLE) + speechBubbleView.setHasMoreContent(false) + } else { + speechBubbleView.setHasMoreContent(true) + } + } else { + this.onReaction?.onTutorialCompleted(this.step) + } + } + + fun completeButtonClicked() { + this.onReaction?.onTutorialCompleted(this.step) + } + + fun dismissButtonClicked() { + this.onReaction?.onTutorialDeferred(this.step) + } + + fun backgroundClicked() { + speechBubbleView.onClick(speechBubbleView) + } + + interface OnTutorialReaction { + fun onTutorialCompleted(step: TutorialStep) + + fun onTutorialDeferred(step: TutorialStep) + } +} 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 51465ac43..0744f5f03 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 @@ -458,7 +458,7 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria }); displayDeathDialogIfNeeded(); - YesterdailyDialog.showDialogIfNeeded(this, user.getId(), userRepository, taskRepository); + YesterdailyDialog.Companion.showDialogIfNeeded(this, user.getId(), userRepository, taskRepository); displayNewInboxMessagesBadge(); } @@ -833,7 +833,7 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria TutorialView view = new TutorialView(this, step, this); this.activeTutorialView = view; view.setTutorialText(text); - view.onReaction = this; + view.setOnReaction(this); view.setCanBeDeferred(canBeDeferred); this.overlayLayout.addView(view); @@ -848,7 +848,7 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria TutorialView view = new TutorialView(this, step, this); this.activeTutorialView = view; view.setTutorialTexts(texts); - view.onReaction = this; + view.setOnReaction(this); view.setCanBeDeferred(canBeDeferred); this.overlayLayout.addView(view); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.java deleted file mode 100644 index a6ec1f63d..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.FAQArticle; -import com.habitrpg.android.habitica.ui.activities.MainActivity; -import com.habitrpg.android.habitica.ui.fragments.faq.FAQDetailFragment; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; - -public class FAQOverviewRecyclerAdapter extends RecyclerView.Adapter { - - private static final int VIEW_TYPE_JUSTIN = 0; - private static final int VIEW_TYPE_FAQ = 1; - - public MainActivity activity; - private List articles; - - private PublishSubject resetWalkthroughEvents = PublishSubject.create(); - - public void setArticles(List articles) { - this.articles = articles; - this.notifyDataSetChanged(); - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_JUSTIN) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.button_list_item, parent, false); - return new ResetWalkthroughViewHolder(view); - } else { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.plain_list_item, parent, false); - return new FAQArticleViewHolder(view); - } - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - if (getItemViewType(position) == VIEW_TYPE_FAQ) { - ((FAQArticleViewHolder) holder).bind(this.articles.get(position-1)); - } - } - - @Override - public int getItemViewType(int position) { - if (position == 0) { - return VIEW_TYPE_JUSTIN; - } else { - return VIEW_TYPE_FAQ; - } - } - - @Override - public int getItemCount() { - return this.articles == null ? 1 : this.articles.size()+1; - } - - public Flowable getResetWalkthroughEvents() { - return resetWalkthroughEvents.toFlowable(BackpressureStrategy.DROP); - } - - class FAQArticleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - @BindView(R.id.textView) - TextView textView; - - FAQArticle article; - - Context context; - - FAQArticleViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - textView.setOnClickListener(this); - - context = itemView.getContext(); - } - - public void bind(FAQArticle article) { - this.article = article; - this.textView.setText(this.article.getQuestion()); - } - - @Override - public void onClick(View v) { - FAQDetailFragment fragment = new FAQDetailFragment(); - fragment.setArticle(this.article); - activity.displayFragment(fragment); - } - } - - private class ResetWalkthroughViewHolder extends RecyclerView.ViewHolder { - - ResetWalkthroughViewHolder(View itemView) { - super(itemView); - Button button = (Button)itemView; - button.setText(itemView.getContext().getString(R.string.reset_walkthrough)); - button.setOnClickListener(v -> resetWalkthroughEvents.onNext(null)); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.kt new file mode 100644 index 000000000..980888b54 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/FAQOverviewRecyclerAdapter.kt @@ -0,0 +1,102 @@ +package com.habitrpg.android.habitica.ui.adapter + +import android.support.v7.widget.RecyclerView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.FAQArticle +import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.fragments.faq.FAQDetailFragment +import com.habitrpg.android.habitica.ui.helpers.bindView +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject + +class FAQOverviewRecyclerAdapter : RecyclerView.Adapter() { + + var activity: MainActivity? = null + private var articles: List = emptyList() + + private val resetWalkthroughEvents = PublishSubject.create() + + fun setArticles(articles: List) { + this.articles = articles + this.notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return if (viewType == VIEW_TYPE_JUSTIN) { + val view = LayoutInflater.from(parent.context).inflate(R.layout.button_list_item, parent, false) + ResetWalkthroughViewHolder(view) + } else { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.plain_list_item, parent, false) + FAQArticleViewHolder(view) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (getItemViewType(position) == VIEW_TYPE_FAQ) { + (holder as FAQArticleViewHolder).bind(articles[position - 1]) + } + } + + override fun getItemViewType(position: Int): Int { + return if (position == 0) { + VIEW_TYPE_JUSTIN + } else { + VIEW_TYPE_FAQ + } + } + + override fun getItemCount(): Int { + return this.articles.size + 1 + } + + fun getResetWalkthroughEvents(): Flowable { + return resetWalkthroughEvents.toFlowable(BackpressureStrategy.DROP) + } + + internal inner class FAQArticleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + private val textView: TextView by bindView(itemView, R.id.textView) + + private var article: FAQArticle? = null + + init { + textView.setOnClickListener(this) + } + + fun bind(article: FAQArticle) { + this.article = article + this.textView.text = this.article?.question + } + + override fun onClick(v: View) { + val fragment = FAQDetailFragment() + article.notNull { + fragment.setArticle(it) + } + activity?.displayFragment(fragment) + } + } + + private inner class ResetWalkthroughViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) { + + init { + val button = itemView as Button + button.text = itemView.getContext().getString(R.string.reset_walkthrough) + button.setOnClickListener { resetWalkthroughEvents.onNext("") } + } + } + + companion object { + + private const val VIEW_TYPE_JUSTIN = 0 + private const val VIEW_TYPE_FAQ = 1 + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java deleted file mode 100644 index e81a2cfb5..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter; - -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.Task; - -import java.util.UUID; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; - - -public class SkillTasksRecyclerViewAdapter extends RealmRecyclerViewAdapter { - - private PublishSubject taskSelectionEvents = PublishSubject.create(); - - public SkillTasksRecyclerViewAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate) { - super(data, autoUpdate); - } - - @Override - public long getItemId(int position) { - if (getData() != null) { - Task task = getData().get(position); - if (task.getId() != null && task.getId().length() == 36) { - return UUID.fromString(task.getId()).getMostSignificantBits(); - } - } - return UUID.randomUUID().getMostSignificantBits(); - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.skill_task_item_card, parent, false); - return new SkillTasksRecyclerViewAdapter.ViewHolder(view); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - if (getData() != null) { - holder.bindHolder(getData().get(position)); - } - } - - public Flowable getTaskSelectionEvents() { - return taskSelectionEvents.toFlowable(BackpressureStrategy.DROP); - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - public Task task; - protected android.content.res.Resources resources; - - @BindView(R.id.titleTextView) - TextView titleTextView; - @BindView(R.id.notesTextView) - TextView notesTextView; - @BindView(R.id.rightBorderView) - View rightBorderView; - - public ViewHolder(View itemView) { - super(itemView); - - itemView.setOnClickListener(this); - itemView.setClickable(true); - - ButterKnife.bind(this, itemView); - - resources = itemView.getResources(); - } - - void bindHolder(Task task) { - this.task = task; - titleTextView.setText(task.getText()); - if (task.getNotes() == null || task.getNotes().length() == 0) { - notesTextView.setVisibility(View.GONE); - } else { - notesTextView.setVisibility(View.VISIBLE); - notesTextView.setText(task.getNotes()); - } - rightBorderView.setBackgroundResource(task.getLightTaskColor()); - } - - @Override - public void onClick(View v) { - if (v.equals(itemView)) { - taskSelectionEvents.onNext(task); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.kt new file mode 100644 index 000000000..edeb68153 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillTasksRecyclerViewAdapter.kt @@ -0,0 +1,83 @@ +package com.habitrpg.android.habitica.ui.adapter + +import android.support.v7.widget.RecyclerView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.ui.helpers.bindView +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import java.util.* + + +class SkillTasksRecyclerViewAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate) { + + private val taskSelectionEvents = PublishSubject.create() + + override fun getItemId(position: Int): Long { + if (data != null) { + val task = data!![position] + if (task.id != null && task.id!!.length == 36) { + return UUID.fromString(task.id).mostSignificantBits + } + } + return UUID.randomUUID().mostSignificantBits + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.skill_task_item_card, parent, false) + return TaskViewHolder(view) + } + + override fun onBindViewHolder(holder: TaskViewHolder, position: Int) { + data.notNull { + holder.bindHolder(it[position]) + } + } + + fun getTaskSelectionEvents(): Flowable { + return taskSelectionEvents.toFlowable(BackpressureStrategy.DROP) + } + + inner class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + var task: Task? = null + + private val titleTextView: TextView by bindView(R.id.titleTextView) + private val notesTextView: TextView by bindView(R.id.notesTextView) + private val rightBorderView: View by bindView(R.id.rightBorderView) + + init { + itemView.setOnClickListener(this) + itemView.isClickable = true + } + + internal fun bindHolder(task: Task) { + this.task = task + titleTextView.text = task.text + if (task.notes?.isEmpty() == true) { + notesTextView.visibility = View.GONE + } else { + notesTextView.visibility = View.VISIBLE + notesTextView.text = task.notes + } + rightBorderView.setBackgroundResource(task.lightTaskColor) + } + + override fun onClick(v: View) { + if (v == itemView) { + task.notNull { + taskSelectionEvents.onNext(it) + } + } + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java deleted file mode 100644 index 3272d8043..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter; - -import android.content.Context; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import com.facebook.drawee.view.SimpleDraweeView; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.commands.UseSkillCommand; -import com.habitrpg.android.habitica.models.Skill; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper; - -import org.greenrobot.eventbus.EventBus; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class SkillsRecyclerViewAdapter extends RecyclerView.Adapter { - - public Double mana; - private List skillList; - - public void setSkillList(List skillList) { - this.skillList = skillList; - this.notifyDataSetChanged(); - } - - public void setMana(Double mana) { - this.mana = mana; - this.notifyDataSetChanged(); - } - - - @Override - public SkillViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.skill_list_item, parent, false); - - return new SkillViewHolder(view); - } - - @Override - public void onBindViewHolder(SkillViewHolder holder, int position) { - holder.bind(skillList.get(position)); - } - - @Override - public int getItemCount() { - return skillList == null ? 0 : skillList.size(); - } - - class SkillViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - private final Drawable magicDrawable; - @BindView(R.id.skill_image) - SimpleDraweeView skillImageView; - - @BindView(R.id.skill_text) - TextView skillNameTextView; - - @BindView(R.id.skill_notes) - TextView skillNotesTextView; - - @BindView(R.id.price_button) - Button priceButton; - - Skill skill; - - Context context; - - public SkillViewHolder(View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - context = itemView.getContext(); - - priceButton.setOnClickListener(this); - - magicDrawable = new BitmapDrawable(context.getResources(), HabiticaIconsHelper.imageOfMagic()); - } - - public void bind(Skill skill) { - this.skill = skill; - skillNameTextView.setText(skill.text); - skillNotesTextView.setText(skill.notes); - - if ("special".equals(skill.habitClass)) { - priceButton.setText(R.string.skill_transformation_use); - - priceButton.setCompoundDrawables(null, null, null, null); - } else { - priceButton.setText(skill.mana + ""); - - priceButton.setCompoundDrawablesWithIntrinsicBounds(magicDrawable, null, null, null); - } - DataBindingUtils.INSTANCE.loadImage(skillImageView, "shop_" + skill.key); - - if (skill.mana > mana) { - priceButton.setEnabled(false); - priceButton.setBackgroundResource(R.color.task_gray); - skillNameTextView.setTextColor(ContextCompat.getColor(context, R.color.task_gray)); - skillNotesTextView.setTextColor(ContextCompat.getColor(context, R.color.task_gray)); - } else { - skillNameTextView.setTextColor(ContextCompat.getColor(context, android.R.color.black)); - skillNotesTextView.setTextColor(ContextCompat.getColor(context, android.R.color.black)); - priceButton.setEnabled(true); - } - } - - @Override - public void onClick(View v) { - UseSkillCommand event = new UseSkillCommand(); - event.skill = this.skill; - - EventBus.getDefault().post(event); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt new file mode 100644 index 000000000..6e97cb6fa --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt @@ -0,0 +1,101 @@ +package com.habitrpg.android.habitica.ui.adapter + +import android.content.Context +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.support.v4.content.ContextCompat +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import com.facebook.drawee.view.SimpleDraweeView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.UseSkillCommand +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.models.Skill +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import org.greenrobot.eventbus.EventBus + +class SkillsRecyclerViewAdapter : RecyclerView.Adapter() { + + var mana: Double = 0.toDouble() + set(value) { + field = value + notifyDataSetChanged() + } + private var skillList: List = emptyList() + + fun setSkillList(skillList: List) { + this.skillList = skillList + this.notifyDataSetChanged() + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SkillViewHolder { + return SkillViewHolder(parent.inflate(R.layout.skill_list_item)) + } + + override fun onBindViewHolder(holder: SkillViewHolder, position: Int) { + holder.bind(skillList[position]) + } + + override fun getItemCount(): Int { + return skillList.size + } + + inner class SkillViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + private val magicDrawable: Drawable + private val skillImageView: SimpleDraweeView by bindView(R.id.skill_image) + private val skillNameTextView: TextView by bindView(R.id.skill_text) + private val skillNotesTextView: TextView by bindView(R.id.skill_image) + private val priceButton: Button by bindView(itemView, R.id.price_button) + + var skill: Skill? = null + + var context: Context = itemView.context + + init { + priceButton.setOnClickListener(this) + magicDrawable = BitmapDrawable(context.resources, HabiticaIconsHelper.imageOfMagic()) + } + + fun bind(skill: Skill) { + this.skill = skill + skillNameTextView.text = skill.text + skillNotesTextView.text = skill.notes + + if ("special" == skill.habitClass) { + priceButton.setText(R.string.skill_transformation_use) + + priceButton.setCompoundDrawables(null, null, null, null) + } else { + priceButton.text = skill.mana.toString() + + priceButton.setCompoundDrawablesWithIntrinsicBounds(magicDrawable, null, null, null) + } + DataBindingUtils.loadImage(skillImageView, "shop_" + skill.key) + + if (skill.mana > mana) { + priceButton.isEnabled = false + priceButton.setBackgroundResource(R.color.task_gray) + skillNameTextView.setTextColor(ContextCompat.getColor(context, R.color.task_gray)) + skillNotesTextView.setTextColor(ContextCompat.getColor(context, R.color.task_gray)) + } else { + skillNameTextView.setTextColor(ContextCompat.getColor(context, android.R.color.black)) + skillNotesTextView.setTextColor(ContextCompat.getColor(context, android.R.color.black)) + priceButton.isEnabled = true + } + } + + override fun onClick(v: View) { + val event = UseSkillCommand() + event.skill = this.skill + + EventBus.getDefault().post(event) + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.java deleted file mode 100644 index 23949d76e..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.inventory; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.facebook.drawee.view.SimpleDraweeView; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.OpenMysteryItemEvent; -import com.habitrpg.android.habitica.events.commands.FeedCommand; -import com.habitrpg.android.habitica.events.commands.HatchingCommand; -import com.habitrpg.android.habitica.models.inventory.Egg; -import com.habitrpg.android.habitica.models.inventory.Food; -import com.habitrpg.android.habitica.models.inventory.HatchingPotion; -import com.habitrpg.android.habitica.models.inventory.Item; -import com.habitrpg.android.habitica.models.inventory.Pet; -import com.habitrpg.android.habitica.models.inventory.QuestContent; -import com.habitrpg.android.habitica.models.inventory.SpecialItem; -import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemRecyclerFragment; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem; - -import org.greenrobot.eventbus.EventBus; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; -import io.realm.RealmResults; - -public class ItemRecyclerAdapter extends RealmRecyclerViewAdapter { - - public boolean isHatching; - public boolean isFeeding; - public Item hatchingItem; - public Pet feedingPet; - public ItemRecyclerFragment fragment; - private RealmResults ownedPets; - public Context context; - - private PublishSubject sellItemEvents = PublishSubject.create(); - private PublishSubject questInvitationEvents = PublishSubject.create(); - - public ItemRecyclerAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate) { - super(data, autoUpdate); - } - - public Flowable getSellItemEvents() { - return sellItemEvents.toFlowable(BackpressureStrategy.DROP); - } - - @Override - public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_item, parent, false); - - return new ItemViewHolder(view); - } - - @Override - public void onBindViewHolder(ItemViewHolder holder, int position) { - if (getData() != null) { - holder.bind(getData().get(position)); - } - } - - public void setOwnedPets(RealmResults pets) { - ownedPets = pets; - } - - public Flowable getQuestInvitationEvents() { - return questInvitationEvents.toFlowable(BackpressureStrategy.DROP); - } - - class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - Item item; - - @BindView(R.id.titleTextView) - TextView titleTextView; - @BindView(R.id.ownedTextView) - TextView ownedTextView; - @BindView(R.id.imageView) - SimpleDraweeView imageView; - - Resources resources; - - ItemViewHolder(View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - resources = itemView.getResources(); - - itemView.setOnClickListener(this); - } - - Boolean isPetOwned() { - String petKey; - if (item instanceof Egg) { - petKey = item.getKey() + "-" + hatchingItem.getKey(); - } else { - petKey = hatchingItem.getKey() + "-" + item.getKey(); - } - return ownedPets != null && ownedPets.where().equalTo("key", petKey).count() > 0; - } - - public void bind(Item item) { - this.item = item; - titleTextView.setText(item.getText()); - ownedTextView.setText(String.valueOf(item.getOwned())); - - boolean disabled = false; - String imageName; - if (item instanceof QuestContent) { - imageName = "inventory_quest_scroll_" + item.getKey(); - } else if (item instanceof SpecialItem) { - imageName = item.getKey(); - } else { - String type = ""; - if (item instanceof Egg) { - type = "Egg"; - } else if (item instanceof Food) { - type = "Food"; - } else if (item instanceof HatchingPotion) { - type = "HatchingPotion"; - } - imageName = "Pet_" + type + "_" + item.getKey(); - - if (isHatching) { - disabled = this.isPetOwned(); - } - } - DataBindingUtils.INSTANCE.loadImage(imageView, imageName != null ? imageName : "head_0"); - - float alpha = 1.0f; - if (disabled) { - alpha = 0.3f; - } - imageView.setAlpha(alpha); - titleTextView.setAlpha(alpha); - ownedTextView.setAlpha(alpha); - } - - @Override - public void onClick(View v) { - if (!isHatching && !isFeeding) { - BottomSheetMenu menu = new BottomSheetMenu(context); - if (!(item instanceof QuestContent) && !(item instanceof SpecialItem)) { - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.sell, item.getValue()), true)); - } - if (item instanceof Egg) { - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.hatch_with_potion))); - } else if (item instanceof HatchingPotion) { - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.hatch_egg))); - } else if (item instanceof QuestContent) { - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.invite_party))); - } else if (item instanceof SpecialItem) { - SpecialItem specialItem = (SpecialItem) item; - if (specialItem.isMysteryItem && specialItem.getOwned() > 0) { - menu.addMenuItem(new BottomSheetMenuItem(context.getString(R.string.open))); - } - } - menu.setSelectionRunnable(index -> { - if (!((item instanceof QuestContent) || (item instanceof SpecialItem)) && index == 0) { - sellItemEvents.onNext(item); - return; - } - if (item instanceof Egg) { - HatchingCommand event = new HatchingCommand(); - event.usingEgg = (Egg) item; - EventBus.getDefault().post(event); - } else if (item instanceof Food) { - FeedCommand event = new FeedCommand(); - event.usingFood = (Food) item; - EventBus.getDefault().post(event); - } else if (item instanceof HatchingPotion) { - HatchingCommand event = new HatchingCommand(); - event.usingHatchingPotion = (HatchingPotion) item; - EventBus.getDefault().post(event); - } else if (item instanceof QuestContent) { - questInvitationEvents.onNext((QuestContent) item); - } else if (item instanceof SpecialItem) { - EventBus.getDefault().post(new OpenMysteryItemEvent()); - } - }); - menu.show(); - } else if (isHatching) { - if (this.isPetOwned()) { - return; - } - if (item instanceof Egg) { - HatchingCommand event = new HatchingCommand(); - event.usingEgg = (Egg) item; - event.usingHatchingPotion = (HatchingPotion) hatchingItem; - EventBus.getDefault().post(event); - } else if (item instanceof HatchingPotion) { - HatchingCommand event = new HatchingCommand(); - event.usingHatchingPotion = (HatchingPotion) item; - event.usingEgg = (Egg) hatchingItem; - EventBus.getDefault().post(event); - } - fragment.dismiss(); - } else if (isFeeding) { - FeedCommand event = new FeedCommand(); - event.usingPet = feedingPet; - event.usingFood = (Food) item; - EventBus.getDefault().post(event); - fragment.dismiss(); - } - - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt new file mode 100644 index 000000000..0e707230e --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -0,0 +1,194 @@ +package com.habitrpg.android.habitica.ui.adapter.inventory + +import android.content.Context +import android.content.res.Resources +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.facebook.drawee.view.SimpleDraweeView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.OpenMysteryItemEvent +import com.habitrpg.android.habitica.events.commands.FeedCommand +import com.habitrpg.android.habitica.events.commands.HatchingCommand +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.inventory.* +import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemRecyclerFragment +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import io.realm.RealmResults +import org.greenrobot.eventbus.EventBus + +class ItemRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate) { + + var isHatching: Boolean = false + var isFeeding: Boolean = false + var hatchingItem: Item? = null + var feedingPet: Pet? = null + var fragment: ItemRecyclerFragment? = null + private var ownedPets: RealmResults? = null + var context: Context? = null + + private val sellItemEvents = PublishSubject.create() + private val questInvitationEvents = PublishSubject.create() + + fun getSellItemFlowable(): Flowable { + return sellItemEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getQuestInvitationFlowable(): Flowable { + return questInvitationEvents.toFlowable(BackpressureStrategy.DROP) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + return ItemViewHolder(parent.inflate(R.layout.item_item)) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + data.notNull { holder.bind(it[position]) } + } + + fun setOwnedPets(pets: RealmResults) { + ownedPets = pets + } + + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + var item: Item? = null + + private val titleTextView: TextView by bindView(R.id.titleTextView) + private val ownedTextView: TextView by bindView(R.id.ownedTextView) + private val imageView: SimpleDraweeView by bindView(R.id.imageView) + + var resources: Resources = itemView.resources + + private val isPetOwned: Boolean? + get() { + val petKey: String = if (item is Egg) { + item?.key + "-" + hatchingItem?.key + } else { + hatchingItem?.key + "-" + item?.key + } + return ownedPets != null && ownedPets?.where()?.equalTo("key", petKey)?.count() ?: 0 > 0 + } + + init { + itemView.setOnClickListener(this) + } + + fun bind(item: Item) { + this.item = item + titleTextView.text = item.text + ownedTextView.text = item.owned.toString() + + var disabled = false + val imageName: String? + if (item is QuestContent) { + imageName = "inventory_quest_scroll_" + item.getKey() + } else if (item is SpecialItem) { + imageName = item.getKey() + } else { + val type = when (item) { + is Egg -> "Egg" + is Food -> "Food" + is HatchingPotion -> "HatchingPotion" + else -> "" + } + imageName = "Pet_" + type + "_" + item.key + + if (isHatching) { + disabled = this.isPetOwned!! + } + } + DataBindingUtils.loadImage(imageView, imageName ?: "head_0") + + var alpha = 1.0f + if (disabled) { + alpha = 0.3f + } + imageView.alpha = alpha + titleTextView.alpha = alpha + ownedTextView.alpha = alpha + } + + override fun onClick(v: View) { + if (!isHatching && !isFeeding) { + val menu = BottomSheetMenu(context) + if (item !is QuestContent && item !is SpecialItem) { + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.sell, item?.value), true)) + } + if (item is Egg) { + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.hatch_with_potion))) + } else if (item is HatchingPotion) { + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.hatch_egg))) + } else if (item is QuestContent) { + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.invite_party))) + } else if (item is SpecialItem) { + val specialItem = item as SpecialItem + if (specialItem.isMysteryItem && specialItem.owned > 0) { + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.open))) + } + } + menu.setSelectionRunnable { index -> + item.notNull { selectedItem -> + if (!(selectedItem is QuestContent || selectedItem is SpecialItem) && index == 0) { + sellItemEvents.onNext(selectedItem) + return@notNull + } + when (selectedItem) { + is Egg -> { + val event = HatchingCommand() + event.usingEgg = selectedItem + EventBus.getDefault().post(event) + } + is Food -> { + val event = FeedCommand() + event.usingFood = selectedItem + EventBus.getDefault().post(event) + } + is HatchingPotion -> { + val event = HatchingCommand() + event.usingHatchingPotion = selectedItem + EventBus.getDefault().post(event) + } + is QuestContent -> questInvitationEvents.onNext(selectedItem) + is SpecialItem -> EventBus.getDefault().post(OpenMysteryItemEvent()) + } + } + } + menu.show() + } else if (isHatching) { + if (this.isPetOwned == true) { + return + } + if (item is Egg) { + val event = HatchingCommand() + event.usingEgg = item as Egg + event.usingHatchingPotion = hatchingItem as HatchingPotion? + EventBus.getDefault().post(event) + } else if (item is HatchingPotion) { + val event = HatchingCommand() + event.usingHatchingPotion = item as HatchingPotion + event.usingEgg = hatchingItem as Egg? + EventBus.getDefault().post(event) + } + fragment?.dismiss() + } else if (isFeeding) { + val event = FeedCommand() + event.usingPet = feedingPet + event.usingFood = item as Food + EventBus.getDefault().post(event) + fragment?.dismiss() + } + + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.java deleted file mode 100644 index bdd91aff3..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.inventory; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.facebook.drawee.view.SimpleDraweeView; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.inventory.Mount; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; - -public class MountDetailRecyclerAdapter extends RealmRecyclerViewAdapter { - - public String itemType; - public Context context; - - private PublishSubject equipEvents = PublishSubject.create(); - - public MountDetailRecyclerAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate) { - super(data, autoUpdate); - } - - - public Flowable getEquipEvents() { - return equipEvents.toFlowable(BackpressureStrategy.DROP); - } - - @Override - public MountViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.animal_overview_item, parent, false); - - return new MountViewHolder(view); - } - - @Override - public void onBindViewHolder(MountViewHolder holder, int position) { - if (getData() != null) { - holder.bind(this.getData().get(position)); - } - } - - class MountViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - Mount animal; - - @BindView(R.id.card_view) - CardView cardView; - - @BindView(R.id.imageView) - SimpleDraweeView imageView; - - @BindView(R.id.titleTextView) - TextView titleView; - - @BindView(R.id.ownedTextView) - TextView ownedTextView; - - Resources resources; - - MountViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - resources = itemView.getResources(); - - itemView.setOnClickListener(this); - } - - public void bind(Mount item) { - animal = item; - titleView.setText(item.getColorText()); - ownedTextView.setVisibility(View.GONE); - this.imageView.setAlpha(1.0f); - if (this.animal.getOwned()) { - DataBindingUtils.INSTANCE.loadImage(this.imageView, "Mount_Icon_" + itemType + "-" + item.getColor()); - } else { - DataBindingUtils.INSTANCE.loadImage(this.imageView, "PixelPaw"); - this.imageView.setAlpha(0.3f); - } - } - - @Override - public void onClick(View v) { - if (!this.animal.getOwned()) { - return; - } - BottomSheetMenu menu = new BottomSheetMenu(context); - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.use_animal))); - menu.setSelectionRunnable(index -> equipEvents.onNext(animal.getKey())); - menu.show(); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt new file mode 100644 index 000000000..5016be4e5 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt @@ -0,0 +1,81 @@ +package com.habitrpg.android.habitica.ui.adapter.inventory + +import android.content.Context +import android.content.res.Resources +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.facebook.drawee.view.SimpleDraweeView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.inventory.Mount +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter + +class MountDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate) { + + var itemType: String? = null + + private val equipEvents = PublishSubject.create() + + + fun getEquipFlowable(): Flowable { + return equipEvents.toFlowable(BackpressureStrategy.DROP) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MountViewHolder { + return MountViewHolder(parent.inflate(R.layout.animal_overview_item)) + } + + override fun onBindViewHolder(holder: MountViewHolder, position: Int) { + data.notNull { holder.bind(it[position]) } + } + + inner class MountViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + var animal: Mount? = null + + private val imageView: SimpleDraweeView by bindView(R.id.imageView) + private val titleView: TextView by bindView(R.id.titleTextView) + private val ownedTextView: TextView by bindView(R.id.ownedTextView) + + var resources: Resources = itemView.resources + + init { + itemView.setOnClickListener(this) + } + + fun bind(item: Mount) { + animal = item + titleView.text = item.colorText + ownedTextView.visibility = View.GONE + this.imageView.alpha = 1.0f + if (this.animal?.owned == true) { + DataBindingUtils.loadImage(this.imageView, "Mount_Icon_" + itemType + "-" + item.color) + } else { + DataBindingUtils.loadImage(this.imageView, "PixelPaw") + this.imageView.alpha = 0.3f + } + } + + override fun onClick(v: View) { + if (this.animal?.owned == false) { + return + } + val menu = BottomSheetMenu(itemView.context) + menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.use_animal))) + menu.setSelectionRunnable { + animal.notNull { equipEvents.onNext(it.key) } + } + menu.show() + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.java deleted file mode 100644 index 6e2ac0fcb..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.inventory; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.support.v7.widget.CardView; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.facebook.drawee.view.SimpleDraweeView; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.commands.FeedCommand; -import com.habitrpg.android.habitica.models.inventory.Mount; -import com.habitrpg.android.habitica.models.inventory.Pet; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu; -import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem; - -import org.greenrobot.eventbus.EventBus; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; -import io.realm.RealmResults; - -public class PetDetailRecyclerAdapter extends RealmRecyclerViewAdapter { - - public String itemType; - public Context context; - private RealmResults ownedMounts; - private PublishSubject equipEvents = PublishSubject.create(); - - public PetDetailRecyclerAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate) { - super(data, autoUpdate); - } - - public Flowable getEquipEvents() { - return equipEvents.toFlowable(BackpressureStrategy.DROP); - } - - @Override - public PetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.pet_detail_item, parent, false); - - return new PetViewHolder(view); - } - - @Override - public void onBindViewHolder(PetViewHolder holder, int position) { - if (getData() != null) { - holder.bind(this.getData().get(position)); - } - } - - public void setOwnedMounts(RealmResults ownedMounts) { - this.ownedMounts = ownedMounts; - notifyDataSetChanged(); - } - - class PetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - Pet animal; - - @BindView(R.id.card_view) - CardView cardView; - - @BindView(R.id.imageView) - SimpleDraweeView imageView; - - @BindView(R.id.titleTextView) - TextView titleView; - - @BindView(R.id.trainedProgressBar) - ProgressBar trainedProgressbar; - - Resources resources; - - public PetViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - resources = itemView.getResources(); - - itemView.setOnClickListener(this); - } - - public void bind(Pet item) { - this.animal = item; - this.titleView.setText(item.getColorText()); - this.trainedProgressbar.setVisibility(animal.getAnimalGroup().equals("specialPets") ? View.GONE : View.VISIBLE); - this.imageView.setAlpha(1.0f); - if (this.animal.getTrained() > 0) { - if (this.isMountOwned()) { - this.trainedProgressbar.setVisibility(View.GONE); - } else { - this.trainedProgressbar.setProgress(this.animal.getTrained()); - } - DataBindingUtils.INSTANCE.loadImage(this.imageView, "Pet-" + itemType + "-" + item.getColor()); - } else { - this.trainedProgressbar.setVisibility(View.GONE); - if (this.animal.getTrained() == 0) { - DataBindingUtils.INSTANCE.loadImage(this.imageView, "PixelPaw"); - } else { - DataBindingUtils.INSTANCE.loadImage(this.imageView, "Pet-" + itemType + "-" + item.getColor()); - } - this.imageView.setAlpha(0.3f); - } - } - - @Override - public void onClick(View v) { - if (!this.isOwned()) { - return; - } - BottomSheetMenu menu = new BottomSheetMenu(context); - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.use_animal))); - if (!animal.getAnimalGroup().equals("specialPets") && !this.isMountOwned()) { - menu.addMenuItem(new BottomSheetMenuItem(resources.getString(R.string.feed))); - } - menu.setSelectionRunnable(index -> { - if (index == 0) { - equipEvents.onNext(animal.getKey()); - } else if (index == 1) { - FeedCommand event = new FeedCommand(); - event.usingPet = animal; - EventBus.getDefault().post(event); - } - }); - menu.show(); - } - - private boolean isOwned() { - return this.animal.getTrained() > 0; - } - - public boolean isMountOwned() { - for (Mount ownedMount : ownedMounts) { - if (ownedMount.getKey().equals(animal.getKey())) { - return true; - } - } - return false; - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt new file mode 100644 index 000000000..3fa8c24ac --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -0,0 +1,124 @@ +package com.habitrpg.android.habitica.ui.adapter.inventory + +import android.content.Context +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.ProgressBar +import android.widget.TextView +import com.facebook.drawee.view.SimpleDraweeView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.FeedCommand +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.inventory.Mount +import com.habitrpg.android.habitica.models.inventory.Pet +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu +import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import io.realm.RealmResults +import org.greenrobot.eventbus.EventBus + +class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate) { + + var itemType: String? = null + var context: Context? = null + private var ownedMounts: RealmResults? = null + private val equipEvents = PublishSubject.create() + + fun getEquipFlowable(): Flowable { + return equipEvents.toFlowable(BackpressureStrategy.DROP) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PetViewHolder { + return PetViewHolder(parent.inflate(R.layout.pet_detail_item)) + } + + override fun onBindViewHolder(holder: PetViewHolder, position: Int) { + data.notNull { + holder.bind(it[position]) + } + } + + fun setOwnedMounts(ownedMounts: RealmResults) { + this.ownedMounts = ownedMounts + notifyDataSetChanged() + } + + inner class PetViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + var animal: Pet? = null + + private val imageView: SimpleDraweeView by bindView(R.id.imageView) + private val titleView: TextView by bindView(R.id.titleTextView) + private val trainedProgressbar: ProgressBar by bindView(R.id.trainedProgressBar) + + private val isOwned: Boolean + get() = this.animal?.trained ?: 0 > 0 + + private val isMountOwned: Boolean + get() { + for (ownedMount in ownedMounts ?: emptyList()) { + if (ownedMount.key == animal?.key) { + return true + } + } + return false + } + + init { + itemView.setOnClickListener(this) + } + + fun bind(item: Pet) { + this.animal = item + this.titleView.text = item.colorText + this.trainedProgressbar.visibility = if (animal?.animalGroup == "specialPets") View.GONE else View.VISIBLE + this.imageView.alpha = 1.0f + if (this.animal?.trained ?: 0 > 0) { + if (this.isMountOwned) { + this.trainedProgressbar.visibility = View.GONE + } else { + this.trainedProgressbar.progress = animal?.trained ?: 0 + } + DataBindingUtils.loadImage(this.imageView, "Pet-" + itemType + "-" + item.color) + } else { + this.trainedProgressbar.visibility = View.GONE + if (this.animal?.trained == 0) { + DataBindingUtils.loadImage(this.imageView, "PixelPaw") + } else { + DataBindingUtils.loadImage(this.imageView, "Pet-" + itemType + "-" + item.color) + } + this.imageView.alpha = 0.3f + } + } + + override fun onClick(v: View) { + if (!this.isOwned) { + return + } + val menu = BottomSheetMenu(context) + menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.use_animal))) + if (animal?.animalGroup != "specialPets" && !this.isMountOwned) { + menu.addMenuItem(BottomSheetMenuItem(itemView.resources.getString(R.string.feed))) + } + menu.setSelectionRunnable { index -> + if (index == 0) { + animal.notNull { + equipEvents.onNext(it.key) + } + } else if (index == 1) { + val event = FeedCommand() + event.usingPet = animal + EventBus.getDefault().post(event) + } + } + menu.show() + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.java deleted file mode 100644 index c52fcf286..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.setup; - -import android.content.Context; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.commands.EquipCommand; -import com.habitrpg.android.habitica.events.commands.UpdateUserCommand; -import com.habitrpg.android.habitica.models.SetupCustomization; -import com.habitrpg.android.habitica.models.user.Preferences; -import com.habitrpg.android.habitica.models.user.User; - -import org.greenrobot.eventbus.EventBus; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class CustomizationSetupAdapter extends RecyclerView.Adapter { - - public String userSize; - public User user; - private List customizationList; - - public void setCustomizationList(List newCustomizationList) { - this.customizationList = newCustomizationList; - this.notifyDataSetChanged(); - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - int viewID = R.layout.setup_customization_item; - - View view = LayoutInflater.from(parent.getContext()) - .inflate(viewID, parent, false); - - return new CustomizationViewHolder(view); - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - ((CustomizationViewHolder) holder).bind(customizationList.get(position)); - } - - @Override - public int getItemCount() { - return customizationList == null ? 0 : customizationList.size(); - } - - private boolean isCustomizationActive(SetupCustomization customization) { - if (this.user == null) { - return false; - } - Preferences prefs = this.user.getPreferences(); - switch (customization.getCategory()) { - case "body": { - switch (customization.getSubcategory()) { - case "size": - return customization.getKey().equals(prefs.getSize()); - case "shirt": - return customization.getKey().equals(prefs.getShirt()); - } - } - case "skin": - return customization.getKey().equals(prefs.getSkin()); - case "background": - return customization.getKey().equals(prefs.getBackground()); - case "hair": - switch (customization.getSubcategory()) { - case "bangs": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getBangs(); - case "base": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getBase(); - case "color": - return customization.getKey().equals(prefs.getHair().getColor()); - case "flower": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getFlower(); - case "beard": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getBeard(); - case "mustache": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getMustache(); - } - case "extras": { - switch (customization.getSubcategory()) { - case "glasses": - return customization.getKey().equals(this.user.getItems().getGear().getEquipped().getEyeWear()) || ("eyewear_base_0".equals(this.user.getItems().getGear().getEquipped().getEyeWear()) && customization.getKey().length() == 0); - case "flower": - return Integer.parseInt(customization.getKey()) == prefs.getHair().getFlower(); - case "wheelchair": - return ("chair_"+ customization.getKey()).equals(prefs.getChair()) || customization.getKey().equals(prefs.getChair()) || (customization.getKey().equals("none") && prefs.getChair() == null); - } - } - } - return false; - } - - class CustomizationViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - @BindView(R.id.imageView) - ImageView imageView; - - @BindView(R.id.textView) - TextView textView; - - SetupCustomization customization; - - Context context; - - CustomizationViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - itemView.setOnClickListener(this); - - context = itemView.getContext(); - } - - public void bind(SetupCustomization customization) { - this.customization = customization; - - if (customization.getDrawableId() != null) { - imageView.setImageResource(customization.getDrawableId()); - } else if (customization.getColorId() != null) { - Drawable drawable = ContextCompat.getDrawable(context, R.drawable.setup_customization_circle); - if (drawable != null) { - drawable.setColorFilter(ContextCompat.getColor(context, customization.getColorId()), PorterDuff.Mode.MULTIPLY); - } - imageView.setImageDrawable(drawable); - } else { - imageView.setImageDrawable(null); - } - textView.setText(customization.getText()); - if (!"0".equals(customization.getKey()) && "flower".equals(customization.getSubcategory())) { - if (isCustomizationActive(customization)) { - imageView.setBackgroundResource(R.drawable.setup_customization_flower_bg_selected); - } else { - imageView.setBackgroundResource(R.drawable.setup_customization_flower_bg); - } - } else { - if (isCustomizationActive(customization)) { - imageView.setBackgroundResource(R.drawable.setup_customization_bg_selected); - textView.setTextColor(ContextCompat.getColor(context, R.color.white)); - } else { - imageView.setBackgroundResource(R.drawable.setup_customization_bg); - textView.setTextColor(ContextCompat.getColor(context, R.color.white_50_alpha)); - } - } - } - - @Override - public void onClick(View v) { - if (customization.getPath().equals("glasses")) { - EquipCommand command = new EquipCommand(); - if (customization.getKey().length() == 0) { - command.key = user.getItems().getGear().getEquipped().getEyeWear(); - } else { - command.key = customization.getKey(); - } - command.type = "equipped"; - EventBus.getDefault().post(command); - } else { - UpdateUserCommand command = new UpdateUserCommand(); - Map updateData = new HashMap<>(); - String updatePath = "preferences." + customization.getPath(); - updateData.put(updatePath, customization.getKey()); - - command.updateData = updateData; - - EventBus.getDefault().post(command); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.kt new file mode 100644 index 000000000..94577de10 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/CustomizationSetupAdapter.kt @@ -0,0 +1,147 @@ +package com.habitrpg.android.habitica.ui.adapter.setup + +import android.content.Context +import android.graphics.PorterDuff +import android.support.v4.content.ContextCompat +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.EquipCommand +import com.habitrpg.android.habitica.events.commands.UpdateUserCommand +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.SetupCustomization +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.helpers.bindView +import org.greenrobot.eventbus.EventBus +import java.util.* + +class CustomizationSetupAdapter : RecyclerView.Adapter() { + + var userSize: String? = null + var user: User? = null + private var customizationList: List = emptyList() + + fun setCustomizationList(newCustomizationList: List) { + this.customizationList = newCustomizationList + this.notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return CustomizationViewHolder(parent.inflate(R.layout.setup_customization_item)) + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + (holder as CustomizationViewHolder).bind(customizationList[position]) + } + + override fun getItemCount(): Int { + return customizationList.size + } + + private fun isCustomizationActive(customization: SetupCustomization): Boolean { + val prefs = this.user?.preferences ?: return false + when (customization.category) { + "body" -> { + when (customization.subcategory) { + "size" -> return customization.key == prefs.size + "shirt" -> return customization.key == prefs.shirt + } + } + "skin" -> return customization.key == prefs.skin + "background" -> return customization.key == prefs.background + "hair" -> { + when (customization.subcategory) { + "bangs" -> return Integer.parseInt(customization.key) == prefs.hair?.bangs + "base" -> return Integer.parseInt(customization.key) == prefs.hair?.base + "color" -> return customization.key == prefs.hair?.color + "flower" -> return Integer.parseInt(customization.key) == prefs.hair?.flower + "beard" -> return Integer.parseInt(customization.key) == prefs.hair?.beard + "mustache" -> return Integer.parseInt(customization.key) == prefs.hair?.mustache + } + } + "extras" -> { + when (customization.subcategory) { + "glasses" -> return customization.key == this.user?.items?.gear?.equipped?.eyeWear || "eyewear_base_0" == this.user?.items?.gear?.equipped?.eyeWear && customization.key.isEmpty() + "flower" -> return Integer.parseInt(customization.key) == prefs.hair?.flower + "wheelchair" -> return "chair_" + customization.key == prefs.chair || customization.key == prefs.chair || customization.key == "none" && prefs.chair == null + } + } + } + return false + } + + internal inner class CustomizationViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + private val imageView: ImageView by bindView(R.id.imageView) + private val textView: TextView by bindView(R.id.textView) + + var customization: SetupCustomization? = null + + var context: Context + + init { + itemView.setOnClickListener(this) + + context = itemView.context + } + + fun bind(customization: SetupCustomization) { + this.customization = customization + + when { + customization.drawableId != null -> imageView.setImageResource(customization.drawableId ?: 0) + customization.colorId != null -> { + val drawable = ContextCompat.getDrawable(context, R.drawable.setup_customization_circle) + drawable?.setColorFilter(ContextCompat.getColor(context, customization.colorId ?: 0), PorterDuff.Mode.MULTIPLY) + imageView.setImageDrawable(drawable) + } + else -> imageView.setImageDrawable(null) + } + textView.text = customization.text + if ("0" != customization.key && "flower" == customization.subcategory) { + if (isCustomizationActive(customization)) { + imageView.setBackgroundResource(R.drawable.setup_customization_flower_bg_selected) + } else { + imageView.setBackgroundResource(R.drawable.setup_customization_flower_bg) + } + } else { + if (isCustomizationActive(customization)) { + imageView.setBackgroundResource(R.drawable.setup_customization_bg_selected) + textView.setTextColor(ContextCompat.getColor(context, R.color.white)) + } else { + imageView.setBackgroundResource(R.drawable.setup_customization_bg) + textView.setTextColor(ContextCompat.getColor(context, R.color.white_50_alpha)) + } + } + } + + override fun onClick(v: View) { + customization.notNull { selectedCustomization -> + if (selectedCustomization.path == "glasses") { + val command = EquipCommand() + if (selectedCustomization.key.isEmpty()) { + command.key = user?.items?.gear?.equipped?.eyeWear + } else { + command.key = selectedCustomization.key + } + command.type = "equipped" + EventBus.getDefault().post(command) + } else { + val command = UpdateUserCommand() + val updateData = HashMap() + val updatePath = "preferences." + selectedCustomization.path + updateData[updatePath] = selectedCustomization.key + + command.updateData = updateData + + EventBus.getDefault().post(command) + } + } + + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.java deleted file mode 100644 index 2a07a366b..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.setup; - -import android.content.Context; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.support.graphics.drawable.VectorDrawableCompat; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class TaskSetupAdapter extends RecyclerView.Adapter { - - public List checkedList; - private String[][] taskList; - - public void setTaskList(String[][] taskList) { - this.taskList = taskList; - this.checkedList = new ArrayList<>(); - for (String[] ignored : this.taskList) { - this.checkedList.add(false); - } - } - - @Override - public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.task_setup_item, parent, false); - - return new TaskViewHolder(view); - } - - @Override - public void onBindViewHolder(TaskViewHolder holder, int position) { - holder.bind(this.taskList[position], this.checkedList.get(position)); - } - - @Override - public int getItemCount() { - return this.taskList == null ? 0 : this.taskList.length; - } - - class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - - private final Drawable icon; - @BindView(R.id.textView) - TextView textView; - - String[] taskGroup; - Boolean isChecked; - - Context context; - - TaskViewHolder(View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - context = itemView.getContext(); - - itemView.setOnClickListener(this); - - icon = VectorDrawableCompat.create(context.getResources(), R.drawable.ic_check_white_18dp, null); - if (icon != null) { - icon.setColorFilter(ContextCompat.getColor(context, R.color.brand_100), PorterDuff.Mode.MULTIPLY); - } - } - - public void bind(String[] taskGroup, Boolean isChecked) { - this.taskGroup = taskGroup; - this.isChecked = isChecked; - - this.textView.setText(this.taskGroup[0]); - if (this.isChecked) { - this.textView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); - textView.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.MULTIPLY); - textView.setTextColor(ContextCompat.getColor(context, R.color.brand_100)); - } else { - this.textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); - textView.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.brand_100), PorterDuff.Mode.MULTIPLY); - textView.setTextColor(ContextCompat.getColor(context, R.color.white)); - } - } - - @Override - public void onClick(View v) { - int position = this.getAdapterPosition(); - checkedList.set(position, !checkedList.get(position)); - notifyItemChanged(position); - } - } - -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.kt new file mode 100644 index 000000000..fd9f96f97 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/setup/TaskSetupAdapter.kt @@ -0,0 +1,85 @@ +package com.habitrpg.android.habitica.ui.adapter.setup + +import android.content.Context +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.support.graphics.drawable.VectorDrawableCompat +import android.support.v4.content.ContextCompat +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.ui.helpers.bindView +import java.util.* + +class TaskSetupAdapter : RecyclerView.Adapter() { + + var checkedList: MutableList = mutableListOf() + private var taskList: Array> = emptyArray() + + fun setTaskList(taskList: Array>) { + this.taskList = taskList + this.checkedList = ArrayList() + for (ignored in this.taskList) { + this.checkedList.add(false) + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder { + return TaskViewHolder(parent.inflate(R.layout.task_setup_item)) + } + + override fun onBindViewHolder(holder: TaskViewHolder, position: Int) { + holder.bind(this.taskList[position], this.checkedList[position]) + } + + override fun getItemCount(): Int { + return this.taskList.size + } + + inner class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + private val icon: Drawable? + private val textView: TextView by bindView(R.id.textView) + + private var taskGroup: Array? = null + private var isChecked: Boolean? = null + + var context: Context = itemView.context + + init { + itemView.setOnClickListener(this) + + icon = VectorDrawableCompat.create(context.resources, R.drawable.ic_check_white_18dp, null) + icon?.setColorFilter(ContextCompat.getColor(context, R.color.brand_100), PorterDuff.Mode.MULTIPLY) + } + + fun bind(taskGroup: Array, isChecked: Boolean?) { + this.taskGroup = taskGroup + this.isChecked = isChecked + + taskGroup.notNull { + textView.text = it[0] + } + if (this.isChecked == true) { + this.textView.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null) + textView.background.setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.MULTIPLY) + textView.setTextColor(ContextCompat.getColor(context, R.color.brand_100)) + } else { + this.textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null) + textView.background.setColorFilter(ContextCompat.getColor(context, R.color.brand_100), PorterDuff.Mode.MULTIPLY) + textView.setTextColor(ContextCompat.getColor(context, R.color.white)) + } + } + + override fun onClick(v: View) { + val position = this.adapterPosition + checkedList[position] = !checkedList[position] + notifyItemChanged(position) + } + } + +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.java deleted file mode 100644 index 28c6fd4d4..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social; - -import android.content.Context; -import android.support.v7.app.AlertDialog; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -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.R; -import com.habitrpg.android.habitica.models.Achievement; -import com.habitrpg.android.habitica.ui.AvatarView; -import com.habitrpg.android.habitica.ui.activities.MainActivity; -import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class AchievementAdapter extends RecyclerView.Adapter { - - public String itemType; - public MainActivity activity; - private List itemList; - - public void setItemList(List itemList) { - this.itemList = itemList; - this.notifyDataSetChanged(); - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if (viewType == 0) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.profile_achievement_category, parent, false); - - return new SectionViewHolder(view); - } else { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.profile_achievement_item, parent, false); - - return new AchievementViewHolder(view); - } - } - - @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { - Object obj = this.itemList.get(position); - if (obj.getClass().equals(String.class)) { - ((SectionViewHolder) holder).bind((String) obj); - } else { - ((AchievementViewHolder) holder).bind((Achievement) itemList.get(position)); - } - } - - @Override - public int getItemViewType(int position) { - if (this.itemList.get(position).getClass().equals(String.class)) { - return 0; - } else { - return 1; - } - } - - @Override - public int getItemCount() { - return itemList == null ? 0 : itemList.size(); - } - - static class AchievementViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - Achievement achievement; - - @BindView(R.id.achievement_drawee) - SimpleDraweeView draweeView; - - @BindView(R.id.achievement_text) - TextView titleView; - - @BindView(R.id.achievement_count_label) - TextView countText; - - @BindView(R.id.achievement_item_layout) - LinearLayout item_layout; - - Context context; - - AchievementViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - item_layout = (LinearLayout) itemView; - context = itemView.getContext(); - - item_layout.setClickable(true); - item_layout.setOnClickListener(this); - } - - public void bind(Achievement item) { - String iconUrl = AvatarView.IMAGE_URI_ROOT + (!item.earned ? "achievement-unearned" : item.icon) + "2x.png"; - - draweeView.setController(Fresco.newDraweeControllerBuilder() - .setUri(iconUrl) - .setControllerListener(new BaseControllerListener() { - @Override - public void onFailure(String id, Throwable throwable) { - } - }) - .build()); - - this.achievement = item; - titleView.setText(item.title); - - if (item.optionalCount == null) { - countText.setVisibility(View.GONE); - } else { - countText.setVisibility(View.VISIBLE); - countText.setText(item.optionalCount.toString()); - } - } - - @Override - public void onClick(View view) { - AlertDialog.Builder b = new AlertDialog.Builder(context); - - View customView = LayoutInflater.from(context) - .inflate(R.layout.dialog_achievement_details, null); - ImageView achievementImage = (ImageView) customView.findViewById(R.id.achievement_image); - achievementImage.setImageDrawable(draweeView.getDrawable()); - - TextView titleView = (TextView) customView.findViewById(R.id.achievement_title); - titleView.setText(achievement.title); - - - TextView textView = (TextView) customView.findViewById(R.id.achievement_text); - textView.setText(achievement.text); - - b.setView(customView); - b.setPositiveButton(R.string.profile_achievement_ok, (dialogInterface, i) -> { - }); - - b.show(); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.kt new file mode 100644 index 000000000..fa654d0eb --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/AchievementAdapter.kt @@ -0,0 +1,116 @@ +package com.habitrpg.android.habitica.ui.adapter.social + +import android.support.v7.app.AlertDialog +import android.support.v7.widget.RecyclerView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +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.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.models.Achievement +import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder + +class AchievementAdapter : RecyclerView.Adapter() { + + var itemType: String? = null + var activity: MainActivity? = null + private var itemList: List = emptyList() + + fun setItemList(itemList: List) { + this.itemList = itemList + this.notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return if (viewType == 0) { + SectionViewHolder(parent.inflate(R.layout.profile_achievement_category)) + } else { + AchievementViewHolder(parent.inflate(R.layout.profile_achievement_item)) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val obj = this.itemList[position] + if (obj.javaClass == String::class.java) { + (holder as SectionViewHolder).bind(obj as String) + } else { + (holder as AchievementViewHolder).bind(itemList[position] as Achievement) + } + } + + override fun getItemViewType(position: Int): Int { + return if (this.itemList[position].javaClass == String::class.java) { + 0 + } else { + 1 + } + } + + override fun getItemCount(): Int { + return itemList.size + } + + internal class AchievementViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + private var achievement: Achievement? = null + + private val draweeView: SimpleDraweeView by bindView(R.id.achievement_drawee) + private val titleView: TextView by bindView(R.id.achievement_text) + private val countText: TextView by bindView(R.id.achievement_count_label) + + init { + itemView.isClickable = true + itemView.setOnClickListener(this) + } + + fun bind(item: Achievement) { + val iconUrl = AvatarView.IMAGE_URI_ROOT + (if (!item.earned) "achievement-unearned" else item.icon) + "2x.png" + + draweeView.controller = Fresco.newDraweeControllerBuilder() + .setUri(iconUrl) + .setControllerListener(object : BaseControllerListener() { + override fun onFailure(id: String?, throwable: Throwable?) {} + }) + .build() + + this.achievement = item + titleView.text = item.title + + if (item.optionalCount == null) { + countText.visibility = View.GONE + } else { + countText.visibility = View.VISIBLE + countText.text = item.optionalCount.toString() + } + } + + override fun onClick(view: View) { + val context = itemView.context + val b = AlertDialog.Builder(context) + + val customView = LayoutInflater.from(context) + .inflate(R.layout.dialog_achievement_details, null) + val achievementImage = customView.findViewById(R.id.achievement_image) as ImageView + achievementImage.setImageDrawable(draweeView.drawable) + + val titleView = customView.findViewById(R.id.achievement_title) as TextView + titleView.text = achievement?.title + + val textView = customView.findViewById(R.id.achievement_text) as TextView + textView.text = achievement?.text + + b.setView(customView) + b.setPositiveButton(R.string.profile_achievement_ok) { _, _ -> } + + b.show() + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java deleted file mode 100644 index 0e0556b26..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social; - -import android.content.Context; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand; -import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand; -import com.habitrpg.android.habitica.models.social.Challenge; -import com.habitrpg.android.habitica.models.social.Group; -import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions; -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper; - -import net.pherth.android.emoji_library.EmojiParser; -import net.pherth.android.emoji_library.EmojiTextView; - -import org.greenrobot.eventbus.EventBus; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.realm.OrderedRealmCollection; -import io.realm.RealmQuery; -import io.realm.RealmRecyclerViewAdapter; - -public class ChallengesListViewAdapter extends RealmRecyclerViewAdapter { - - private boolean viewUserChallengesOnly; - private OrderedRealmCollection unfilteredData; - private final String userId; - - public ChallengesListViewAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate, boolean viewUserChallengesOnly, String userId) { - super(data, autoUpdate); - this.viewUserChallengesOnly = viewUserChallengesOnly; - this.userId = userId; - } - - @Override - public ChallengeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.challenge_item, parent, false); - - return new ChallengeViewHolder(view, viewUserChallengesOnly); - } - - @Override - public void onBindViewHolder(ChallengeViewHolder holder, int position) { - if (getData() != null) { - holder.bind(getData().get(position)); - } - } - - public void updateUnfilteredData(@Nullable OrderedRealmCollection data) { - super.updateData(data); - unfilteredData = data; - } - - public void filter(ChallengeFilterOptions filterOptions) { - if (unfilteredData == null) { - return; - } - - RealmQuery query = unfilteredData.where(); - - if (filterOptions.showByGroups != null && filterOptions.showByGroups.size() > 0) { - String[] groupIds = new String[filterOptions.showByGroups.size()]; - int index = 0; - for (Group group : filterOptions.showByGroups) { - groupIds[index] = group.getId(); - index += 1; - } - query = query.in("groupId", groupIds); - } - - if (filterOptions.showOwned != filterOptions.notOwned) { - if (filterOptions.showOwned) { - query = query.equalTo("leaderId", userId); - } else { - query = query.notEqualTo("leaderId", userId); - } - } - - this.updateData(query.findAll()); - } - - public static class ChallengeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - private final Context context; - @BindView(R.id.challenge_name) - EmojiTextView challengeName; - - @BindView(R.id.challenge_group_name) - TextView challengeDescription; - - @BindView(R.id.leaderParticipantLayout) - LinearLayout leaderParticipantLayout; - - @BindView(R.id.leaderName) - TextView leaderName; - - @BindView(R.id.participantCount) - TextView participantCount; - - @BindView(R.id.officialHabiticaChallengeLayout) - LinearLayout officialChallengeLayout; - - @BindView(R.id.challenge_is_participating) - View challengeParticipatingTextView; - - @Nullable - @BindView(R.id.memberCountTextView) - TextView memberCountTextView; - - @BindView(R.id.arrowImage) - LinearLayout arrowImage; - - @BindView(R.id.gemPrizeTextView) - TextView gemPrizeTextView; - - @BindView(R.id.gem_icon) - ImageView gemIconView; - - private Challenge challenge; - private boolean viewUserChallengesOnly; - - ChallengeViewHolder(View itemView, boolean viewUserChallengesOnly) { - super(itemView); - this.viewUserChallengesOnly = viewUserChallengesOnly; - ButterKnife.bind(this, itemView); - - context = itemView.getContext(); - itemView.setOnClickListener(this); - - gemIconView.setImageBitmap(HabiticaIconsHelper.imageOfGem()); - - if (!viewUserChallengesOnly) { - challengeName.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.brand_200)); - } - } - - public void bind(Challenge challenge) { - this.challenge = challenge; - - challengeName.setText(EmojiParser.parseEmojis(challenge.name.trim())); - challengeDescription.setText(challenge.groupName); - - officialChallengeLayout.setVisibility(challenge.official ? View.VISIBLE : View.GONE); - - if (viewUserChallengesOnly) { - leaderParticipantLayout.setVisibility(View.GONE); - challengeParticipatingTextView.setVisibility(View.GONE); - arrowImage.setVisibility(View.VISIBLE); - } else { - challengeParticipatingTextView.setVisibility(challenge.isParticipating ? View.VISIBLE : View.GONE); - - leaderName.setText(context.getString(R.string.byLeader, challenge.leaderName)); - participantCount.setText(String.valueOf(challenge.memberCount)); - leaderParticipantLayout.setVisibility(View.VISIBLE); - arrowImage.setVisibility(View.GONE); - } - - gemPrizeTextView.setText(String.valueOf(challenge.prize)); - } - - @Override - public void onClick(View view) { - if (challenge != null && challenge.isManaged() && challenge.isManaged()) { - if (viewUserChallengesOnly) { - EventBus.getDefault().post(new ShowChallengeDetailActivityCommand(challenge.id)); - } else { - EventBus.getDefault().post(new ShowChallengeDetailDialogCommand(challenge.id)); - } - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.kt new file mode 100644 index 000000000..ec3945f7f --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChallengesListViewAdapter.kt @@ -0,0 +1,133 @@ +package com.habitrpg.android.habitica.ui.adapter.social + +import android.support.v4.content.ContextCompat +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailActivityCommand +import com.habitrpg.android.habitica.events.commands.ShowChallengeDetailDialogCommand +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.social.Challenge +import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import net.pherth.android.emoji_library.EmojiParser +import net.pherth.android.emoji_library.EmojiTextView +import org.greenrobot.eventbus.EventBus + +class ChallengesListViewAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean, private val viewUserChallengesOnly: Boolean, private val userId: String) : RealmRecyclerViewAdapter(data, autoUpdate) { + private var unfilteredData: OrderedRealmCollection? = null + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChallengeViewHolder { + return ChallengeViewHolder(parent.inflate(R.layout.challenge_item), viewUserChallengesOnly) + } + + override fun onBindViewHolder(holder: ChallengeViewHolder, position: Int) { + data.notNull { + holder.bind(it[position]) + } + } + + fun updateUnfilteredData(data: OrderedRealmCollection?) { + super.updateData(data) + unfilteredData = data + } + + fun filter(filterOptions: ChallengeFilterOptions) { + if (unfilteredData == null) { + return + } + + var query = unfilteredData?.where() + + if (filterOptions.showByGroups != null && filterOptions.showByGroups.size > 0) { + val groupIds = arrayOfNulls(filterOptions.showByGroups.size) + var index = 0 + for (group in filterOptions.showByGroups) { + groupIds[index] = group.id + index += 1 + } + query = query?.`in`("groupId", groupIds) + } + + if (filterOptions.showOwned != filterOptions.notOwned) { + query = if (filterOptions.showOwned) { + query?.equalTo("leaderId", userId) + } else { + query?.notEqualTo("leaderId", userId) + } + } + + query.notNull { + this.updateData(it.findAll()) + } + } + + class ChallengeViewHolder internal constructor(itemView: View, private val viewUserChallengesOnly: Boolean) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + private val challengeName: EmojiTextView by bindView(R.id.challenge_name) + private val challengeDescription: TextView by bindView(R.id.challenge_group_name) + private val leaderParticipantLayout: LinearLayout by bindView(R.id.leaderParticipantLayout) + private val leaderName: TextView by bindView(R.id.leaderName) + private val participantCount: TextView by bindView(R.id.participantCount) + private val officialChallengeLayout: LinearLayout by bindView(R.id.officialHabiticaChallengeLayout) + private val challengeParticipatingTextView: View by bindView(R.id.challenge_is_participating) + private val memberCountTextView: TextView by bindView(R.id.memberCountTextView) + private val arrowImage: LinearLayout by bindView(R.id.arrowImage) + private val gemPrizeTextView: TextView by bindView(R.id.gemPrizeTextView) + private val gemIconView: ImageView by bindView(R.id.gem_icon) + + private var challenge: Challenge? = null + + init { + itemView.setOnClickListener(this) + + gemIconView.setImageBitmap(HabiticaIconsHelper.imageOfGem()) + + if (!viewUserChallengesOnly) { + challengeName.setTextColor(ContextCompat.getColor(itemView.context, R.color.brand_200)) + } + } + + fun bind(challenge: Challenge) { + this.challenge = challenge + + challengeName.text = EmojiParser.parseEmojis(challenge.name.trim { it <= ' ' }) + challengeDescription.text = challenge.groupName + + officialChallengeLayout.visibility = if (challenge.official) View.VISIBLE else View.GONE + + if (viewUserChallengesOnly) { + leaderParticipantLayout.visibility = View.GONE + challengeParticipatingTextView.visibility = View.GONE + arrowImage.visibility = View.VISIBLE + } else { + challengeParticipatingTextView.visibility = if (challenge.isParticipating) View.VISIBLE else View.GONE + + leaderName.text = itemView.context.getString(R.string.byLeader, challenge.leaderName) + participantCount.text = challenge.memberCount.toString() + leaderParticipantLayout.visibility = View.VISIBLE + arrowImage.visibility = View.GONE + } + + gemPrizeTextView.text = challenge.prize.toString() + } + + override fun onClick(view: View) { + if (challenge != null && challenge!!.isManaged && challenge!!.isManaged) { + if (viewUserChallengesOnly) { + EventBus.getDefault().post(ShowChallengeDetailActivityCommand(challenge!!.id)) + } else { + EventBus.getDefault().post(ShowChallengeDetailDialogCommand(challenge!!.id)) + } + } + } + } +} 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 deleted file mode 100644 index 7a5fe5544..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.java +++ /dev/null @@ -1,316 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.PopupMenu; -import android.support.v7.widget.RecyclerView; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.social.ChatMessage; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils; -import com.habitrpg.android.habitica.ui.helpers.MarkdownParser; - -import net.pherth.android.emoji_library.EmojiTextView; - -import java.lang.reflect.Field; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.Maybe; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; - -public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter { - - private User user; - private boolean isTavern; - private String uuid; - private User sendingUser; - - private PublishSubject likeMessageEvents = PublishSubject.create(); - private PublishSubject userLabelClickEvents = PublishSubject.create(); - private PublishSubject privateMessageClickEvents = PublishSubject.create(); - private PublishSubject deleteMessageEvents = PublishSubject.create(); - private PublishSubject flatMessageEvents = PublishSubject.create(); - private PublishSubject copyMessageAsTodoEvents = PublishSubject.create(); - private PublishSubject copyMessageEvents = PublishSubject.create(); - - public ChatRecyclerViewAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate, User user, boolean isTavern) { - super(data, autoUpdate); - this.user = user; - this.isTavern = isTavern; - if (user != null) this.uuid = user.getId(); - } - - public void setSendingUser(@Nullable User user) { - this.sendingUser = user; - } - - @Override - public ChatRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.tavern_chat_item, parent, false); - return new ChatRecyclerViewHolder(view, uuid, isTavern); - } - - @Override - public void onBindViewHolder(ChatRecyclerViewHolder holder, int position) { - if (getData() != null) { - holder.bind(getData().get(position)); - } - } - - public Flowable getLikeMessageEvents() { - return likeMessageEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getUserLabelClickEvents() { - return userLabelClickEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getPrivateMessageClickEvents() { - return privateMessageClickEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getDeleteMessageEvents() { - return deleteMessageEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getFlagMessageEvents() { - return flatMessageEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getCopyMessageAsTodoEvents() { - return copyMessageAsTodoEvents.toFlowable(BackpressureStrategy.DROP); - } - - public Flowable getCopyMessageEvents() { - return copyMessageEvents.toFlowable(BackpressureStrategy.DROP); - } - - - class ChatRecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, PopupMenu.OnMenuItemClickListener { - - @BindView(R.id.btn_options) - ImageView btnOptions; - @BindView(R.id.user_background_layout) - LinearLayout userBackground; - @BindView(R.id.user_label) - TextView userLabel; - @BindView(R.id.message_text) - EmojiTextView messageText; - @BindView(R.id.ago_label) - TextView agoLabel; - @BindView(R.id.like_background_layout) - LinearLayout likeBackground; - @BindView(R.id.tvLikes) - TextView tvLikes; - - Context context; - Resources res; - private String userId; - private boolean isTavern; - private ChatMessage chatMessage; - - ChatRecyclerViewHolder(View itemView, String currentUserId, boolean isTavern) { - super(itemView); - this.userId = currentUserId; - this.isTavern = isTavern; - - ButterKnife.bind(this, itemView); - - context = itemView.getContext(); - - res = context.getResources(); - - if (btnOptions != null) { - btnOptions.setOnClickListener(this); - } - } - - public void bind(final ChatMessage msg) { - chatMessage = msg; - - setLikeProperties(); - - if (userBackground != null) { - if (msg.getSent() != null && msg.getSent().equals("true") && sendingUser != null) { - DataBindingUtils.INSTANCE.setRoundedBackgroundInt(userBackground, sendingUser.getContributorColor()); - } else { - DataBindingUtils.INSTANCE.setRoundedBackgroundInt(userBackground, msg.getContributorColor()); - } - } - - if (userLabel != null) { - if (msg.getSent() != null && msg.getSent().equals("true")) { - userLabel.setText(sendingUser.getProfile().getName()); - } else { - if (msg.getUser() != null && msg.getUser().length() > 0) { - userLabel.setText(msg.getUser()); - } else { - userLabel.setText(R.string.system); - } - } - - userLabel.setClickable(true); - userLabel.setOnClickListener(view -> userLabelClickEvents.onNext(msg.getUuid())); - } - - DataBindingUtils.INSTANCE.setForegroundTintColor(userLabel, msg.getContributorForegroundColor()); - - if (messageText != null) { - messageText.setText(chatMessage.getParsedText()); - if (msg.getParsedText() == null) { - messageText.setText(chatMessage.getText()); - Maybe.just(chatMessage.getText()) - .map(MarkdownParser.INSTANCE::parseMarkdown) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(parsedText -> { - chatMessage.setParsedText(parsedText); - messageText.setText(chatMessage.getParsedText()); - }, Throwable::printStackTrace); - } - this.messageText.setMovementMethod(LinkMovementMethod.getInstance()); - } - - if (agoLabel != null) { - agoLabel.setText(msg.getAgoString(res)); - } - } - - private void setLikeProperties() { - likeBackground.setVisibility(isTavern ? View.VISIBLE : View.INVISIBLE); - tvLikes.setText("+" + chatMessage.getLikeCount()); - - int backgroundColorRes; - int foregroundColorRes; - - if (chatMessage.getLikeCount() != 0) { - if (chatMessage.userLikesMessage(userId)) { - backgroundColorRes = R.color.tavern_userliked_background; - foregroundColorRes = R.color.tavern_userliked_foreground; - } else { - backgroundColorRes = R.color.tavern_somelikes_background; - foregroundColorRes = R.color.tavern_somelikes_foreground; - } - } else { - backgroundColorRes = R.color.tavern_nolikes_background; - foregroundColorRes = R.color.tavern_nolikes_foreground; - } - - DataBindingUtils.INSTANCE.setRoundedBackground(likeBackground, ContextCompat.getColor(context, backgroundColorRes)); - tvLikes.setTextColor(ContextCompat.getColor(context, foregroundColorRes)); - } - - @Override - public void onClick(View v) { - if (chatMessage != null) { - if (btnOptions == v) { - PopupMenu popupMenu = new PopupMenu(context, v); - - //set my own listener giving the View that activates the event onClick (i.e. YOUR ImageView) - popupMenu.setOnMenuItemClickListener(this); - //inflate your PopUpMenu - popupMenu.getMenuInflater().inflate(R.menu.chat_message, popupMenu.getMenu()); - - // Force icons to show - Object menuHelper = null; - Class[] argTypes; - try { - Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup"); - fMenuHelper.setAccessible(true); - menuHelper = fMenuHelper.get(popupMenu); - argTypes = new Class[]{boolean.class}; - menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true); - } catch (Exception ignored) { - } - - - popupMenu.getMenu().findItem(R.id.menu_chat_delete).setVisible(shouldShowDelete(chatMessage)); - popupMenu.getMenu().findItem(R.id.menu_chat_flag).setVisible(!chatMessage.getUuid().equals("system")); - popupMenu.getMenu().findItem(R.id.menu_chat_copy_as_todo).setVisible(false); - popupMenu.getMenu().findItem(R.id.menu_chat_send_pm).setVisible(false); - - popupMenu.show(); - - // Try to force some horizontal offset - try { - Field fListPopup = menuHelper.getClass().getDeclaredField("mPopup"); - fListPopup.setAccessible(true); - Object listPopup = fListPopup.get(menuHelper); - argTypes = new Class[]{int.class}; - Class listPopupClass = listPopup.getClass(); - - // Get the width of the popup window - int width = (Integer) listPopupClass.getDeclaredMethod("getWidth").invoke(listPopup); - - // Invoke setHorizontalOffset() with the negative width to move left by that distance - listPopupClass.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(listPopup, -width); - - // Invoke show() to update the window's position - listPopupClass.getDeclaredMethod("show").invoke(listPopup); - } catch (Exception ignored) { - - } - } - } - } - - private boolean shouldShowDelete(ChatMessage chatMsg) { - return !chatMsg.isSystemMessage() && (chatMsg.getUuid().equals(userId) || user.getContributor() != null && user.getContributor().getAdmin()); - } - - @OnClick(R.id.tvLikes) - public void toggleLike() { - likeMessageEvents.onNext(chatMessage); - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_chat_delete: { - deleteMessageEvents.onNext(chatMessage); - break; - } - case R.id.menu_chat_flag: { - flatMessageEvents.onNext(chatMessage); - break; - } - case R.id.menu_chat_copy_as_todo: { - copyMessageAsTodoEvents.onNext(chatMessage); - break; - } - - case R.id.menu_chat_send_pm: { - privateMessageClickEvents.onNext(chatMessage.getUuid()); - break; - } - - case R.id.menu_chat_copy: { - copyMessageEvents.onNext(chatMessage); - break; - } - } - - return false; - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt new file mode 100644 index 000000000..a36e87fcd --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt @@ -0,0 +1,263 @@ +package com.habitrpg.android.habitica.ui.adapter.social + +import android.content.Context +import android.content.res.Resources +import android.support.v4.content.ContextCompat +import android.support.v7.widget.PopupMenu +import android.support.v7.widget.RecyclerView +import android.text.method.LinkMovementMethod +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.social.ChatMessage +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils +import com.habitrpg.android.habitica.ui.helpers.MarkdownParser +import com.habitrpg.android.habitica.ui.helpers.bindView +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.Maybe +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import net.pherth.android.emoji_library.EmojiTextView + +class ChatRecyclerViewAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean, private val user: User?, private val isTavern: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate) { + private var uuid: String = "" + private var sendingUser: User? = null + + private val likeMessageEvents = PublishSubject.create() + private val userLabelClickEvents = PublishSubject.create() + private val privateMessageClickEvents = PublishSubject.create() + private val deleteMessageEvents = PublishSubject.create() + private val flagMessageEvents = PublishSubject.create() + private val copyMessageAsTodoEvents = PublishSubject.create() + private val copyMessageEvents = PublishSubject.create() + + init { + if (user != null) this.uuid = user.id + } + + fun setSendingUser(user: User?) { + this.sendingUser = user + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatRecyclerViewHolder { + return ChatRecyclerViewHolder(parent.inflate(R.layout.tavern_chat_item), uuid, isTavern) + } + + override fun onBindViewHolder(holder: ChatRecyclerViewHolder, position: Int) { + data.notNull { holder.bind(it[position]) } + } + + fun getLikeMessageFlowable(): Flowable { + return likeMessageEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getUserLabelClickFlowable(): Flowable { + return userLabelClickEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getPrivateMessageClickFlowable(): Flowable { + return privateMessageClickEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getFlagMessageClickFlowable(): Flowable { + return flagMessageEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getDeleteMessageFlowable(): Flowable { + return deleteMessageEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getCopyMessageAsTodoFlowable(): Flowable { + return copyMessageAsTodoEvents.toFlowable(BackpressureStrategy.DROP) + } + + fun getCopyMessageFlowable(): Flowable { + return copyMessageEvents.toFlowable(BackpressureStrategy.DROP) + } + + + inner class ChatRecyclerViewHolder(itemView: View, private val userId: String, private val isTavern: Boolean) : RecyclerView.ViewHolder(itemView), View.OnClickListener, PopupMenu.OnMenuItemClickListener { + + private val btnOptions: ImageView by bindView(R.id.btn_options) + private val userBackground: LinearLayout by bindView(R.id.user_background_layout) + private val userLabel: TextView by bindView(R.id.user_label) + private val messageText: EmojiTextView by bindView(R.id.message_text) + private val agoLabel: TextView by bindView(R.id.ago_label) + private val likeBackground: LinearLayout by bindView(R.id.like_background_layout) + private val tvLikes: TextView by bindView(R.id.tvLikes) + + val context: Context = itemView.context + val res: Resources = itemView.resources + private var chatMessage: ChatMessage? = null + + init { + btnOptions.setOnClickListener(this) + tvLikes.setOnClickListener { toggleLike() } + } + + fun bind(msg: ChatMessage) { + chatMessage = msg + + setLikeProperties() + + if (msg.sent != null && msg.sent == "true" && sendingUser != null) { + DataBindingUtils.setRoundedBackgroundInt(userBackground, sendingUser!!.contributorColor) + } else { + DataBindingUtils.setRoundedBackgroundInt(userBackground, msg.contributorColor) + } + + if (msg.sent != null && msg.sent == "true") { + userLabel.text = sendingUser?.profile?.name + } else { + if (msg.user != null && msg.user?.isNotEmpty() == true) { + userLabel.text = msg.user + } else { + userLabel.setText(R.string.system) + } + } + + userLabel.isClickable = true + userLabel.setOnClickListener { view -> userLabelClickEvents.onNext(msg.uuid ?: "") } + + DataBindingUtils.setForegroundTintColor(userLabel, msg.contributorForegroundColor) + + messageText.text = chatMessage?.parsedText + if (msg.parsedText == null) { + messageText.text = chatMessage?.text + Maybe.just(chatMessage?.text ?: "") + .map { MarkdownParser.parseMarkdown(it) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ parsedText -> + chatMessage?.parsedText = parsedText + messageText.text = chatMessage?.parsedText + }, { it.printStackTrace() }) + } + this.messageText.movementMethod = LinkMovementMethod.getInstance() + + agoLabel.text = msg.getAgoString(res) + } + + private fun setLikeProperties() { + likeBackground.visibility = if (isTavern) View.VISIBLE else View.INVISIBLE + tvLikes.text = "+" + chatMessage?.likeCount + + val backgroundColorRes: Int + val foregroundColorRes: Int + + if (chatMessage?.likeCount != 0) { + if (chatMessage?.userLikesMessage(userId) == true) { + backgroundColorRes = R.color.tavern_userliked_background + foregroundColorRes = R.color.tavern_userliked_foreground + } else { + backgroundColorRes = R.color.tavern_somelikes_background + foregroundColorRes = R.color.tavern_somelikes_foreground + } + } else { + backgroundColorRes = R.color.tavern_nolikes_background + foregroundColorRes = R.color.tavern_nolikes_foreground + } + + DataBindingUtils.setRoundedBackground(likeBackground, ContextCompat.getColor(context, backgroundColorRes)) + tvLikes.setTextColor(ContextCompat.getColor(context, foregroundColorRes)) + } + + override fun onClick(v: View) { + if (chatMessage != null) { + if (btnOptions === v) { + val popupMenu = PopupMenu(context, v) + + //set my own listener giving the View that activates the event onClick (i.e. YOUR ImageView) + popupMenu.setOnMenuItemClickListener(this) + //inflate your PopUpMenu + popupMenu.menuInflater.inflate(R.menu.chat_message, popupMenu.menu) + + // Force icons to show + var menuHelper: Any? = null + var argTypes: Array> + try { + val fMenuHelper = PopupMenu::class.java.getDeclaredField("mPopup") + fMenuHelper.isAccessible = true + menuHelper = fMenuHelper.get(popupMenu) + argTypes = arrayOf(Boolean::class.java) + menuHelper?.javaClass?.getDeclaredMethod("setForceShowIcon", *argTypes)?.invoke(menuHelper, true) + } catch (ignored: Exception) { + } + + + popupMenu.menu.findItem(R.id.menu_chat_delete).isVisible = shouldShowDelete(chatMessage) + popupMenu.menu.findItem(R.id.menu_chat_flag).isVisible = chatMessage?.uuid != "system" + popupMenu.menu.findItem(R.id.menu_chat_copy_as_todo).isVisible = false + popupMenu.menu.findItem(R.id.menu_chat_send_pm).isVisible = false + + popupMenu.show() + + // Try to force some horizontal offset + try { + val fListPopup = menuHelper?.javaClass?.getDeclaredField("mPopup") + fListPopup?.isAccessible = true + val listPopup = fListPopup?.get(menuHelper) + argTypes = arrayOf(Int::class.java) + val listPopupClass = listPopup?.javaClass + + // Get the width of the popup window + val width = listPopupClass?.getDeclaredMethod("getWidth")?.invoke(listPopup) as Int? + + // Invoke setHorizontalOffset() with the negative width to move left by that distance + listPopupClass?.getDeclaredMethod("setHorizontalOffset", *argTypes)?.invoke(listPopup, -(width ?: 0)) + + // Invoke show() to update the window's position + listPopupClass?.getDeclaredMethod("show")?.invoke(listPopup) + } catch (ignored: Exception) { + + } + + } + } + } + + private fun shouldShowDelete(chatMsg: ChatMessage?): Boolean { + return chatMsg?.isSystemMessage != true && (chatMsg?.uuid == userId || user?.contributor != null && user.contributor.admin) + } + + fun toggleLike() { + chatMessage.notNull { likeMessageEvents.onNext(it) } + } + + override fun onMenuItemClick(item: MenuItem): Boolean { + chatMessage.notNull { + when (item.itemId) { + R.id.menu_chat_delete -> { + deleteMessageEvents.onNext(it) + } + R.id.menu_chat_flag -> { + flagMessageEvents.onNext(it) + } + R.id.menu_chat_copy_as_todo -> { + copyMessageAsTodoEvents.onNext(it) + } + + R.id.menu_chat_send_pm -> { + privateMessageClickEvents.onNext(it.uuid ?: "") + } + + R.id.menu_chat_copy -> { + copyMessageEvents.onNext(it) + } + } + } + return 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 deleted file mode 100644 index d7d49e89c..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social; - -import android.content.Context; -import android.content.res.Resources; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.members.Member; -import com.habitrpg.android.habitica.models.members.MemberPreferences; -import com.habitrpg.android.habitica.models.user.Stats; -import com.habitrpg.android.habitica.ui.AvatarView; -import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel; -import com.habitrpg.android.habitica.ui.helpers.ViewHelper; -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper; -import com.habitrpg.android.habitica.ui.views.ValueBar; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.subjects.PublishSubject; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; - -public class PartyMemberRecyclerViewAdapter extends RealmRecyclerViewAdapter { - - - private Context context; - - private PublishSubject userClickedEvents = PublishSubject.create(); - - - public PartyMemberRecyclerViewAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate, Context context) { - super(data, autoUpdate); - this.context = context; - } - - @Override - public MemberViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.party_member, parent, false); - - return new MemberViewHolder(view); - } - - @Override - public void onBindViewHolder(MemberViewHolder holder, int position) { - if (getData() != null) { - holder.bind(getData().get(position)); - } - } - - public Flowable getUserClickedEvents() { - return userClickedEvents.toFlowable(BackpressureStrategy.DROP); - } - - class MemberViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.avatarView) - AvatarView avatarView; - - @BindView(R.id.username) - TextView userName; - - @BindView(R.id.user_lvl) - TextView lvl; - - @BindView(R.id.class_label) - TextView classLabel; - - @BindView(R.id.class_background_layout) - View classBackground; - - @BindView(R.id.hpBar) - ValueBar hpBar; - - Resources resources; - - MemberViewHolder(View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - hpBar.setLightBackground(true); - hpBar.setIcon(HabiticaIconsHelper.imageOfHeartLightBg()); - - resources = itemView.getResources(); - } - - public void bind(Member user) { - avatarView.setAvatar(user); - - AvatarWithBarsViewModel.Companion.setHpBarData(hpBar, user.getStats()); - - lvl.setText(context.getString(R.string.user_level, user.getStats().getLvl())); - - classLabel.setText(user.getStats().getTranslatedClassName(context)); - - MemberPreferences preferences = user.getPreferences(); - - int colorResourceID; - switch (user.getStats().habitClass) { - case Stats.HEALER: { - colorResourceID = R.color.class_healer; - break; - } - case Stats.WARRIOR: { - colorResourceID = R.color.class_warrior; - break; - } - case Stats.ROGUE: { - colorResourceID = R.color.class_rogue; - break; - } - case Stats.MAGE: { - colorResourceID = R.color.class_wizard; - break; - } - default: - colorResourceID = R.color.task_gray; - } - ViewHelper.SetBackgroundTint(classBackground, ContextCompat.getColor(context, colorResourceID)); - userName.setText(user.getProfile().getName()); - - if (itemView != null) { - itemView.setClickable(true); - itemView.setOnClickListener(view -> userClickedEvents.onNext(user.getId())); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.kt new file mode 100644 index 000000000..7425e9ab5 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PartyMemberRecyclerViewAdapter.kt @@ -0,0 +1,89 @@ +package com.habitrpg.android.habitica.ui.adapter.social + +import android.content.Context +import android.support.v4.content.ContextCompat +import android.support.v7.widget.RecyclerView +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.members.Member +import com.habitrpg.android.habitica.models.user.Stats +import com.habitrpg.android.habitica.ui.AvatarView +import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel +import com.habitrpg.android.habitica.ui.helpers.ViewHelper +import com.habitrpg.android.habitica.ui.helpers.bindView +import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper +import com.habitrpg.android.habitica.ui.views.ValueBar +import io.reactivex.BackpressureStrategy +import io.reactivex.Flowable +import io.reactivex.subjects.PublishSubject +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter + +class PartyMemberRecyclerViewAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean, private val context: Context) : RealmRecyclerViewAdapter(data, autoUpdate) { + + private val userClickedEvents = PublishSubject.create() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MemberViewHolder { + return MemberViewHolder(parent.inflate(R.layout.party_member)) + } + + override fun onBindViewHolder(holder: MemberViewHolder, position: Int) { + data.notNull { + holder.bind(it[position]) + } + } + + fun getUserClickedEvents(): Flowable { + return userClickedEvents.toFlowable(BackpressureStrategy.DROP) + } + + inner class MemberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + private val avatarView: AvatarView by bindView(R.id.avatarView) + private val userName: TextView by bindView(R.id.username) + private val lvl: TextView by bindView(R.id.user_lvl) + private val classLabel: TextView by bindView(R.id.class_label) + private val classBackground: View by bindView(R.id.class_background_layout) + private val hpBar: ValueBar by bindView(R.id.hpBar) + + init { + hpBar.setLightBackground(true) + hpBar.setIcon(HabiticaIconsHelper.imageOfHeartLightBg()) + } + + fun bind(user: Member) { + avatarView.setAvatar(user) + + AvatarWithBarsViewModel.setHpBarData(hpBar, user.stats) + + lvl.text = context.getString(R.string.user_level, user.stats.getLvl()) + + classLabel.text = user.stats.getTranslatedClassName(context) + + val colorResourceID: Int = when (user.stats.habitClass) { + Stats.HEALER -> { + R.color.class_healer + } + Stats.WARRIOR -> { + R.color.class_warrior + } + Stats.ROGUE -> { + R.color.class_rogue + } + Stats.MAGE -> { + R.color.class_wizard + } + else -> R.color.task_gray + } + ViewHelper.SetBackgroundTint(classBackground, ContextCompat.getColor(context, colorResourceID)) + userName.text = user.profile.name + + itemView.isClickable = true + itemView.setOnClickListener { userClickedEvents.onNext(user.id) } + } + } +} 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 deleted file mode 100644 index 3c25706b7..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social; - -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -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 com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.ApiClient; -import com.habitrpg.android.habitica.events.DisplayFragmentEvent; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.social.Group; -import com.habitrpg.android.habitica.ui.fragments.social.GuildFragment; - -import org.greenrobot.eventbus.EventBus; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.realm.Case; -import io.realm.OrderedRealmCollection; -import io.realm.RealmRecyclerViewAdapter; - -public class PublicGuildsRecyclerViewAdapter extends RealmRecyclerViewAdapter implements Filterable { - - public ApiClient apiClient; - private List memberGuildIDs; - - public PublicGuildsRecyclerViewAdapter(@Nullable OrderedRealmCollection data, boolean autoUpdate) { - super(data, autoUpdate); - } - - public void setMemberGuildIDs(List memberGuildIDs) { - this.memberGuildIDs = memberGuildIDs; - } - - @Override - public GuildViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_public_guild, parent, false); - GuildViewHolder guildViewHolder = new GuildViewHolder(view); - guildViewHolder.itemView.setOnClickListener(v -> { - Group guild = (Group) v.getTag(); - GuildFragment guildFragment = new GuildFragment(); - guildFragment.setGuildId(guild.getId()); - guildFragment.isMember = isInGroup(guild); - DisplayFragmentEvent event = new DisplayFragmentEvent(); - event.fragment = guildFragment; - EventBus.getDefault().post(event); - }); - guildViewHolder.joinLeaveButton.setOnClickListener(v -> { - Group guild = (Group) v.getTag(); - boolean isMember = this.memberGuildIDs != null && this.memberGuildIDs.contains(guild.getId()); - if (isMember) { - PublicGuildsRecyclerViewAdapter.this.apiClient.leaveGroup(guild.getId()) - .subscribe(aVoid -> { - memberGuildIDs.remove(guild.getId()); - if (getData() != null) { - int indexOfGroup = getData().indexOf(guild); - notifyItemChanged(indexOfGroup); - } - }, RxErrorHandler.handleEmptyError()); - } else { - PublicGuildsRecyclerViewAdapter.this.apiClient.joinGroup(guild.getId()) - .subscribe(group -> { - memberGuildIDs.add(group.getId()); - if (getData() != null) { - int indexOfGroup = getData().indexOf(group); - notifyItemChanged(indexOfGroup); - } - }, RxErrorHandler.handleEmptyError()); - } - - }); - return guildViewHolder; - } - - @Override - public void onBindViewHolder(GuildViewHolder holder, int position) { - if (getData() != null && holder != null) { - Group guild = getData().get(position); - boolean isInGroup = isInGroup(guild); - holder.bind(guild, isInGroup); - holder.itemView.setTag(guild); - holder.joinLeaveButton.setTag(guild); - } - } - - private boolean isInGroup(Group guild) { - return this.memberGuildIDs != null && this.memberGuildIDs.contains(guild.getId()); - } - - @Override - public Filter getFilter() { - return new Filter() { - @Override - protected FilterResults performFiltering(CharSequence constraint) { - FilterResults results = new FilterResults(); - results.values = constraint; - return new FilterResults(); - } - - @Override - protected void publishResults(CharSequence constraint, FilterResults results) { - if (getData() != null && constraint.length() > 0) { - updateData(getData().where() - .contains("name", String.valueOf(constraint), Case.INSENSITIVE) - .findAll()); - } - } - }; - } - - - static class GuildViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.nameTextView) - TextView nameTextView; - - @BindView(R.id.memberCountTextView) - TextView memberCountTextView; - - @BindView(R.id.descriptionTextView) - TextView descriptionTextView; - - @BindView(R.id.joinleaveButton) - Button joinLeaveButton; - - GuildViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - - public void bind(Group guild, boolean isInGroup) { - this.nameTextView.setText(guild.getName()); - this.memberCountTextView.setText(String.valueOf(guild.getMemberCount())); - this.descriptionTextView.setText(guild.getDescription()); - if (isInGroup) { - this.joinLeaveButton.setText(R.string.leave); - } else { - this.joinLeaveButton.setText(R.string.join); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.kt new file mode 100644 index 000000000..cf60048ed --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/PublicGuildsRecyclerViewAdapter.kt @@ -0,0 +1,125 @@ +package com.habitrpg.android.habitica.ui.adapter.social + +import android.support.v7.widget.RecyclerView +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 com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.ApiClient +import com.habitrpg.android.habitica.events.DisplayFragmentEvent +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.social.Group +import com.habitrpg.android.habitica.ui.fragments.social.GuildFragment +import com.habitrpg.android.habitica.ui.helpers.bindView +import io.reactivex.functions.Consumer +import io.realm.Case +import io.realm.OrderedRealmCollection +import io.realm.RealmRecyclerViewAdapter +import org.greenrobot.eventbus.EventBus + +class PublicGuildsRecyclerViewAdapter(data: OrderedRealmCollection?, autoUpdate: Boolean) : RealmRecyclerViewAdapter(data, autoUpdate), Filterable { + + var apiClient: ApiClient? = null + private var memberGuildIDs: MutableList = mutableListOf() + + fun setMemberGuildIDs(memberGuildIDs: MutableList) { + this.memberGuildIDs = memberGuildIDs + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GuildViewHolder { + val guildViewHolder = GuildViewHolder(parent.inflate(R.layout.item_public_guild)) + guildViewHolder.itemView.setOnClickListener { v -> + val guild = v.tag as Group + val guildFragment = GuildFragment() + guildFragment.setGuildId(guild.id) + guildFragment.isMember = isInGroup(guild) + val event = DisplayFragmentEvent() + event.fragment = guildFragment + EventBus.getDefault().post(event) + } + guildViewHolder.joinLeaveButton.setOnClickListener { v -> + val guild = v.tag as Group + val isMember = this.memberGuildIDs.contains(guild.id) + if (isMember) { + this@PublicGuildsRecyclerViewAdapter.apiClient!!.leaveGroup(guild.id) + .subscribe(Consumer { + memberGuildIDs.remove(guild.id) + if (data != null) { + val indexOfGroup = data!!.indexOf(guild) + notifyItemChanged(indexOfGroup) + } + }, RxErrorHandler.handleEmptyError()) + } else { + this@PublicGuildsRecyclerViewAdapter.apiClient!!.joinGroup(guild.id) + .subscribe(Consumer { group -> + memberGuildIDs.add(group.id) + if (data != null) { + val indexOfGroup = data!!.indexOf(group) + notifyItemChanged(indexOfGroup) + } + }, RxErrorHandler.handleEmptyError()) + } + + } + return guildViewHolder + } + + override fun onBindViewHolder(holder: GuildViewHolder, position: Int) { + data.notNull { + val guild = it[position] + val isInGroup = isInGroup(guild) + holder.bind(guild, isInGroup) + holder.itemView.tag = guild + holder.joinLeaveButton.tag = guild + } + } + + private fun isInGroup(guild: Group): Boolean { + return this.memberGuildIDs.contains(guild.id) + } + + override fun getFilter(): Filter { + return object : Filter() { + override fun performFiltering(constraint: CharSequence): Filter.FilterResults { + val results = Filter.FilterResults() + results.values = constraint + return Filter.FilterResults() + } + + override fun publishResults(constraint: CharSequence, results: Filter.FilterResults) { + data.notNull { + if (constraint.isNotEmpty()) { + updateData(it.where() + .contains("name", constraint.toString(), Case.INSENSITIVE) + .findAll()) + } + } + } + } + } + + class GuildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + private val nameTextView: TextView by bindView(R.id.nameTextView) + private val memberCountTextView: TextView by bindView(R.id.memberCountTextView) + private val descriptionTextView: TextView by bindView(R.id.descriptionTextView) + internal val joinLeaveButton: Button by bindView(R.id.joinleaveButton) + + + fun bind(guild: Group, isInGroup: Boolean) { + this.nameTextView.text = guild.name + this.memberCountTextView.text = guild.memberCount.toString() + this.descriptionTextView.text = guild.description + if (isInGroup) { + this.joinLeaveButton.setText(R.string.leave) + } else { + this.joinLeaveButton.setText(R.string.join) + } + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.java deleted file mode 100644 index 85231a087..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.social.challenges; - -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; - -import com.github.underscore.U; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.social.Group; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class ChallengesFilterRecyclerViewAdapter extends RecyclerView.Adapter { - - - private List entries; - private List holderList; - - public ChallengesFilterRecyclerViewAdapter(Collection entries) { - - this.entries = new ArrayList<>(entries); - this.holderList = new ArrayList<>(); - } - - @Override - public ChallengesFilterRecyclerViewAdapter.ChallengeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.dialog_challenge_filter_group_item, parent, false); - - ChallengeViewHolder challengeViewHolder = new ChallengeViewHolder(view); - holderList.add(challengeViewHolder); - - return challengeViewHolder; - } - - @Override - public void onBindViewHolder(ChallengesFilterRecyclerViewAdapter.ChallengeViewHolder holder, int position) { - holder.bind(entries.get(position)); - } - - @Override - public int getItemCount() { - return entries.size(); - } - - public void deSelectAll(){ - for (ChallengeViewHolder h : holderList) { - h.checkbox.setChecked(false); - } - } - - public void selectAll(){ - for (ChallengeViewHolder h : holderList) { - h.checkbox.setChecked(true); - } - } - - public void selectAll(List groupsToCheck){ - for (ChallengeViewHolder h : holderList) { - h.checkbox.setChecked(U.find(groupsToCheck, g -> h.group.getId().equals(g.getId())).isPresent()); - } - } - public List getCheckedEntries(){ - ArrayList result = new ArrayList<>(); - - for (ChallengeViewHolder h : holderList) { - if(h.checkbox.isChecked()){ - result.add(h.group); - } - } - - return result; - } - - public static class ChallengeViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.challenge_filter_group_checkbox) - CheckBox checkbox; - - public Group group; - - public ChallengeViewHolder(View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - } - - public void bind(Group group) { - this.group = group; - - checkbox.setText(group.getName()); - } - } -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt new file mode 100644 index 000000000..d6884a0f5 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/challenges/ChallengesFilterRecyclerViewAdapter.kt @@ -0,0 +1,86 @@ +package com.habitrpg.android.habitica.ui.adapter.social.challenges + +import android.support.v7.widget.RecyclerView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CheckBox +import com.github.underscore.U +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.notNull +import com.habitrpg.android.habitica.models.social.Group +import com.habitrpg.android.habitica.ui.helpers.bindView +import java.util.* + +class ChallengesFilterRecyclerViewAdapter(entries: Collection) : RecyclerView.Adapter() { + + + private val entries: List + private val holderList: MutableList + val checkedEntries: List + get() { + val result = ArrayList() + + for (h in holderList) { + if (h.checkbox.isChecked) { + h.group.notNull { + result.add(it) + } + } + } + return result + } + + init { + this.entries = ArrayList(entries) + this.holderList = ArrayList() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChallengesFilterRecyclerViewAdapter.ChallengeViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.dialog_challenge_filter_group_item, parent, false) + + val challengeViewHolder = ChallengeViewHolder(view) + holderList.add(challengeViewHolder) + + return challengeViewHolder + } + + override fun onBindViewHolder(holder: ChallengesFilterRecyclerViewAdapter.ChallengeViewHolder, position: Int) { + holder.bind(entries[position]) + } + + override fun getItemCount(): Int { + return entries.size + } + + fun deSelectAll() { + for (h in holderList) { + h.checkbox.isChecked = false + } + } + + fun selectAll() { + for (h in holderList) { + h.checkbox.isChecked = true + } + } + + fun selectAll(groupsToCheck: List) { + for (h in holderList) { + h.checkbox.isChecked = U.find(groupsToCheck) { g -> h.group?.id == g.id }.isPresent + } + } + + class ChallengeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + internal val checkbox: CheckBox by bindView(itemView, R.id.challenge_filter_group_checkbox) + + var group: Group? = null + + fun bind(group: Group) { + this.group = group + + checkbox.text = group.name + } + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.java deleted file mode 100644 index fd32560bb..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.tasks; - -import android.graphics.Color; -import android.support.v7.widget.RecyclerView; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.models.tasks.ChecklistItem; -import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperAdapter; -import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperViewHolder; - -import net.pherth.android.emoji_library.EmojiEditText; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class CheckListAdapter extends RecyclerView.Adapter - implements ItemTouchHelperAdapter { - - private final List items = new ArrayList<>(); - - public CheckListAdapter() { - } - - public void setItems(List items) { - this.items.addAll(items); - } - - @Override - public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.checklist_item, parent, false); - return new ItemViewHolder(view); - } - - @Override - public void onBindViewHolder(final ItemViewHolder holder, int position) { - holder.textWatcher.id = null; - holder.checkListTextView.setText(items.get(position).getText()); - holder.textWatcher.id = items.get(position).getId(); - } - - public void addItem(ChecklistItem item) { - items.add(item); - notifyItemInserted(items.size() - 1); - } - - public List getCheckListItems() { - return items; - } - - @Override - public int getItemCount() { - return items.size(); - } - - - @Override - public void onItemDismiss(int position) { - if (position >= 0 && position < items.size()) { - items.remove(position); - notifyItemRemoved(position); - } - } - - - @Override - public void onItemMove(int fromPosition, int toPosition) { - ChecklistItem item = items.get(fromPosition); - items.remove(fromPosition); - items.add(toPosition, item); - notifyItemMoved(fromPosition, toPosition); - } - - class ItemViewHolder extends RecyclerView.ViewHolder implements - ItemTouchHelperViewHolder, Button.OnClickListener { - - ChecklistTextWatcher textWatcher; - @BindView(R.id.item_edittext) - EmojiEditText checkListTextView; - @BindView(R.id.delete_item_button) - Button deleteButton; - - ItemViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - deleteButton.setOnClickListener(this); - - textWatcher = new ChecklistTextWatcher(); - checkListTextView.addTextChangedListener(textWatcher); - } - - @Override - public void onItemSelected() { - itemView.setBackgroundColor(Color.LTGRAY); - } - - @Override - public void onItemClear() { - itemView.setBackgroundColor(0); - } - - @Override - public void onClick(View v) { - if (v == deleteButton) { - CheckListAdapter.this.onItemDismiss(getAdapterPosition()); - } - } - - private class ChecklistTextWatcher implements TextWatcher { - - public String id; - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - if (id == null) { - return; - } - for (ChecklistItem item : items) { - if (id.equals(item.getId())) { - item.setText(checkListTextView.getText().toString()); - break; - } - } - } - } - } -} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.kt new file mode 100644 index 000000000..158832c0e --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/CheckListAdapter.kt @@ -0,0 +1,114 @@ +package com.habitrpg.android.habitica.ui.adapter.tasks + +import android.graphics.Color +import android.support.v7.widget.RecyclerView +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.models.tasks.ChecklistItem +import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperAdapter +import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperViewHolder +import com.habitrpg.android.habitica.ui.helpers.bindView +import net.pherth.android.emoji_library.EmojiEditText +import java.util.* + +class CheckListAdapter : RecyclerView.Adapter(), ItemTouchHelperAdapter { + + private val items = ArrayList() + + val checkListItems: List + get() = items + + fun setItems(items: List) { + this.items.addAll(items) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.checklist_item, parent, false) + return ItemViewHolder(view) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + holder.textWatcher.id = null + holder.checkListTextView.setText(items[position].text) + holder.textWatcher.id = items[position].id + } + + fun addItem(item: ChecklistItem) { + items.add(item) + notifyItemInserted(items.size - 1) + } + + override fun getItemCount(): Int { + return items.size + } + + + override fun onItemDismiss(position: Int) { + if (position >= 0 && position < items.size) { + items.removeAt(position) + notifyItemRemoved(position) + } + } + + + override fun onItemMove(fromPosition: Int, toPosition: Int) { + val item = items[fromPosition] + items.removeAt(fromPosition) + items.add(toPosition, item) + notifyItemMoved(fromPosition, toPosition) + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), ItemTouchHelperViewHolder, View.OnClickListener { + + internal val textWatcher: ChecklistTextWatcher = ChecklistTextWatcher() + internal val checkListTextView: EmojiEditText by bindView(itemView, R.id.item_edittext) + private val deleteButton: Button by bindView(itemView, R.id.delete_item_button) + + init { + deleteButton.setOnClickListener(this) + checkListTextView.addTextChangedListener(textWatcher) + } + + override fun onItemSelected() { + itemView.setBackgroundColor(Color.LTGRAY) + } + + override fun onItemClear() { + itemView.setBackgroundColor(0) + } + + override fun onClick(v: View) { + if (v === deleteButton) { + this@CheckListAdapter.onItemDismiss(adapterPosition) + } + } + + internal inner class ChecklistTextWatcher : TextWatcher { + + var id: String? = null + + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { + + } + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} + + override fun afterTextChanged(s: Editable) { + if (id == null) { + return + } + for (item in items) { + if (id == item.id) { + item.text = checkListTextView.text.toString() + break + } + } + } + } + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java deleted file mode 100644 index 789101bc9..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.habitrpg.android.habitica.ui.adapter.tasks; - -import android.graphics.Color; -import android.support.annotation.Nullable; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.helpers.RemindersManager; -import com.habitrpg.android.habitica.models.tasks.RemindersItem; -import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperAdapter; -import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperViewHolder; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; - -/** - * Created by keithholliday on 5/31/16. - */ -public class RemindersAdapter extends RecyclerView.Adapter - implements ItemTouchHelperAdapter, RemindersManager.ReminderTimeSelectedCallback { - - private final List reminders = new ArrayList<>(); - private final String taskType; - private RemindersManager remindersManager; - - public RemindersAdapter(String taskType) { - this.remindersManager = new RemindersManager(taskType); - this.taskType = taskType; - } - - public void setReminders(List reminders) { - this.reminders.addAll(reminders); - } - - @Override - public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.reminder_item, parent, false); - return new ItemViewHolder(view); - } - - @Override - public void onBindViewHolder(final ItemViewHolder holder, int position) { - Date time = reminders.get(position).getTime(); - holder.reminderItemTextView.setText(remindersManager.reminderTimeToString(time)); - holder.hour = time.getHours(); - holder.minute = time.getMinutes(); - } - - public void addItem(RemindersItem item) { - reminders.add(item); - notifyItemInserted(reminders.size() - 1); - } - - public List getRemindersItems() { - return reminders; - } - - @Override - public int getItemCount() { - return reminders.size(); - } - - - @Override - public void onItemDismiss(int position) { - if (position >= 0 && position < reminders.size()) { - reminders.remove(position); - notifyItemRemoved(position); - } - } - - @Override - public void onItemMove(int fromPosition, int toPosition) { - Collections.swap(reminders, fromPosition, toPosition); - notifyItemMoved(fromPosition, toPosition); - } - - @Override - public void onReminderTimeSelected(@Nullable RemindersItem remindersItem) { - if (remindersItem == null) { - return; - } - for (int pos = 0; pos < reminders.size(); pos++) { - if (remindersItem.getId().equals(reminders.get(pos).getId())) { - reminders.set(pos, remindersItem); - notifyItemChanged(pos); - break; - } - } - } - - class ItemViewHolder extends RecyclerView.ViewHolder implements - ItemTouchHelperViewHolder, Button.OnClickListener { - - @BindView(R.id.item_edittext) - EditText reminderItemTextView; - - @BindView(R.id.delete_item_button) - Button deleteButton; - - int hour, minute; - - ItemViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - deleteButton.setOnClickListener(this); - - reminderItemTextView.setOnClickListener(v -> { - RemindersItem reminder = reminders.get(getAdapterPosition()); - - remindersManager.createReminderTimeDialog(RemindersAdapter.this, taskType, v.getContext(), reminder); - }); - } - - @Override - public void onItemSelected() { - itemView.setBackgroundColor(Color.LTGRAY); - } - - @Override - public void onItemClear() { - itemView.setBackgroundColor(0); - } - - @Override - public void onClick(View v) { - if (v == deleteButton) { - RemindersAdapter.this.onItemDismiss(getAdapterPosition()); - } - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.kt new file mode 100644 index 000000000..65daa1d15 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.kt @@ -0,0 +1,112 @@ +package com.habitrpg.android.habitica.ui.adapter.tasks + +import android.graphics.Color +import android.support.v7.widget.RecyclerView +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.EditText +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.helpers.RemindersManager +import com.habitrpg.android.habitica.models.tasks.RemindersItem +import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperAdapter +import com.habitrpg.android.habitica.ui.helpers.ItemTouchHelperViewHolder +import com.habitrpg.android.habitica.ui.helpers.bindView +import java.util.* + +/** + * Created by keithholliday on 5/31/16. + */ +class RemindersAdapter(private val taskType: String) : RecyclerView.Adapter(), ItemTouchHelperAdapter, RemindersManager.ReminderTimeSelectedCallback { + + private val reminders = ArrayList() + private val remindersManager: RemindersManager = RemindersManager(taskType) + + val remindersItems: List + get() = reminders + + fun setReminders(reminders: List) { + this.reminders.addAll(reminders) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.reminder_item, parent, false) + return ItemViewHolder(view) + } + + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val time = reminders[position].time + holder.reminderItemTextView.setText(remindersManager.reminderTimeToString(time)) + holder.hour = time.hours + holder.minute = time.minutes + } + + fun addItem(item: RemindersItem) { + reminders.add(item) + notifyItemInserted(reminders.size - 1) + } + + override fun getItemCount(): Int { + return reminders.size + } + + + override fun onItemDismiss(position: Int) { + if (position >= 0 && position < reminders.size) { + reminders.removeAt(position) + notifyItemRemoved(position) + } + } + + override fun onItemMove(fromPosition: Int, toPosition: Int) { + Collections.swap(reminders, fromPosition, toPosition) + notifyItemMoved(fromPosition, toPosition) + } + + override fun onReminderTimeSelected(remindersItem: RemindersItem?) { + if (remindersItem == null) { + return + } + for (pos in reminders.indices) { + if (remindersItem.id == reminders[pos].id) { + reminders[pos] = remindersItem + notifyItemChanged(pos) + break + } + } + } + + inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), ItemTouchHelperViewHolder, View.OnClickListener { + + internal val reminderItemTextView: EditText by bindView(itemView, R.id.item_edittext) + private val deleteButton: Button by bindView(itemView, R.id.delete_item_button) + + var hour: Int = 0 + var minute: Int = 0 + + init { + deleteButton.setOnClickListener(this) + + reminderItemTextView.setOnClickListener { v -> + val reminder = reminders[adapterPosition] + + remindersManager.createReminderTimeDialog(this@RemindersAdapter, taskType, v.context, reminder) + } + } + + override fun onItemSelected() { + itemView.setBackgroundColor(Color.LTGRAY) + } + + override fun onItemClear() { + itemView.setBackgroundColor(0) + } + + override fun onClick(v: View) { + if (v === deleteButton) { + this@RemindersAdapter.onItemDismiss(adapterPosition) + } + } + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/GemsPurchaseFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/GemsPurchaseFragment.java index ce0392a23..7a2fe2a70 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/GemsPurchaseFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/GemsPurchaseFragment.java @@ -73,7 +73,7 @@ public class GemsPurchaseFragment extends BaseFragment implements GemPurchaseAct Drawable heartDrawable = new BitmapDrawable(getResources(), HabiticaIconsHelper.imageOfHeartLarge()); supportTextView.setCompoundDrawables(null, heartDrawable, null, null); - gems84View.seedsImageButton.setOnClickListener(v -> ((GemPurchaseActivity) this.getActivity()).showSeedsPromo(getString(R.string.seeds_interstitial_gems), "store")); + gems84View.getSeedsImageButton().setOnClickListener(v -> ((GemPurchaseActivity) this.getActivity()).showSeedsPromo(getString(R.string.seeds_interstitial_gems), "store")); } @Override diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/faq/FAQOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/faq/FAQOverviewFragment.kt index c2a24fbcd..b2d344f02 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/faq/FAQOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/faq/FAQOverviewFragment.kt @@ -40,7 +40,7 @@ class FAQOverviewFragment : BaseMainFragment() { resetViews() adapter = FAQOverviewRecyclerAdapter() - adapter?.resetWalkthroughEvents?.subscribe(Consumer { this.userRepository.resetTutorial(user) }, RxErrorHandler.handleEmptyError()) + adapter?.getResetWalkthroughEvents()?.subscribe(Consumer { this.userRepository.resetTutorial(user) }, RxErrorHandler.handleEmptyError()) adapter?.activity = activity recyclerView?.layoutManager = LinearLayoutManager(activity) recyclerView?.addItemDecoration(DividerItemDecoration(getActivity()!!, DividerItemDecoration.VERTICAL)) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 0e62627e2..070b31812 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -99,11 +99,11 @@ class ItemRecyclerFragment : BaseFragment() { recyclerView?.adapter = adapter adapter?.notNull { - compositeSubscription.add(it.sellItemEvents + compositeSubscription.add(it.getSellItemFlowable() .flatMap { item -> inventoryRepository.sellItem(user, item) } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.questInvitationEvents + compositeSubscription.add(it.getQuestInvitationFlowable() .flatMap { quest -> inventoryRepository.inviteToQuest(quest) } .subscribe(Consumer { EventBus.getDefault().post(OpenMenuItemCommand(NavigationDrawerFragment.SIDEBAR_PARTY)) }, RxErrorHandler.handleEmptyError())) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.java index aaa807186..e0b87175e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.java @@ -48,13 +48,12 @@ public class MountDetailRecyclerFragment extends BaseMainFragment { adapter = (MountDetailRecyclerAdapter) recyclerView.getAdapter(); if (adapter == null) { adapter = new MountDetailRecyclerAdapter(null, true); - adapter.context = this.getActivity(); - adapter.itemType = this.animalType; + adapter.setItemType(this.animalType); recyclerView.setAdapter(adapter); recyclerView.setItemAnimator(new SafeDefaultItemAnimator()); this.loadItems(); - getCompositeSubscription().add(adapter.getEquipEvents() + getCompositeSubscription().add(adapter.getEquipFlowable() .flatMap(key -> inventoryRepository.equip(user, "mount", key)) .subscribe(items -> {}, RxErrorHandler.handleEmptyError())); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt index fafa63584..21f50a233 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt @@ -67,7 +67,7 @@ class PetDetailRecyclerFragment : BaseMainFragment() { recyclerView.itemAnimator = SafeDefaultItemAnimator() this.loadItems() - compositeSubscription.add(adapter.equipEvents + compositeSubscription.add(adapter.getEquipFlowable() .flatMap { key -> inventoryRepository.equip(user, "pet", key) } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt index 0209fdf64..6efbd6186 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt @@ -86,7 +86,7 @@ class StableRecyclerFragment : BaseFragment() { } - adapter = recyclerView?.adapter as StableRecyclerAdapter + adapter = recyclerView?.adapter as StableRecyclerAdapter? if (adapter == null) { adapter = StableRecyclerAdapter() adapter?.activity = this.activity as MainActivity? diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt index cb0c4a891..da5f0b3d4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/AvatarSetupFragment.kt @@ -118,7 +118,7 @@ class AvatarSetupFragment : BaseFragment() { override fun setUserVisibleHint(isVisibleToUser: Boolean) { super.setUserVisibleHint(isVisibleToUser) if (isVisibleToUser && context != null) { - speechBubbleView?.animateText(context?.getString(R.string.avatar_setup_description)) + speechBubbleView?.animateText(context?.getString(R.string.avatar_setup_description) ?: "") } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt index 6567157e9..2ce1c679b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/TaskSetupFragment.kt @@ -61,7 +61,7 @@ class TaskSetupFragment : BaseFragment() { override fun setUserVisibleHint(isVisibleToUser: Boolean) { super.setUserVisibleHint(isVisibleToUser) if (isVisibleToUser && context != null) { - speechBubbleView?.animateText(context?.getString(R.string.task_setup_description)) + speechBubbleView?.animateText(context?.getString(R.string.task_setup_description) ?: "") } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt index 4fb265b25..05da956c0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/setup/WelcomeFragment.kt @@ -34,7 +34,7 @@ class WelcomeFragment : BaseFragment() { resetViews() - speechBubbleView?.animateText(context?.getString(R.string.welcome_text)) + speechBubbleView?.animateText(context?.getString(R.string.welcome_text) ?: "") heartIconView?.setImageBitmap(HabiticaIconsHelper.imageOfHeartLightBg()) expIconView?.setImageBitmap(HabiticaIconsHelper.imageOfExperience()) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt index 3572bfd8a..f844aa5a5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt @@ -72,7 +72,7 @@ class SkillsFragment : BaseMainFragment() { return } - adapter?.mana = this.user?.stats?.getMp() + adapter?.mana = this.user?.stats?.getMp() ?: 0.toDouble() user?.let { Observable.concat(userRepository.getSkills(it).firstElement().toObservable().flatMap { Observable.fromIterable(it) }, userRepository.getSpecialItems(it).firstElement().toObservable().flatMap { Observable.fromIterable(it) }) @@ -108,7 +108,7 @@ class SkillsFragment : BaseMainFragment() { private fun displaySkillResult(usedSkill: Skill?, response: SkillResponse) { removeProgressDialog() - adapter?.setMana(response.user.stats.mp) + adapter?.mana = response.user.stats.mp val activity = activity ?: return if ("special" == usedSkill?.habitClass) { showSnackbar(activity.getFloatingMenuWrapper(), context!!.getString(R.string.used_skill_without_mana, usedSkill.text), HabiticaSnackbar.SnackbarDisplayType.BLUE) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/ChatListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/ChatListFragment.kt index 03eac3c66..a082b6d65 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/ChatListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/ChatListFragment.kt @@ -105,12 +105,12 @@ class ChatListFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener { chatAdapter = ChatRecyclerViewAdapter(null, true, user, true) chatAdapter.notNull { - compositeSubscription.add(it.userLabelClickEvents.subscribe(Consumer { userId -> FullProfileActivity.open(context, userId) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.deleteMessageEvents.subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.flagMessageEvents.subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.copyMessageAsTodoEvents.subscribe(Consumer{ this.copyMessageAsTodo(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.copyMessageEvents.subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.likeMessageEvents.flatMap { socialRepository.likeMessage(it) }.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getUserLabelClickFlowable().subscribe(Consumer { userId -> FullProfileActivity.open(context, userId) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getDeleteMessageFlowable().subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getFlagMessageClickFlowable().subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getCopyMessageAsTodoFlowable().subscribe(Consumer{ this.copyMessageAsTodo(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getCopyMessageFlowable().subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getLikeMessageFlowable().flatMap { socialRepository.likeMessage(it) }.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt index d2f40c0de..b3dfe08c1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt @@ -61,11 +61,11 @@ class InboxMessageListFragment : BaseMainFragment(), SwipeRefreshLayout.OnRefres recyclerView.adapter = chatAdapter recyclerView.itemAnimator = SafeDefaultItemAnimator() chatAdapter.notNull { - compositeSubscription.add(it.userLabelClickEvents.subscribe(Consumer { FullProfileActivity.open(context, it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.deleteMessageEvents.subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.flagMessageEvents.subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.copyMessageAsTodoEvents.subscribe(Consumer { this.copyMessageAsTodo(it) }, RxErrorHandler.handleEmptyError())) - compositeSubscription.add(it.copyMessageEvents.subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getUserLabelClickFlowable().subscribe(Consumer { FullProfileActivity.open(context, it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getDeleteMessageFlowable().subscribe(Consumer { this.showDeleteConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getFlagMessageClickFlowable().subscribe(Consumer { this.showFlagConfirmationDialog(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getCopyMessageAsTodoFlowable().subscribe(Consumer { this.copyMessageAsTodo(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(it.getCopyMessageFlowable().subscribe(Consumer { this.copyMessageToClipboard(it) }, RxErrorHandler.handleEmptyError())) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.kt index a03a6d110..2efa5e546 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/PublicGuildsFragment.kt @@ -48,7 +48,7 @@ class PublicGuildsFragment : BaseMainFragment(), SearchView.OnQueryTextListener recyclerView?.layoutManager = LinearLayoutManager(this.activity) recyclerView?.addItemDecoration(DividerItemDecoration(getActivity()!!, DividerItemDecoration.VERTICAL)) - viewAdapter.setMemberGuildIDs(this.memberGuildIDs) + viewAdapter.setMemberGuildIDs(this.memberGuildIDs?.toMutableList() ?: mutableListOf()) viewAdapter.apiClient = this.apiClient viewAdapter = PublicGuildsRecyclerViewAdapter(null, true) recyclerView?.adapter = viewAdapter diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt index b83d1895c..41cdec231 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeFilterDialogHolder.kt @@ -53,11 +53,10 @@ internal class ChallengeFilterDialogHolder private constructor(view: View, priva } private fun fillChallengeGroups() { - this.groupRecyclerView?.layoutManager = LinearLayoutManager(context) adapter = ChallengesFilterRecyclerViewAdapter(getGroups(challengesViewed)) if (currentFilter != null && currentFilter?.showByGroups != null) { - adapter?.selectAll(currentFilter?.showByGroups) + adapter?.selectAll(currentFilter?.showByGroups ?: emptyList()) } this.groupRecyclerView?.adapter = adapter diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt index 96bae48e4..405958762 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt @@ -8,7 +8,6 @@ import android.support.v7.widget.LinearLayoutManager import android.view.* import android.widget.RelativeLayout import android.widget.TextView -import butterknife.ButterKnife import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.AppComponent import com.habitrpg.android.habitica.data.ChallengeRepository @@ -153,7 +152,7 @@ class ChallengeListFragment : BaseMainFragment(), SwipeRefreshLayout.OnRefreshLi private fun changeFilter(challengeFilterOptions: ChallengeFilterOptions) { filterOptions = challengeFilterOptions - challengeAdapter?.filter(filterOptions) + challengeAdapter?.filter(challengeFilterOptions) } override fun onOptionsItemSelected(item: MenuItem?): Boolean { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.java deleted file mode 100644 index 2daf66b2d..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.habitrpg.android.habitica.ui.views.yesterdailies; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.os.Build; -import android.support.annotation.NonNull; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.TaskRepository; -import com.habitrpg.android.habitica.data.UserRepository; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.models.tasks.ChecklistItem; -import com.habitrpg.android.habitica.models.tasks.Task; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import butterknife.BindColor; -import butterknife.BindView; -import butterknife.ButterKnife; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; - -public class YesterdailyDialog extends AlertDialog { - - static boolean isDisplaying = false; - - private final List tasks; - private final TaskRepository taskRepository; - private UserRepository userRepository; - - @BindView(R.id.yesterdailies_list) - LinearLayout yesterdailiesList; - - @BindColor(R.color.task_gray) - int taskGray; - - private YesterdailyDialog(@NonNull Context context, UserRepository userRepository, TaskRepository taskRepository, List tasks) { - super(context); - this.userRepository = userRepository; - this.taskRepository = taskRepository; - this.tasks = tasks; - - LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.dialog_yesterdaily, null); - ButterKnife.bind(this, view); - this.setView(view); - this.setButton(AlertDialog.BUTTON_POSITIVE, - context.getString(R.string.start_day), - (dialog, which) -> {}); - - this.setOnDismissListener(dialog -> runCron()); - - createTaskViews(inflater); - } - - private void runCron() { - List completedTasks = new ArrayList<>(); - for (Task task : tasks) { - if (task.getCompleted()) { - completedTasks.add(task); - } - } - userRepository.runCron(completedTasks); - isDisplaying = false; - } - - private void createTaskViews(LayoutInflater inflater) { - for (Task task : tasks) { - View taskView = createNewTaskView(inflater); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - taskView.setClipToOutline(true); - } - configureTaskView(taskView, task); - View taskContainer = taskView.findViewById(R.id.taskHolder); - taskContainer.setOnClickListener(v -> { - task.setCompleted(!task.getCompleted()); - configureTaskView(taskView, task); - }); - - if (task.getChecklist().size() > 0) { - View checklistDivider = taskView.findViewById(R.id.checklistDivider); - checklistDivider.setVisibility(View.VISIBLE); - ViewGroup checklistContainer = taskView.findViewById(R.id.checklistView); - for (ChecklistItem item : task.getChecklist()) { - View checklistView = inflater.inflate(R.layout.checklist_item_row, yesterdailiesList, false); - configureChecklistView(checklistView, item); - checklistView.setOnClickListener(v -> { - item.setCompleted(!item.getCompleted()); - taskRepository.scoreChecklistItem(task.getId(), item.getId()).subscribe(task1 -> {}, RxErrorHandler.handleEmptyError()); - configureChecklistView(checklistView, item); - }); - checklistContainer.addView(checklistView); - } - } - CheckBox checkBox = (CheckBox) taskView.findViewById(R.id.checkBox); - checkBox.setEnabled(false); - checkBox.setClickable(false); - yesterdailiesList.addView(taskView); - } - } - - private void configureChecklistView(View checklistView, ChecklistItem item) { - CheckBox checkbox = (CheckBox) checklistView.findViewById(R.id.checkBox); - checkbox.setChecked(item.getCompleted()); - View checkboxHolder = checklistView.findViewById(R.id.checkBoxHolder); - checkboxHolder.setBackgroundResource(R.color.gray_700); - TextView textView = (TextView) checklistView.findViewById(R.id.checkedTextView); - textView.setText(item.getText()); - } - - private void configureTaskView(View taskView, Task task) { - boolean completed = !task.isDisplayedActive(); - CheckBox checkbox = (CheckBox) taskView.findViewById(R.id.checkBox); - View checkboxHolder = taskView.findViewById(R.id.checkBoxHolder); - checkbox.setChecked(completed); - if (completed) { - checkboxHolder.setBackgroundColor(this.taskGray); - } else { - checkboxHolder.setBackgroundResource(task.getLightTaskColor()); - } - TextView textView = (TextView) taskView.findViewById(R.id.text_view); - textView.setText(task.getText()); - } - - - private View createNewTaskView(LayoutInflater inflater) { - return inflater.inflate(R.layout.dialog_yesterdaily_task, yesterdailiesList, false); - } - - public static void showDialogIfNeeded(Activity activity, String userId, UserRepository userRepository, TaskRepository taskRepository) { - if (userRepository != null && userId != null) { - Observable.just("") - .delay(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()) - .filter(aVoid -> !userRepository.isClosed()) - .flatMapMaybe(aVoid -> userRepository.getUser(userId).firstElement()) - .filter(user -> user != null && user != null && user.getNeedsCron()) - .flatMapMaybe(user -> { - final Calendar cal = Calendar.getInstance(); - cal.add(Calendar.DATE, -1); - return taskRepository.updateDailiesIsDue(cal.getTime()).firstElement(); - }) - .flatMapMaybe(user -> taskRepository.getTasks(Task.TYPE_DAILY, userId).firstElement()) - .map(tasks -> tasks.where().equalTo("isDue", true).equalTo("completed", false).equalTo("yesterDaily", true).findAll()) - .flatMapMaybe( tasks -> taskRepository.getTaskCopies(tasks).firstElement()) - .retry(1) - .subscribe(tasks -> { - if (isDisplaying) { - return; - } - if (tasks.size() > 0) { - showDialog(activity, userRepository, taskRepository, tasks); - } else { - userRepository.runCron(); - } - }, RxErrorHandler.handleEmptyError()); - } - } - - private static void showDialog(Activity activity, UserRepository userRepository, TaskRepository taskRepository, List tasks) { - YesterdailyDialog dialog = new YesterdailyDialog(activity, userRepository, taskRepository, tasks); - if (!activity.isFinishing()) { - dialog.show(); - isDisplaying = true; - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt new file mode 100644 index 000000000..cf3aeb780 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt @@ -0,0 +1,161 @@ +package com.habitrpg.android.habitica.ui.views.yesterdailies + +import android.app.Activity +import android.app.AlertDialog +import android.content.Context +import android.os.Build +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CheckBox +import android.widget.LinearLayout +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.TaskRepository +import com.habitrpg.android.habitica.data.UserRepository +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.tasks.ChecklistItem +import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.android.habitica.ui.helpers.bindColor +import com.habitrpg.android.habitica.ui.helpers.bindView +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.functions.Consumer +import java.util.* +import java.util.concurrent.TimeUnit + +class YesterdailyDialog private constructor(context: Context, private val userRepository: UserRepository, private val taskRepository: TaskRepository, private val tasks: List) : AlertDialog(context) { + + private val yesterdailiesList: LinearLayout by bindView(R.id.yesterdailies_list) + + private val taskGray: Int by bindColor(context, R.color.task_gray) + + init { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + val view = inflater.inflate(R.layout.dialog_yesterdaily, null) + this.setView(view) + this.setButton(AlertDialog.BUTTON_POSITIVE, + context.getString(R.string.start_day) + ) { _, _ -> } + + this.setOnDismissListener { runCron() } + + createTaskViews(inflater) + } + + private fun runCron() { + val completedTasks = ArrayList() + for (task in tasks) { + if (task.completed) { + completedTasks.add(task) + } + } + userRepository.runCron(completedTasks) + isDisplaying = false + } + + private fun createTaskViews(inflater: LayoutInflater) { + for (task in tasks) { + val taskView = createNewTaskView(inflater) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + taskView.clipToOutline = true + } + configureTaskView(taskView, task) + val taskContainer = taskView.findViewById(R.id.taskHolder) + taskContainer.setOnClickListener { + task.completed = !task.completed + configureTaskView(taskView, task) + } + + if (task.checklist?.size ?: 0 > 0) { + val checklistDivider = taskView.findViewById(R.id.checklistDivider) + checklistDivider.visibility = View.VISIBLE + val checklistContainer = taskView.findViewById(R.id.checklistView) + for (item in task.checklist ?: emptyList()) { + val checklistView = inflater.inflate(R.layout.checklist_item_row, yesterdailiesList, false) + configureChecklistView(checklistView, item) + checklistView.setOnClickListener { + item.completed = !item.completed + taskRepository.scoreChecklistItem(task.id ?: "", item.id).subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) + configureChecklistView(checklistView, item) + } + checklistContainer.addView(checklistView) + } + } + val checkBox = taskView.findViewById(R.id.checkBox) as CheckBox + checkBox.isEnabled = false + checkBox.isClickable = false + yesterdailiesList.addView(taskView) + } + } + + private fun configureChecklistView(checklistView: View, item: ChecklistItem) { + val checkbox = checklistView.findViewById(R.id.checkBox) as CheckBox + checkbox.isChecked = item.completed + val checkboxHolder = checklistView.findViewById(R.id.checkBoxHolder) + checkboxHolder.setBackgroundResource(R.color.gray_700) + val textView = checklistView.findViewById(R.id.checkedTextView) as TextView + textView.text = item.text + } + + private fun configureTaskView(taskView: View, task: Task) { + val completed = !task.isDisplayedActive + val checkbox = taskView.findViewById(R.id.checkBox) as CheckBox + val checkboxHolder = taskView.findViewById(R.id.checkBoxHolder) + checkbox.isChecked = completed + if (completed) { + checkboxHolder.setBackgroundColor(this.taskGray) + } else { + checkboxHolder.setBackgroundResource(task.lightTaskColor) + } + val textView = taskView.findViewById(R.id.text_view) as TextView + textView.text = task.text + } + + + private fun createNewTaskView(inflater: LayoutInflater): View { + return inflater.inflate(R.layout.dialog_yesterdaily_task, yesterdailiesList, false) + } + + companion object { + + internal var isDisplaying = false + + fun showDialogIfNeeded(activity: Activity, userId: String?, userRepository: UserRepository?, taskRepository: TaskRepository) { + if (userRepository != null && userId != null) { + Observable.just("") + .delay(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()) + .filter { !userRepository.isClosed } + .flatMapMaybe { userRepository.getUser(userId).firstElement() } + .filter { user -> user.needsCron } + .flatMapMaybe { + val cal = Calendar.getInstance() + cal.add(Calendar.DATE, -1) + taskRepository.updateDailiesIsDue(cal.time).firstElement() + } + .flatMapMaybe { taskRepository.getTasks(Task.TYPE_DAILY, userId).firstElement() } + .map { tasks -> tasks.where().equalTo("isDue", true).equalTo("completed", false).equalTo("yesterDaily", true).findAll() } + .flatMapMaybe> { tasks -> taskRepository.getTaskCopies(tasks).firstElement() } + .retry(1) + .subscribe(Consumer { tasks -> + if (isDisplaying) { + return@Consumer + } + if (tasks.isNotEmpty()) { + showDialog(activity, userRepository, taskRepository, tasks) + } else { + userRepository.runCron() + } + }, RxErrorHandler.handleEmptyError()) + } + } + + private fun showDialog(activity: Activity, userRepository: UserRepository, taskRepository: TaskRepository, tasks: List) { + val dialog = YesterdailyDialog(activity, userRepository, taskRepository, tasks) + if (!activity.isFinishing) { + dialog.show() + isDisplaying = true + } + } + } +} diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialogTests.java b/Habitica/src/test/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialogTests.java index 0b567f9c1..35036ce8c 100644 --- a/Habitica/src/test/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialogTests.java +++ b/Habitica/src/test/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialogTests.java @@ -69,23 +69,23 @@ public class YesterdailyDialogTests extends BaseTestCase { @Test public void showsDialogIfNeededAndTasks() throws Exception { when(mockTasks.size()).thenReturn(1); - YesterdailyDialog.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); + YesterdailyDialog.Companion.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); verifyNew(YesterdailyDialog.class).withArguments(any(Context.class), any(UserRepository.class), any(List.class)); } @Test public void doesntShowDialogIfAlreadyShown() throws Exception { when(mockTasks.size()).thenReturn(1); - YesterdailyDialog.isDisplaying = true; - YesterdailyDialog.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); + YesterdailyDialog.Companion.setIsDisplaying(true); + YesterdailyDialog.Companion.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); verifyNew(YesterdailyDialog.class, times(0)).withArguments(any(Context.class), any(UserRepository.class), any(List.class)); } @Test public void doesntShowDialogIfNoTasks() throws Exception { when(mockTasks.size()).thenReturn(0); - YesterdailyDialog.isDisplaying = true; - YesterdailyDialog.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); + YesterdailyDialog.Companion.setIsDisplaying(true); + YesterdailyDialog.Companion.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); verifyNew(YesterdailyDialog.class, times(0)).withArguments(any(Context.class), any(UserRepository.class), any(List.class)); } @@ -93,8 +93,8 @@ public class YesterdailyDialogTests extends BaseTestCase { public void doesntShowDialogIfNotNeeded() throws Exception { testUser.setNeedsCron(false); when(mockTasks.size()).thenReturn(1); - YesterdailyDialog.isDisplaying = true; - YesterdailyDialog.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); + YesterdailyDialog.Companion.setIsDisplaying(true); + YesterdailyDialog.Companion.showDialogIfNeeded(mockContext, "", mockUserRepository, mockTaskRepository); verifyNew(YesterdailyDialog.class, times(0)).withArguments(any(Context.class), any(UserRepository.class), any(List.class)); }