mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-13 17:51:57 +00:00
Refactor fragments to be in kotlin and not use Butterknife
This commit is contained in:
parent
e66c95bda0
commit
381b76a33a
103 changed files with 3216 additions and 3489 deletions
|
|
@ -0,0 +1,136 @@
|
|||
package com.habitrpg.android.habitica.api;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.habitrpg.android.habitica.models.ContentResult;
|
||||
import com.habitrpg.android.habitica.models.FAQArticle;
|
||||
import com.habitrpg.android.habitica.models.Skill;
|
||||
import com.habitrpg.android.habitica.models.Tag;
|
||||
import com.habitrpg.android.habitica.models.TutorialStep;
|
||||
import com.habitrpg.android.habitica.models.WorldState;
|
||||
import com.habitrpg.android.habitica.models.inventory.Customization;
|
||||
import com.habitrpg.android.habitica.models.inventory.Egg;
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment;
|
||||
import com.habitrpg.android.habitica.models.inventory.Food;
|
||||
import com.habitrpg.android.habitica.models.inventory.HatchingPotion;
|
||||
import com.habitrpg.android.habitica.models.inventory.Mount;
|
||||
import com.habitrpg.android.habitica.models.inventory.Pet;
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest;
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestCollect;
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent;
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestDropItem;
|
||||
import com.habitrpg.android.habitica.models.responses.FeedResponse;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.social.ChatMessage;
|
||||
import com.habitrpg.android.habitica.models.social.Group;
|
||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||
import com.habitrpg.android.habitica.models.tasks.TaskList;
|
||||
import com.habitrpg.android.habitica.models.user.Purchases;
|
||||
import com.habitrpg.android.habitica.models.user.User;
|
||||
import com.habitrpg.android.habitica.utils.BooleanAsIntAdapter;
|
||||
import com.habitrpg.android.habitica.utils.ChallengeDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ChallengeListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ChatMessageDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ChatMessageListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.ContentDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.CustomizationDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.DateDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.EggListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.EquipmentListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.FAQArticleListDeserilializer;
|
||||
import com.habitrpg.android.habitica.utils.FeedResponseDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.FoodListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.GroupSerialization;
|
||||
import com.habitrpg.android.habitica.utils.HatchingPotionListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.MemberSerialization;
|
||||
import com.habitrpg.android.habitica.utils.MountListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.MountMapDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.PetListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.PetMapDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.PurchasedDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.QuestCollectDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.QuestDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.QuestDropItemsListSerialization;
|
||||
import com.habitrpg.android.habitica.utils.QuestListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.SkillDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.TaskListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.TaskSerializer;
|
||||
import com.habitrpg.android.habitica.utils.TaskTagDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.TutorialStepListDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.UserDeserializer;
|
||||
import com.habitrpg.android.habitica.utils.WorldStateSerialization;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.realm.RealmList;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class GSonFactoryCreator {
|
||||
|
||||
public static GsonConverterFactory create() {
|
||||
Type taskTagClassListType = new TypeToken<RealmList<Tag>>() {}.getType();
|
||||
Type skillListType = new TypeToken<List<Skill>>() {}.getType();
|
||||
Type customizationListType = new TypeToken<RealmList<Customization>>() {}.getType();
|
||||
Type tutorialStepListType = new TypeToken<RealmList<TutorialStep>>() {}.getType();
|
||||
Type faqArticleListType = new TypeToken<RealmList<FAQArticle>>() {}.getType();
|
||||
Type itemDataListType = new TypeToken<RealmList<Equipment>>() {}.getType();
|
||||
Type eggListType = new TypeToken<RealmList<Egg>>() {}.getType();
|
||||
Type foodListType = new TypeToken<RealmList<Food>>() {}.getType();
|
||||
Type hatchingPotionListType = new TypeToken<RealmList<HatchingPotion>>() {}.getType();
|
||||
Type questContentListType = new TypeToken<RealmList<QuestContent>>() {}.getType();
|
||||
Type petMapType = new TypeToken<Map<String, Pet>>() {}.getType();
|
||||
Type mountMapType = new TypeToken<Map<String, Mount>>() {}.getType();
|
||||
Type petListType = new TypeToken<RealmList<Pet>>() {}.getType();
|
||||
Type mountListType = new TypeToken<RealmList<Mount>>() {}.getType();
|
||||
Type questCollectListType = new TypeToken<RealmList<QuestCollect>>() {}.getType();
|
||||
Type chatMessageListType = new TypeToken<RealmList<ChatMessage>>() {}.getType();
|
||||
Type challengeListType = new TypeToken<List<Challenge>>() {}.getType();
|
||||
Type challengeRealmListType = new TypeToken<RealmList<Challenge>>() {}.getType();
|
||||
Type questDropItemListType = new TypeToken<RealmList<QuestDropItem>>() {}.getType();
|
||||
|
||||
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(taskTagClassListType, new TaskTagDeserializer())
|
||||
.registerTypeAdapter(Boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(skillListType, new SkillDeserializer())
|
||||
.registerTypeAdapter(TaskList.class, new TaskListDeserializer())
|
||||
.registerTypeAdapter(Purchases.class, new PurchasedDeserializer())
|
||||
.registerTypeAdapter(customizationListType, new CustomizationDeserializer())
|
||||
.registerTypeAdapter(tutorialStepListType, new TutorialStepListDeserializer())
|
||||
.registerTypeAdapter(faqArticleListType, new FAQArticleListDeserilializer())
|
||||
.registerTypeAdapter(Group.class, new GroupSerialization())
|
||||
.registerTypeAdapter(Date.class, new DateDeserializer())
|
||||
.registerTypeAdapter(itemDataListType, new EquipmentListDeserializer())
|
||||
.registerTypeAdapter(eggListType, new EggListDeserializer())
|
||||
.registerTypeAdapter(foodListType, new FoodListDeserializer())
|
||||
.registerTypeAdapter(hatchingPotionListType, new HatchingPotionListDeserializer())
|
||||
.registerTypeAdapter(questContentListType, new QuestListDeserializer())
|
||||
.registerTypeAdapter(petListType, new PetListDeserializer())
|
||||
.registerTypeAdapter(mountListType, new MountListDeserializer())
|
||||
.registerTypeAdapter(petMapType, new PetMapDeserializer())
|
||||
.registerTypeAdapter(mountMapType, new MountMapDeserializer())
|
||||
.registerTypeAdapter(ChatMessage.class, new ChatMessageDeserializer())
|
||||
.registerTypeAdapter(Task.class, new TaskSerializer())
|
||||
.registerTypeAdapter(ContentResult.class, new ContentDeserializer())
|
||||
.registerTypeAdapter(FeedResponse.class, new FeedResponseDeserializer())
|
||||
.registerTypeAdapter(Challenge.class, new ChallengeDeserializer())
|
||||
.registerTypeAdapter(User.class, new UserDeserializer())
|
||||
.registerTypeAdapter(questCollectListType, new QuestCollectDeserializer())
|
||||
.registerTypeAdapter(chatMessageListType, new ChatMessageListDeserializer())
|
||||
.registerTypeAdapter(challengeListType, new ChallengeListDeserializer())
|
||||
.registerTypeAdapter(challengeRealmListType, new ChallengeListDeserializer())
|
||||
.registerTypeAdapter(questDropItemListType, new QuestDropItemsListSerialization())
|
||||
.registerTypeAdapter(Quest.class, new QuestDeserializer())
|
||||
.registerTypeAdapter(Member.class, new MemberSerialization())
|
||||
.registerTypeAdapter(WorldState.class, new WorldStateSerialization())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create();
|
||||
return GsonConverterFactory.create(gson);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import com.habitrpg.android.habitica.BuildConfig
|
|||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.api.ApiService
|
||||
import com.habitrpg.android.habitica.api.GSonFactoryCreator
|
||||
import com.habitrpg.android.habitica.api.HostConfig
|
||||
import com.habitrpg.android.habitica.api.Server
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
|
|
@ -686,103 +687,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
|
|||
private const val TAG = "ApiClientImpl"
|
||||
|
||||
fun createGsonFactory(): GsonConverterFactory {
|
||||
val taskTagClassListType = object : TypeToken<RealmList<Tag>>() {
|
||||
|
||||
}.type
|
||||
val skillListType = object : TypeToken<List<Skill>>() {
|
||||
|
||||
}.type
|
||||
val customizationListType = object : TypeToken<RealmList<Customization>>() {
|
||||
|
||||
}.type
|
||||
val tutorialStepListType = object : TypeToken<RealmList<TutorialStep>>() {
|
||||
|
||||
}.type
|
||||
val faqArticleListType = object : TypeToken<RealmList<FAQArticle>>() {
|
||||
|
||||
}.type
|
||||
val itemDataListType = object : TypeToken<RealmList<Equipment>>() {
|
||||
|
||||
}.type
|
||||
val eggListType = object : TypeToken<RealmList<Egg>>() {
|
||||
|
||||
}.type
|
||||
val foodListType = object : TypeToken<RealmList<Food>>() {
|
||||
|
||||
}.type
|
||||
val hatchingPotionListType = object : TypeToken<RealmList<HatchingPotion>>() {
|
||||
|
||||
}.type
|
||||
val questContentListType = object : TypeToken<RealmList<QuestContent>>() {
|
||||
|
||||
}.type
|
||||
val petMapType = object : TypeToken<Map<String, Pet>>() {
|
||||
|
||||
}.type
|
||||
val mountMapType = object : TypeToken<Map<String, Mount>>() {
|
||||
|
||||
}.type
|
||||
val petListType = object : TypeToken<RealmList<Pet>>() {
|
||||
|
||||
}.type
|
||||
val mountListType = object : TypeToken<RealmList<Mount>>() {
|
||||
|
||||
}.type
|
||||
val questCollectListType = object : TypeToken<RealmList<QuestCollect>>() {
|
||||
|
||||
}.type
|
||||
val chatMessageListType = object : TypeToken<RealmList<ChatMessage>>() {
|
||||
|
||||
}.type
|
||||
val challengeListType = object : TypeToken<List<Challenge>>() {
|
||||
|
||||
}.type
|
||||
val challengeRealmListType = object : TypeToken<RealmList<Challenge>>() {
|
||||
|
||||
}.type
|
||||
val questDropItemListType = object : TypeToken<RealmList<QuestDropItem>>() {
|
||||
|
||||
}.type
|
||||
|
||||
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
||||
val gson = GsonBuilder()
|
||||
.registerTypeAdapter(taskTagClassListType, TaskTagDeserializer())
|
||||
.registerTypeAdapter(Boolean::class.java, BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(skillListType, SkillDeserializer())
|
||||
.registerTypeAdapter(TaskList::class.java, TaskListDeserializer())
|
||||
.registerTypeAdapter(Purchases::class.java, PurchasedDeserializer())
|
||||
.registerTypeAdapter(customizationListType, CustomizationDeserializer())
|
||||
.registerTypeAdapter(tutorialStepListType, TutorialStepListDeserializer())
|
||||
.registerTypeAdapter(faqArticleListType, FAQArticleListDeserilializer())
|
||||
.registerTypeAdapter(Group::class.java, GroupSerialization())
|
||||
.registerTypeAdapter(Date::class.java, DateDeserializer())
|
||||
.registerTypeAdapter(itemDataListType, EquipmentListDeserializer())
|
||||
.registerTypeAdapter(eggListType, EggListDeserializer())
|
||||
.registerTypeAdapter(foodListType, FoodListDeserializer())
|
||||
.registerTypeAdapter(hatchingPotionListType, HatchingPotionListDeserializer())
|
||||
.registerTypeAdapter(questContentListType, QuestListDeserializer())
|
||||
.registerTypeAdapter(petListType, PetListDeserializer())
|
||||
.registerTypeAdapter(mountListType, MountListDeserializer())
|
||||
.registerTypeAdapter(petMapType, PetMapDeserializer())
|
||||
.registerTypeAdapter(mountMapType, MountMapDeserializer())
|
||||
.registerTypeAdapter(ChatMessage::class.java, ChatMessageDeserializer())
|
||||
.registerTypeAdapter(Task::class.java, TaskSerializer())
|
||||
.registerTypeAdapter(ContentResult::class.java, ContentDeserializer())
|
||||
.registerTypeAdapter(FeedResponse::class.java, FeedResponseDeserializer())
|
||||
.registerTypeAdapter(Challenge::class.java, ChallengeDeserializer())
|
||||
.registerTypeAdapter(User::class.java, UserDeserializer())
|
||||
.registerTypeAdapter(questCollectListType, QuestCollectDeserializer())
|
||||
.registerTypeAdapter(chatMessageListType, ChatMessageListDeserializer())
|
||||
.registerTypeAdapter(challengeListType, ChallengeListDeserializer())
|
||||
.registerTypeAdapter(challengeRealmListType, ChallengeListDeserializer())
|
||||
.registerTypeAdapter(questDropItemListType, QuestDropItemsListSerialization())
|
||||
.registerTypeAdapter(Quest::class.java, QuestDeserializer())
|
||||
.registerTypeAdapter(Member::class.java, MemberSerialization())
|
||||
.registerTypeAdapter(WorldState::class.java, WorldStateSerialization())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create()
|
||||
return GsonConverterFactory.create(gson)
|
||||
return GSonFactoryCreator.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.habitrpg.android.habitica.extensions
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.support.annotation.IdRes
|
||||
import android.view.View
|
||||
import com.habitrpg.android.habitica.R
|
||||
|
||||
public fun AlertDialog.Builder.setOkButton(listener: ((DialogInterface, Int) -> Unit)? = null): AlertDialog.Builder {
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@ fun View.setScaledPadding(context: Context?, left: Int, top: Int, right: Int, bo
|
|||
this.setPadding(left.dpToPx(context), top.dpToPx(context), right.dpToPx(context), bottom.dpToPx(context))
|
||||
}
|
||||
|
||||
fun <T : View> View.bindView(@IdRes res: Int) : Lazy<T> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { findViewById<T>(res) }
|
||||
}
|
||||
|
||||
var <T : View> T.backgroundCompat: Drawable?
|
||||
get() {
|
||||
return background
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
package com.habitrpg.android.habitica.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.support.annotation.ColorRes
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.View
|
||||
|
||||
fun <T : View> bindView(container: View, @IdRes res: Int) : Lazy<T> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { container.findViewById<T>(res) }
|
||||
}
|
||||
|
||||
fun <T : View> bindOptionalView(container: View?, @IdRes res: Int) : Lazy<T?> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { container?.findViewById<T>(res) }
|
||||
}
|
||||
|
||||
fun bindColor(context: Context, @ColorRes res: Int) : Lazy<Int> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { ContextCompat.getColor(context, res) }
|
||||
}
|
||||
|
|
@ -9,5 +9,7 @@ public class TaskGroupPlan extends RealmObject {
|
|||
@PrimaryKey
|
||||
String task_id;
|
||||
|
||||
public boolean approvalRequested, approvalApproved, approvalRequired;
|
||||
public boolean approvalRequested;
|
||||
public boolean approvalApproved;
|
||||
public boolean approvalRequired;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.events.BoughtGemsEvent
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand
|
||||
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.models.Avatar
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.views.CurrencyViews
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.ValueBar
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
if (challengeName != null) {
|
||||
challengeName.setText(EmojiParser.parseEmojis(challenge.name));
|
||||
}
|
||||
challengeDescription.setText(MarkdownParser.parseMarkdown(challenge.description));
|
||||
challengeDescription.setText(MarkdownParser.INSTANCE.parseMarkdown(challenge.description));
|
||||
|
||||
memberCountTextView.setText(String.valueOf(challenge.memberCount));
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ public class ChallengeDetailActivity extends BaseActivity {
|
|||
|
||||
@OnClick(R.id.btn_show_more)
|
||||
void onShowMore() {
|
||||
ChallengeDetailDialogHolder.showDialog(ChallengeDetailActivity.this,
|
||||
ChallengeDetailDialogHolder.Companion.showDialog(ChallengeDetailActivity.this,
|
||||
ChallengeDetailActivity.this.challengeRepository,
|
||||
challenge,
|
||||
challenge1 -> ChallengeDetailActivity.this.onBackPressed());
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ public class FullProfileActivity extends BaseActivity {
|
|||
|
||||
String blurbText = profile.getBlurb();
|
||||
if (blurbText != null && !blurbText.isEmpty()) {
|
||||
blurbTextView.setText(MarkdownParser.parseMarkdown(blurbText));
|
||||
blurbTextView.setText(MarkdownParser.INSTANCE.parseMarkdown(blurbText));
|
||||
}
|
||||
userIdText.setText(userId);
|
||||
copyUserIdButton.setVisibility(View.VISIBLE);
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public class GroupFormActivity extends BaseActivity {
|
|||
Intent resultIntent = new Intent();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("name", this.groupNameEditText.getText().toString());
|
||||
bundle.putString("description", MarkdownParser.parseCompiled(this.groupDescriptionEditText.getText()));
|
||||
bundle.putString("description", MarkdownParser.INSTANCE.parseCompiled(this.groupDescriptionEditText.getText()));
|
||||
bundle.putString("leader", this.groupLeader);
|
||||
resultIntent.putExtras(bundle);
|
||||
setResult(Activity.RESULT_OK, resultIntent);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class MaintenanceActivity extends BaseActivity {
|
|||
this.titleTextView.setText(data.getString("title"));
|
||||
|
||||
imageView.setImageURI(Uri.parse(data.getString("imageUrl")));
|
||||
this.descriptionTextView.setText(MarkdownParser.parseMarkdown(data.getString("description")));
|
||||
this.descriptionTextView.setText(MarkdownParser.INSTANCE.parseMarkdown(data.getString("description")));
|
||||
this.descriptionTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
isDeprecationNotice = data.getBoolean("deprecationNotice");
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public class PartyInviteActivity extends BaseActivity {
|
|||
public Fragment getItem(int position) {
|
||||
|
||||
PartyInviteFragment fragment = new PartyInviteFragment();
|
||||
fragment.isEmailInvite = position == 0;
|
||||
fragment.setEmailInvite(position == 0);
|
||||
if (fragments.size() > position) {
|
||||
fragments.set(position, fragment);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -255,9 +255,9 @@ public class SetupActivity extends BaseActivity implements ViewPager.OnPageChang
|
|||
switch (position) {
|
||||
case 1: {
|
||||
avatarSetupFragment = new AvatarSetupFragment();
|
||||
avatarSetupFragment.activity = SetupActivity.this;
|
||||
avatarSetupFragment.setActivity(SetupActivity.this);
|
||||
avatarSetupFragment.setUser(user);
|
||||
avatarSetupFragment.width = pager.getWidth();
|
||||
avatarSetupFragment.setWidth(pager.getWidth());
|
||||
fragment = avatarSetupFragment;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1087,7 +1087,7 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
|
||||
private boolean saveTask(Task task) {
|
||||
|
||||
String text = MarkdownParser.parseCompiled(taskText.getText());
|
||||
String text = MarkdownParser.INSTANCE.parseCompiled(taskText.getText());
|
||||
if (text == null || text.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1099,7 +1099,7 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
|
|||
taskRepository.executeTransaction(realm -> {
|
||||
try {
|
||||
task.setText(text);
|
||||
task.setNotes(MarkdownParser.parseCompiled(taskNotes.getText()));
|
||||
task.setNotes(MarkdownParser.INSTANCE.parseCompiled(taskNotes.getText()));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import android.widget.*
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.models.inventory.Customization
|
||||
import com.habitrpg.android.habitica.models.inventory.CustomizationSet
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import android.view.ViewGroup
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||
import com.habitrpg.android.habitica.extensions.bindOptionalView
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindOptionalView
|
||||
import com.habitrpg.android.habitica.ui.menu.HabiticaDrawerItem
|
||||
import io.reactivex.BackpressureStrategy
|
||||
import io.reactivex.Flowable
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ 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.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import android.widget.Button
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.inventory.Item
|
||||
import com.habitrpg.android.habitica.models.shops.Shop
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ 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.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.inventory.Animal
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.inventory.stable.MountDetailRecyclerFragment
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ public class ChatRecyclerViewAdapter extends RealmRecyclerViewAdapter<ChatMessag
|
|||
if (msg.getParsedText() == null) {
|
||||
messageText.setText(chatMessage.getText());
|
||||
Maybe.just(chatMessage.getText())
|
||||
.map(MarkdownParser::parseMarkdown)
|
||||
.map(MarkdownParser.INSTANCE::parseMarkdown)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(parsedText -> {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.CallSuper
|
||||
import android.support.v4.app.DialogFragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.Unbinder
|
||||
import com.habitrpg.android.habitica.HabiticaApplication
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
|
|
@ -31,7 +28,6 @@ abstract class BaseFragment : DialogFragment() {
|
|||
|
||||
var tutorialStepIdentifier: String? = null
|
||||
var tutorialText: String? = null
|
||||
var unbinder: Unbinder? = null
|
||||
protected var tutorialCanBeDeferred = true
|
||||
var tutorialTexts: MutableList<String> = ArrayList()
|
||||
|
||||
|
|
@ -66,15 +62,6 @@ abstract class BaseFragment : DialogFragment() {
|
|||
|
||||
abstract fun injectFragment(component: AppComponent)
|
||||
|
||||
@CallSuper
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
if (unbinder == null) {
|
||||
unbinder = ButterKnife.bind(this, view)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
showTutorialIfNeeded()
|
||||
|
|
@ -115,10 +102,6 @@ abstract class BaseFragment : DialogFragment() {
|
|||
if (EventBus.getDefault().isRegistered(this)) {
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
if (unbinder != null) {
|
||||
unbinder!!.unbind()
|
||||
unbinder = null
|
||||
}
|
||||
if (!compositeSubscription.isDisposed) {
|
||||
compositeSubscription.dispose()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.faq;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
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.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.models.FAQArticle;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class FAQDetailFragment extends BaseMainFragment {
|
||||
@BindView(R.id.questionTextView)
|
||||
TextView questionTextView;
|
||||
|
||||
@BindView(R.id.answerTextView)
|
||||
TextView answerTextView;
|
||||
|
||||
private FAQArticle article;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View view = inflater.inflate(R.layout.fragment_faq_detail, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
|
||||
if (this.article != null) {
|
||||
this.questionTextView.setText(this.article.getQuestion());
|
||||
this.answerTextView.setText(MarkdownParser.parseMarkdown(this.article.getAnswer()));
|
||||
}
|
||||
this.answerTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
}
|
||||
|
||||
public void setArticle(FAQArticle article) {
|
||||
this.article = article;
|
||||
if (this.questionTextView != null) {
|
||||
this.questionTextView.setText(this.article.getQuestion());
|
||||
}
|
||||
if (this.answerTextView != null) {
|
||||
this.answerTextView.setText(MarkdownParser.parseMarkdown(this.article.getAnswer()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.faq
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
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.components.AppComponent
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.FAQArticle
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
|
||||
class FAQDetailFragment : BaseMainFragment() {
|
||||
private val questionTextView: TextView? by bindView(R.id.questionTextView)
|
||||
private val answerTextView: TextView? by bindView(R.id.answerTextView)
|
||||
|
||||
private var article: FAQArticle? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_faq_detail)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
if (this.article != null) {
|
||||
this.questionTextView!!.text = this.article!!.question
|
||||
//TODO: FIX
|
||||
this.answerTextView?.text = MarkdownParser.parseMarkdown(article?.answer)
|
||||
}
|
||||
this.answerTextView!!.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {}
|
||||
|
||||
fun setArticle(article: FAQArticle) {
|
||||
this.article = article
|
||||
if (this.questionTextView != null) {
|
||||
this.questionTextView!!.text = this.article!!.question
|
||||
}
|
||||
if (this.answerTextView != null) {
|
||||
//TODO: FIX
|
||||
this.answerTextView?.text = MarkdownParser.parseMarkdown(article.answer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.faq;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.FAQRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.ui.adapter.FAQOverviewRecyclerAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class FAQOverviewFragment extends BaseMainFragment {
|
||||
@Inject
|
||||
FAQRepository faqRepository;
|
||||
|
||||
@BindView(R.id.recyclerView)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
FAQOverviewRecyclerAdapter adapter;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
adapter = new FAQOverviewRecyclerAdapter();
|
||||
adapter.getResetWalkthroughEvents().subscribe(aVoid -> this.userRepository.resetTutorial(user), RxErrorHandler.handleEmptyError());
|
||||
adapter.activity = activity;
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setItemAnimator(new SafeDefaultItemAnimator());
|
||||
this.loadArticles();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
faqRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void loadArticles() {
|
||||
if (user == null || adapter == null) {
|
||||
return;
|
||||
}
|
||||
faqRepository.getArticles().subscribe(adapter::setArticles, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String customTitle() {
|
||||
if (!isAdded()) {
|
||||
return "";
|
||||
}
|
||||
return getString(R.string.FAQ);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.faq
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.DividerItemDecoration
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.FAQRepository
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.FAQOverviewRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import io.reactivex.functions.Consumer
|
||||
import javax.inject.Inject
|
||||
|
||||
class FAQOverviewFragment : BaseMainFragment() {
|
||||
@Inject
|
||||
lateinit var faqRepository: FAQRepository
|
||||
|
||||
private val recyclerView: RecyclerView? by bindView(R.id.recyclerView)
|
||||
|
||||
internal var adapter: FAQOverviewRecyclerAdapter? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_recyclerview)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
adapter = FAQOverviewRecyclerAdapter()
|
||||
adapter?.resetWalkthroughEvents?.subscribe(Consumer { this.userRepository.resetTutorial(user) }, RxErrorHandler.handleEmptyError())
|
||||
adapter?.activity = activity
|
||||
recyclerView?.layoutManager = LinearLayoutManager(activity)
|
||||
recyclerView?.addItemDecoration(DividerItemDecoration(getActivity()!!, DividerItemDecoration.VERTICAL))
|
||||
recyclerView?.adapter = adapter
|
||||
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
this.loadArticles()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
faqRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
private fun loadArticles() {
|
||||
if (user == null || adapter == null) {
|
||||
return
|
||||
}
|
||||
faqRepository.articles.subscribe(Consumer { adapter?.setArticles(it) }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
override fun customTitle(): String {
|
||||
return if (!isAdded) {
|
||||
""
|
||||
} else getString(R.string.FAQ)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.inventory.items;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository;
|
||||
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
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.models.user.User;
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport;
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import io.realm.OrderedRealmCollection;
|
||||
|
||||
public class ItemRecyclerFragment extends BaseFragment {
|
||||
|
||||
@Inject
|
||||
InventoryRepository inventoryRepository;
|
||||
|
||||
private static final String ITEM_TYPE_KEY = "CLASS_TYPE_KEY";
|
||||
@BindView(R.id.recyclerView)
|
||||
public RecyclerViewEmptySupport recyclerView;
|
||||
@BindView(R.id.emptyView)
|
||||
public View emptyView;
|
||||
@BindView(R.id.empty_text_view)
|
||||
public TextView emptyTextView;
|
||||
@BindView(R.id.titleTextView)
|
||||
public TextView titleView;
|
||||
@BindView(R.id.footerTextView)
|
||||
public TextView footerView;
|
||||
@BindView(R.id.openMarketButton)
|
||||
public Button openMarketButton;
|
||||
public ItemRecyclerAdapter adapter;
|
||||
public String itemType;
|
||||
public String itemTypeText;
|
||||
public boolean isHatching;
|
||||
public boolean isFeeding;
|
||||
public Item hatchingItem;
|
||||
public Pet feedingPet;
|
||||
@Nullable
|
||||
public User user;
|
||||
LinearLayoutManager layoutManager = null;
|
||||
|
||||
private View view;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
view = inflater.inflate(R.layout.fragment_items, container, false);
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
|
||||
recyclerView.setEmptyView(emptyView);
|
||||
emptyTextView.setText(getString(R.string.empty_items, itemTypeText));
|
||||
|
||||
android.support.v4.app.FragmentActivity context = getActivity();
|
||||
|
||||
layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
||||
|
||||
if (layoutManager == null) {
|
||||
layoutManager = new LinearLayoutManager(context);
|
||||
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
}
|
||||
|
||||
adapter = (ItemRecyclerAdapter) recyclerView.getAdapter();
|
||||
if (adapter == null) {
|
||||
adapter = new ItemRecyclerAdapter(null, true);
|
||||
adapter.context = this.getActivity();
|
||||
adapter.isHatching = this.isHatching;
|
||||
adapter.isFeeding = this.isFeeding;
|
||||
adapter.fragment = this;
|
||||
if (this.hatchingItem != null) {
|
||||
adapter.hatchingItem = this.hatchingItem;
|
||||
}
|
||||
if (this.feedingPet != null) {
|
||||
adapter.feedingPet = this.feedingPet;
|
||||
}
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
getCompositeSubscription().add(adapter.getSellItemEvents()
|
||||
.flatMap(item -> inventoryRepository.sellItem(user, item))
|
||||
.subscribe(item -> {}, RxErrorHandler.handleEmptyError()));
|
||||
|
||||
getCompositeSubscription().add(adapter.getQuestInvitationEvents()
|
||||
.flatMap(quest -> inventoryRepository.inviteToQuest(quest))
|
||||
.subscribe(group -> {
|
||||
EventBus.getDefault().post(new OpenMenuItemCommand(NavigationDrawerFragment.SIDEBAR_PARTY));
|
||||
}, RxErrorHandler.handleEmptyError()));
|
||||
}
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
|
||||
recyclerView.setItemAnimator(new SafeDefaultItemAnimator());
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "");
|
||||
}
|
||||
|
||||
if (this.isHatching) {
|
||||
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
this.titleView.setText(getString(R.string.hatch_with, this.hatchingItem.getText()));
|
||||
this.titleView.setVisibility(View.VISIBLE);
|
||||
this.footerView.setText(getString(R.string.hatching_market_info));
|
||||
this.footerView.setVisibility(View.VISIBLE);
|
||||
this.openMarketButton.setVisibility(View.VISIBLE);
|
||||
} else if (this.isFeeding) {
|
||||
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
this.titleView.setText(getString(R.string.dialog_feeding, this.feedingPet.getColorText(), this.feedingPet.getAnimalText()));
|
||||
this.titleView.setVisibility(View.VISIBLE);
|
||||
this.footerView.setText(getString(R.string.feeding_market_info));
|
||||
this.footerView.setVisibility(View.VISIBLE);
|
||||
this.openMarketButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
this.titleView.setVisibility(View.GONE);
|
||||
this.footerView.setVisibility(View.GONE);
|
||||
this.openMarketButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
inventoryRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
this.loadItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if ((this.isHatching || this.isFeeding) && getDialog().getWindow() != null) {
|
||||
android.view.WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
|
||||
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
params.verticalMargin = 60;
|
||||
getDialog().getWindow().setAttributes(params);
|
||||
}
|
||||
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(ITEM_TYPE_KEY, this.itemType);
|
||||
}
|
||||
|
||||
private void loadItems() {
|
||||
Class<? extends Item> itemClass = null;
|
||||
switch (itemType) {
|
||||
case "eggs":
|
||||
itemClass = Egg.class;
|
||||
break;
|
||||
case "hatchingPotions":
|
||||
itemClass = HatchingPotion.class;
|
||||
break;
|
||||
case "food":
|
||||
itemClass = Food.class;
|
||||
break;
|
||||
case "quests":
|
||||
itemClass = QuestContent.class;
|
||||
break;
|
||||
case "special":
|
||||
itemClass = SpecialItem.class;
|
||||
break;
|
||||
}
|
||||
inventoryRepository.getOwnedItems(itemClass, user).firstElement().subscribe(items -> {
|
||||
if (items.size() > 0) {
|
||||
adapter.updateData((OrderedRealmCollection<Item>) items);
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError());
|
||||
|
||||
getCompositeSubscription().add(inventoryRepository.getOwnedPets().subscribe(adapter::setOwnedPets, RxErrorHandler.handleEmptyError()));
|
||||
}
|
||||
|
||||
@OnClick(R.id.openMarketButton)
|
||||
public void onOpenMarketClicked() {
|
||||
dismiss();
|
||||
openMarket();
|
||||
}
|
||||
|
||||
@OnClick(R.id.openEmptyMarketButton)
|
||||
public void onEmptyOpenMarketButtonClicked() {
|
||||
openMarket();
|
||||
}
|
||||
|
||||
private void openMarket() {
|
||||
EventBus.getDefault().post(new OpenMenuItemCommand(NavigationDrawerFragment.SIDEBAR_SHOPS));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.inventory.items
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.DividerItemDecoration
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand
|
||||
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.inventory.*
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.realm.OrderedRealmCollection
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import javax.inject.Inject
|
||||
|
||||
class ItemRecyclerFragment : BaseFragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView)
|
||||
val emptyView: View? by bindView(R.id.emptyView)
|
||||
val emptyTextView: TextView? by bindView(R.id.empty_text_view)
|
||||
val titleView: TextView? by bindView(R.id.titleTextView)
|
||||
val footerView: TextView? by bindView(R.id.footerTextView)
|
||||
val openMarketButton: Button? by bindView(R.id.openMarketButton)
|
||||
val openEmptyMarketButton: Button? by bindView(R.id.openEmptyMarketButton)
|
||||
var adapter: ItemRecyclerAdapter? = null
|
||||
var itemType: String? = null
|
||||
var itemTypeText: String? = null
|
||||
var isHatching: Boolean = false
|
||||
var isFeeding: Boolean = false
|
||||
var hatchingItem: Item? = null
|
||||
var feedingPet: Pet? = null
|
||||
var user: User? = null
|
||||
internal var layoutManager: LinearLayoutManager? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_items)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
inventoryRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
recyclerView?.setEmptyView(emptyView)
|
||||
emptyTextView?.text = getString(R.string.empty_items, itemTypeText)
|
||||
|
||||
val context = activity
|
||||
|
||||
layoutManager = recyclerView?.layoutManager as LinearLayoutManager?
|
||||
|
||||
if (layoutManager == null) {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
|
||||
recyclerView?.layoutManager = layoutManager
|
||||
}
|
||||
|
||||
adapter = recyclerView?.adapter as ItemRecyclerAdapter?
|
||||
if (adapter == null) {
|
||||
adapter = ItemRecyclerAdapter(null, true)
|
||||
adapter?.context = this.activity
|
||||
adapter?.isHatching = this.isHatching
|
||||
adapter?.isFeeding = this.isFeeding
|
||||
adapter?.fragment = this
|
||||
if (this.hatchingItem != null) {
|
||||
adapter?.hatchingItem = this.hatchingItem
|
||||
}
|
||||
if (this.feedingPet != null) {
|
||||
adapter?.feedingPet = this.feedingPet
|
||||
}
|
||||
recyclerView?.adapter = adapter
|
||||
|
||||
adapter?.notNull {
|
||||
compositeSubscription.add(it.sellItemEvents
|
||||
.flatMap { item -> inventoryRepository.sellItem(user, item) }
|
||||
.subscribe(Consumer { }, RxErrorHandler.handleEmptyError()))
|
||||
|
||||
compositeSubscription.add(it.questInvitationEvents
|
||||
.flatMap { quest -> inventoryRepository.inviteToQuest(quest) }
|
||||
.subscribe(Consumer { EventBus.getDefault().post(OpenMenuItemCommand(NavigationDrawerFragment.SIDEBAR_PARTY)) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
}
|
||||
activity.notNull {
|
||||
recyclerView?.addItemDecoration(DividerItemDecoration(it, DividerItemDecoration.VERTICAL))
|
||||
}
|
||||
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "")
|
||||
}
|
||||
|
||||
if (this.isHatching) {
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
this.titleView?.text = getString(R.string.hatch_with, this.hatchingItem?.text)
|
||||
this.titleView?.visibility = View.VISIBLE
|
||||
this.footerView?.text = getString(R.string.hatching_market_info)
|
||||
this.footerView?.visibility = View.VISIBLE
|
||||
this.openMarketButton?.visibility = View.VISIBLE
|
||||
} else if (this.isFeeding) {
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
this.titleView?.text = getString(R.string.dialog_feeding, this.feedingPet?.colorText, this.feedingPet?.animalText)
|
||||
this.titleView?.visibility = View.VISIBLE
|
||||
this.footerView?.text = getString(R.string.feeding_market_info)
|
||||
this.footerView?.visibility = View.VISIBLE
|
||||
this.openMarketButton?.visibility = View.VISIBLE
|
||||
} else {
|
||||
this.titleView?.visibility = View.GONE
|
||||
this.footerView?.visibility = View.GONE
|
||||
this.openMarketButton?.visibility = View.GONE
|
||||
}
|
||||
|
||||
openMarketButton?.setOnClickListener {
|
||||
dismiss()
|
||||
openMarket()
|
||||
}
|
||||
|
||||
openEmptyMarketButton?.setOnClickListener { openMarket() }
|
||||
|
||||
this.loadItems()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
if ((this.isHatching || this.isFeeding) && dialog.window != null) {
|
||||
val params = dialog.window?.attributes
|
||||
params?.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
params?.verticalMargin = 60f
|
||||
dialog.window?.attributes = params
|
||||
}
|
||||
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putString(ITEM_TYPE_KEY, this.itemType)
|
||||
}
|
||||
|
||||
private fun loadItems() {
|
||||
var itemClass: Class<out Item>? = null
|
||||
when (itemType) {
|
||||
"eggs" -> itemClass = Egg::class.java
|
||||
"hatchingPotions" -> itemClass = HatchingPotion::class.java
|
||||
"food" -> itemClass = Food::class.java
|
||||
"quests" -> itemClass = QuestContent::class.java
|
||||
"special" -> itemClass = SpecialItem::class.java
|
||||
}
|
||||
inventoryRepository.getOwnedItems(itemClass, user).firstElement().subscribe(Consumer { items ->
|
||||
if (items.size > 0) {
|
||||
adapter?.updateData(items as OrderedRealmCollection<Item>)
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
|
||||
compositeSubscription.add(inventoryRepository?.ownedPets.subscribe(Consumer { adapter?.setOwnedPets(it) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
|
||||
private fun openMarket() {
|
||||
EventBus.getDefault().post(OpenMenuItemCommand(NavigationDrawerFragment.SIDEBAR_SHOPS))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -53,29 +53,29 @@ public class ItemsFragment extends BaseMainFragment {
|
|||
|
||||
switch (position) {
|
||||
case 0: {
|
||||
fragment.itemType = "eggs";
|
||||
fragment.setItemType("eggs");
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
fragment.itemType = "hatchingPotions";
|
||||
fragment.setItemType("hatchingPotions");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
fragment.itemType = "food";
|
||||
fragment.setItemType("food");
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
fragment.itemType = "quests";
|
||||
fragment.setItemType("quests");
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
fragment.itemType = "special";
|
||||
fragment.setItemType("special");
|
||||
}
|
||||
}
|
||||
fragment.isHatching = false;
|
||||
fragment.isFeeding = false;
|
||||
fragment.itemTypeText = this.getPageTitle(position).toString();
|
||||
fragment.user = ItemsFragment.this.user;
|
||||
fragment.setHatching(false);
|
||||
fragment.setFeeding(false);
|
||||
fragment.setItemTypeText(this.getPageTitle(position).toString());
|
||||
fragment.setUser(ItemsFragment.this.user);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
|
@ -116,14 +116,14 @@ public class ItemsFragment extends BaseMainFragment {
|
|||
if (event.usingEgg == null || event.usingHatchingPotion == null) {
|
||||
ItemRecyclerFragment fragment = new ItemRecyclerFragment();
|
||||
if (event.usingEgg != null) {
|
||||
fragment.itemType = "hatchingPotions";
|
||||
fragment.hatchingItem = event.usingEgg;
|
||||
fragment.setItemType("hatchingPotions");
|
||||
fragment.setHatchingItem(event.usingEgg);
|
||||
} else {
|
||||
fragment.itemType = "eggs";
|
||||
fragment.hatchingItem = event.usingHatchingPotion;
|
||||
fragment.setItemType("eggs");
|
||||
fragment.setHatchingItem(event.usingHatchingPotion);
|
||||
}
|
||||
fragment.isHatching = true;
|
||||
fragment.isFeeding = false;
|
||||
fragment.setHatching(true);
|
||||
fragment.setFeeding(false);
|
||||
fragment.show(getFragmentManager(), "hatchingDialog");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,16 +49,16 @@ public class StableFragment extends BaseMainFragment {
|
|||
|
||||
switch (position) {
|
||||
case 0: {
|
||||
fragment.itemType = "pets";
|
||||
fragment.setItemType("pets");
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
fragment.itemType = "mounts";
|
||||
fragment.setItemType("mounts");
|
||||
break;
|
||||
}
|
||||
}
|
||||
fragment.user = StableFragment.this.user;
|
||||
fragment.itemTypeText = this.getPageTitle(position).toString();
|
||||
fragment.setUser(StableFragment.this.user);
|
||||
fragment.setItemTypeText(this.getPageTitle(position).toString());
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,188 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.inventory.stable;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
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.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.models.inventory.Animal;
|
||||
import com.habitrpg.android.habitica.models.inventory.Mount;
|
||||
import com.habitrpg.android.habitica.models.inventory.Pet;
|
||||
import com.habitrpg.android.habitica.models.user.User;
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration;
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport;
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
|
||||
public class StableRecyclerFragment extends BaseFragment {
|
||||
private static final String ITEM_TYPE_KEY = "CLASS_TYPE_KEY";
|
||||
|
||||
@Inject
|
||||
InventoryRepository inventoryRepository;
|
||||
|
||||
@BindView(R.id.recyclerView)
|
||||
public RecyclerViewEmptySupport recyclerView;
|
||||
@BindView(R.id.emptyView)
|
||||
public TextView emptyView;
|
||||
public StableRecyclerAdapter adapter;
|
||||
public String itemType;
|
||||
public String itemTypeText;
|
||||
public User user;
|
||||
GridLayoutManager layoutManager = null;
|
||||
|
||||
private View view;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
|
||||
recyclerView.setEmptyView(emptyView);
|
||||
emptyView.setText(getString(R.string.empty_items, itemTypeText));
|
||||
|
||||
layoutManager = new GridLayoutManager(getActivity(), 2);
|
||||
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||
@Override
|
||||
public int getSpanSize(int position) {
|
||||
if (adapter.getItemViewType(position) == 0) {
|
||||
return layoutManager.getSpanCount();
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.addItemDecoration(new MarginDecoration(getActivity()));
|
||||
|
||||
|
||||
adapter = (StableRecyclerAdapter) recyclerView.getAdapter();
|
||||
if (adapter == null) {
|
||||
adapter = new StableRecyclerAdapter();
|
||||
adapter.setActivity((MainActivity) this.getActivity());
|
||||
adapter.setItemType(this.itemType);
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setItemAnimator(new SafeDefaultItemAnimator());
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "");
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
inventoryRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
this.loadItems();
|
||||
final View finalView = view;
|
||||
finalView.post(() -> setGridSpanCount(finalView.getWidth()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(ITEM_TYPE_KEY, this.itemType);
|
||||
}
|
||||
|
||||
|
||||
private void setGridSpanCount(int width) {
|
||||
int spanCount = 0;
|
||||
if (getContext() != null && getContext().getResources() != null) {
|
||||
float itemWidth;
|
||||
itemWidth = getContext().getResources().getDimension(R.dimen.pet_width);
|
||||
|
||||
spanCount = (int) (width / itemWidth);
|
||||
}
|
||||
if (spanCount == 0) {
|
||||
spanCount = 1;
|
||||
}
|
||||
layoutManager.setSpanCount(spanCount);
|
||||
}
|
||||
|
||||
private void loadItems() {
|
||||
Flowable<? extends Animal> observable;
|
||||
|
||||
if ("pets".equals(itemType)) {
|
||||
observable = inventoryRepository.getPets().firstElement().toFlowable().flatMap(Flowable::fromIterable);
|
||||
} else {
|
||||
observable = inventoryRepository.getMounts().firstElement().toFlowable().flatMap(Flowable::fromIterable);
|
||||
}
|
||||
|
||||
observable.toList().flatMap(unsortedAnimals -> {
|
||||
List<Object> items = new ArrayList<>();
|
||||
if (unsortedAnimals.size() == 0) {
|
||||
return Single.just(items);
|
||||
}
|
||||
String lastSectionTitle = "";
|
||||
|
||||
Animal lastAnimal = unsortedAnimals.get(0);
|
||||
for (Animal animal : unsortedAnimals) {
|
||||
if (!animal.getAnimal().equals(lastAnimal.getAnimal()) || animal == unsortedAnimals.get(unsortedAnimals.size()-1)) {
|
||||
if (!((lastAnimal.getAnimalGroup().equals("premiumPets") || lastAnimal.getAnimalGroup().equals("specialPets")
|
||||
|| lastAnimal.getAnimalGroup().equals("specialMounts") || lastAnimal.getAnimalGroup().equals("premiumMounts"))
|
||||
&& lastAnimal.getNumberOwned() == 0)) {
|
||||
items.add(lastAnimal);
|
||||
}
|
||||
lastAnimal = animal;
|
||||
}
|
||||
if (!animal.getAnimalGroup().equals(lastSectionTitle)) {
|
||||
if (items.size() > 0 && items.get(items.size() - 1).getClass().equals(String.class)) {
|
||||
items.remove(items.size() - 1);
|
||||
}
|
||||
items.add(animal.getAnimalGroup());
|
||||
lastSectionTitle = animal.getAnimalGroup();
|
||||
}
|
||||
if (user != null && user.getItems() != null) {
|
||||
switch (itemType) {
|
||||
case "pets":
|
||||
Pet pet = (Pet) animal;
|
||||
if (pet.getTrained() > 0) {
|
||||
lastAnimal.setNumberOwned(lastAnimal.getNumberOwned() + 1);
|
||||
}
|
||||
break;
|
||||
case "mounts":
|
||||
Mount mount = (Mount) animal;
|
||||
if (mount.getOwned()) {
|
||||
lastAnimal.setNumberOwned(lastAnimal.getNumberOwned() + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Single.just(items);
|
||||
}).subscribe(items -> adapter.setItemList(items), RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.inventory.stable
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.GridLayoutManager
|
||||
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.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Animal
|
||||
import com.habitrpg.android.habitica.models.inventory.Mount
|
||||
import com.habitrpg.android.habitica.models.inventory.Pet
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.adapter.inventory.StableRecyclerAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.*
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.functions.Consumer
|
||||
|
||||
class StableRecyclerFragment : BaseFragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
|
||||
private val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView)
|
||||
private val emptyView: TextView? by bindView(R.id.emptyView)
|
||||
var adapter: StableRecyclerAdapter? = null
|
||||
var itemType: String? = null
|
||||
var itemTypeText: String? = null
|
||||
var user: User? = null
|
||||
internal var layoutManager: GridLayoutManager? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "")
|
||||
}
|
||||
|
||||
return container?.inflate(R.layout.fragment_recyclerview)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
inventoryRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
recyclerView?.setEmptyView(emptyView)
|
||||
emptyView?.text = getString(R.string.empty_items, itemTypeText)
|
||||
|
||||
layoutManager = GridLayoutManager(activity, 2)
|
||||
layoutManager?.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
return if (adapter?.getItemViewType(position) == 0) {
|
||||
layoutManager?.spanCount ?: 1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
recyclerView?.layoutManager = layoutManager
|
||||
activity.notNull {
|
||||
recyclerView?.addItemDecoration(MarginDecoration(it))
|
||||
}
|
||||
|
||||
|
||||
adapter = recyclerView?.adapter as StableRecyclerAdapter
|
||||
if (adapter == null) {
|
||||
adapter = StableRecyclerAdapter()
|
||||
adapter?.activity = this.activity as MainActivity?
|
||||
adapter?.itemType = this.itemType
|
||||
recyclerView?.adapter = adapter
|
||||
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
}
|
||||
|
||||
this.loadItems()
|
||||
view.post { setGridSpanCount(view.width) }
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putString(ITEM_TYPE_KEY, this.itemType)
|
||||
}
|
||||
|
||||
|
||||
private fun setGridSpanCount(width: Int) {
|
||||
var spanCount = 0
|
||||
if (context != null && context?.resources != null) {
|
||||
val itemWidth: Float = context?.resources?.getDimension(R.dimen.pet_width) ?: 0.toFloat()
|
||||
|
||||
spanCount = (width / itemWidth).toInt()
|
||||
}
|
||||
if (spanCount == 0) {
|
||||
spanCount = 1
|
||||
}
|
||||
layoutManager?.spanCount = spanCount
|
||||
}
|
||||
|
||||
private fun loadItems() {
|
||||
val observable: Flowable<out Animal> = if ("pets" == itemType) {
|
||||
inventoryRepository.pets.firstElement().toFlowable().flatMap { Flowable.fromIterable(it) }
|
||||
} else {
|
||||
inventoryRepository.mounts.firstElement().toFlowable().flatMap { Flowable.fromIterable(it) }
|
||||
}
|
||||
|
||||
observable.toList().flatMap { unsortedAnimals ->
|
||||
val items = ArrayList<Any>()
|
||||
if (unsortedAnimals.size == 0) {
|
||||
return@flatMap Single.just<List<Any>>(items)
|
||||
}
|
||||
var lastSectionTitle = ""
|
||||
|
||||
var lastAnimal: Animal = unsortedAnimals[0]
|
||||
for (animal in unsortedAnimals) {
|
||||
if (animal.animal != lastAnimal.animal || animal === unsortedAnimals[unsortedAnimals.size - 1]) {
|
||||
if (!((lastAnimal.animalGroup == "premiumPets" || lastAnimal.animalGroup == "specialPets"
|
||||
|| lastAnimal.animalGroup == "specialMounts" || lastAnimal.animalGroup == "premiumMounts") && lastAnimal.numberOwned == 0)) {
|
||||
items.add(lastAnimal)
|
||||
}
|
||||
lastAnimal = animal
|
||||
}
|
||||
if (animal.animalGroup != lastSectionTitle) {
|
||||
if (items.size > 0 && items[items.size - 1].javaClass == String::class.java) {
|
||||
items.removeAt(items.size - 1)
|
||||
}
|
||||
items.add(animal.animalGroup)
|
||||
lastSectionTitle = animal.animalGroup
|
||||
}
|
||||
if (user != null && user?.items != null) {
|
||||
when (itemType) {
|
||||
"pets" -> {
|
||||
val pet = animal as Pet
|
||||
if (pet.trained > 0) {
|
||||
lastAnimal.numberOwned = lastAnimal.numberOwned + 1
|
||||
}
|
||||
}
|
||||
"mounts" -> {
|
||||
val mount = animal as Mount
|
||||
if (mount.owned) {
|
||||
lastAnimal.numberOwned = lastAnimal.numberOwned + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Single.just<List<Any>>(items)
|
||||
}.subscribe(Consumer { items -> adapter?.setItemList(items) }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
||||
}
|
||||
}
|
||||
|
|
@ -188,9 +188,11 @@ class AuthenticationPreferenceFragment: BasePreferencesFragment() {
|
|||
}
|
||||
|
||||
private fun showSubscriptionStatusDialog() {
|
||||
val view = SubscriptionDetailsView(context)
|
||||
view.setPlan(user?.purchased?.plan)
|
||||
context.notNull { context ->
|
||||
val view = SubscriptionDetailsView(context)
|
||||
user?.purchased?.plan?.notNull {
|
||||
view.setPlan(it)
|
||||
}
|
||||
val dialog = AlertDialog.Builder(context)
|
||||
.setView(view)
|
||||
.setTitle(R.string.subscription_status)
|
||||
|
|
|
|||
|
|
@ -1,269 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.ApiClient;
|
||||
import com.habitrpg.android.habitica.data.SetupCustomizationRepository;
|
||||
import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
|
||||
import com.habitrpg.android.habitica.models.SetupCustomization;
|
||||
import com.habitrpg.android.habitica.models.user.User;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView;
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.CustomizationSetupAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.views.setup.AvatarCategoryView;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class AvatarSetupFragment extends BaseFragment {
|
||||
|
||||
public SetupActivity activity;
|
||||
public int width;
|
||||
View view;
|
||||
@BindView(R.id.avatarView)
|
||||
AvatarView avatarView;
|
||||
@BindView(R.id.customization_list)
|
||||
RecyclerView customizationList;
|
||||
@BindView(R.id.subcategory_tabs)
|
||||
TabLayout subCategoryTabs;
|
||||
@BindView(R.id.body_button)
|
||||
AvatarCategoryView bodyButton;
|
||||
@BindView(R.id.skin_button)
|
||||
AvatarCategoryView skinButton;
|
||||
@BindView(R.id.hair_button)
|
||||
AvatarCategoryView hairButton;
|
||||
@BindView(R.id.extras_button)
|
||||
AvatarCategoryView extrasButton;
|
||||
@BindView(R.id.caret_view)
|
||||
ImageView caretView;
|
||||
@BindView(R.id.speech_bubble)
|
||||
SpeechBubbleView speechBubbleView;
|
||||
|
||||
CustomizationSetupAdapter adapter;
|
||||
LinearLayoutManager layoutManager;
|
||||
@Inject
|
||||
SetupCustomizationRepository customizationRepository;
|
||||
@Inject
|
||||
ApiClient apiClient;
|
||||
|
||||
private User user;
|
||||
private List<String> subcategories;
|
||||
private AvatarCategoryView activeButton;
|
||||
private String activeCategory;
|
||||
private String activeSubCategory;
|
||||
private Random random;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
view = inflater.inflate(R.layout.fragment_setup_avatar, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
this.adapter = new CustomizationSetupAdapter();
|
||||
if (this.user != null) {
|
||||
this.adapter.userSize = this.user.getPreferences().getSize();
|
||||
} else {
|
||||
this.adapter.userSize = "slim";
|
||||
}
|
||||
this.adapter.user = this.user;
|
||||
this.layoutManager = new LinearLayoutManager(activity);
|
||||
this.layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
this.customizationList.setLayoutManager(this.layoutManager);
|
||||
|
||||
this.customizationList.setAdapter(this.adapter);
|
||||
|
||||
this.subCategoryTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
int position = tab.getPosition();
|
||||
if (subcategories != null && position < subcategories.size()) {
|
||||
activeSubCategory = subcategories.get(position);
|
||||
}
|
||||
loadCustomizations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
this.selectedBodyCategory();
|
||||
|
||||
this.random = new Random();
|
||||
|
||||
if (this.user != null) {
|
||||
this.updateAvatar();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if (isVisibleToUser && getContext() != null) {
|
||||
speechBubbleView.animateText(getContext().getString(R.string.avatar_setup_description));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void loadCustomizations() {
|
||||
if (this.user == null || this.adapter == null || this.activeCategory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.adapter.setCustomizationList(customizationRepository.getCustomizations(activeCategory, activeSubCategory, user));
|
||||
}
|
||||
|
||||
public void setUser(@Nullable User user) {
|
||||
this.user = user;
|
||||
if (avatarView != null) {
|
||||
updateAvatar();
|
||||
}
|
||||
if (this.adapter != null) {
|
||||
this.adapter.user = user;
|
||||
this.adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAvatar() {
|
||||
avatarView.setAvatar(user);
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.body_button)
|
||||
protected void selectedBodyCategory() {
|
||||
activateButton(bodyButton);
|
||||
this.activeCategory = "body";
|
||||
this.subCategoryTabs.removeAllTabs();
|
||||
this.subcategories = Arrays.asList("size", "shirt");
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_size));
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_shirt));
|
||||
loadCustomizations();
|
||||
}
|
||||
|
||||
@OnClick(R.id.skin_button)
|
||||
protected void selectedSkinCategory() {
|
||||
activateButton(skinButton);
|
||||
this.activeCategory = "skin";
|
||||
this.subCategoryTabs.removeAllTabs();
|
||||
this.subcategories = Collections.singletonList("color");
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_skin_color));
|
||||
loadCustomizations();
|
||||
}
|
||||
|
||||
@OnClick(R.id.hair_button)
|
||||
protected void selectedHairCategory() {
|
||||
activateButton(hairButton);
|
||||
this.activeCategory = "hair";
|
||||
this.subCategoryTabs.removeAllTabs();
|
||||
this.subcategories = Arrays.asList("bangs", "color", "ponytail");
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_hair_bangs));
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_hair_color));
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_hair_ponytail));
|
||||
loadCustomizations();
|
||||
}
|
||||
|
||||
@OnClick(R.id.extras_button)
|
||||
protected void selectedExtrasCategory() {
|
||||
activateButton(extrasButton);
|
||||
this.activeCategory = "extras";
|
||||
this.subCategoryTabs.removeAllTabs();
|
||||
this.subcategories = Arrays.asList("glasses", "flower", "wheelchair");
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_glasses));
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_flower));
|
||||
this.subCategoryTabs.addTab(subCategoryTabs.newTab().setText(R.string.avatar_wheelchair));
|
||||
loadCustomizations();
|
||||
}
|
||||
|
||||
@OnClick(R.id.randomize_button)
|
||||
protected void randomizeCharacter() {
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
UpdateUserCommand command = new UpdateUserCommand();
|
||||
Map<String, Object> updateData = new HashMap<>();
|
||||
updateData.put("preferences.size", chooseRandomKey(customizationRepository.getCustomizations("body", "size", user), false));
|
||||
updateData.put("preferences.shirt", chooseRandomKey(customizationRepository.getCustomizations("body", "shirt", user), false));
|
||||
updateData.put("preferences.skin", chooseRandomKey(customizationRepository.getCustomizations("skin", "color", user), false));
|
||||
updateData.put("preferences.hair.color", chooseRandomKey(customizationRepository.getCustomizations("hair", "color", user), false));
|
||||
updateData.put("preferences.hair.base", chooseRandomKey(customizationRepository.getCustomizations("hair", "ponytail", user), false));
|
||||
updateData.put("preferences.hair.bangs", chooseRandomKey(customizationRepository.getCustomizations("hair", "bangs", user), false));
|
||||
updateData.put("preferences.hair.flower", chooseRandomKey(customizationRepository.getCustomizations("extras", "flower", user), true));
|
||||
updateData.put("preferences.chair", chooseRandomKey(customizationRepository.getCustomizations("extras", "wheelchair", user), true));
|
||||
command.updateData = updateData;
|
||||
|
||||
EventBus.getDefault().post(command);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String chooseRandomKey(List<SetupCustomization> customizations, boolean weighFirstOption) {
|
||||
if (customizations.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (weighFirstOption) {
|
||||
if (random.nextInt(10) > 3) {
|
||||
return customizations.get(0).getKey();
|
||||
}
|
||||
}
|
||||
return customizations.get(random.nextInt(customizations.size())).getKey();
|
||||
}
|
||||
|
||||
private void activateButton(AvatarCategoryView button) {
|
||||
if (this.activeButton != null) {
|
||||
this.activeButton.setActive(false);
|
||||
}
|
||||
this.activeButton = button;
|
||||
this.activeButton.setActive(true);
|
||||
int[] location = new int[2];
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)this.caretView.getLayoutParams();
|
||||
this.activeButton.getLocationOnScreen(location);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
Resources r = getResources();
|
||||
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, r.getDisplayMetrics());
|
||||
params.setMarginStart(location[0]+px);
|
||||
this.caretView.setLayoutParams(params);
|
||||
} else {
|
||||
caretView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.design.widget.TabLayout
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import butterknife.OnClick
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.SetupCustomizationRepository
|
||||
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.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.CustomizationSetupAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import com.habitrpg.android.habitica.ui.views.setup.AvatarCategoryView
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class AvatarSetupFragment : BaseFragment() {
|
||||
|
||||
@Inject
|
||||
lateinit var customizationRepository: SetupCustomizationRepository
|
||||
@Inject
|
||||
lateinit var apiClient: ApiClient
|
||||
|
||||
var activity: SetupActivity? = null
|
||||
var width: Int = 0
|
||||
private val avatarView: AvatarView? by bindView(R.id.avatarView)
|
||||
private val customizationList: RecyclerView? by bindView(R.id.customization_list)
|
||||
private val subCategoryTabs: TabLayout? by bindView(R.id.subcategory_tabs)
|
||||
private val bodyButton: AvatarCategoryView? by bindView(R.id.body_button)
|
||||
private val skinButton: AvatarCategoryView? by bindView(R.id.skin_button)
|
||||
private val hairButton: AvatarCategoryView? by bindView(R.id.hair_button)
|
||||
private val extrasButton: AvatarCategoryView? by bindView(R.id.extras_button)
|
||||
private val caretView: ImageView? by bindView(R.id.caret_view)
|
||||
private val speechBubbleView: SpeechBubbleView? by bindView(R.id.speech_bubble)
|
||||
private val randomizeButton: Button? by bindView(R.id.randomize_button)
|
||||
|
||||
internal var adapter: CustomizationSetupAdapter? = null
|
||||
internal var layoutManager: LinearLayoutManager = LinearLayoutManager(activity)
|
||||
|
||||
private var user: User? = null
|
||||
private var subcategories: List<String> = emptyList()
|
||||
private var activeButton: AvatarCategoryView? = null
|
||||
private var activeCategory: String? = null
|
||||
private var activeSubCategory: String? = null
|
||||
private var random = Random()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_setup_avatar)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
this.adapter = CustomizationSetupAdapter()
|
||||
this.adapter?.userSize = this.user?.preferences?.size ?: "slim"
|
||||
|
||||
this.adapter?.user = this.user
|
||||
this.layoutManager = LinearLayoutManager(activity)
|
||||
this.layoutManager.orientation = LinearLayoutManager.HORIZONTAL
|
||||
this.customizationList?.layoutManager = this.layoutManager
|
||||
|
||||
this.customizationList?.adapter = this.adapter
|
||||
|
||||
this.subCategoryTabs?.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
val position = tab.position
|
||||
if (position < subcategories.size) {
|
||||
activeSubCategory = subcategories[position]
|
||||
}
|
||||
loadCustomizations()
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab) {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
bodyButton?.setOnClickListener { selectedBodyCategory() }
|
||||
skinButton?.setOnClickListener { selectedSkinCategory() }
|
||||
hairButton?.setOnClickListener { selectedHairCategory() }
|
||||
extrasButton?.setOnClickListener { selectedExtrasCategory() }
|
||||
randomizeButton?.setOnClickListener { randomizeCharacter() }
|
||||
|
||||
this.selectedBodyCategory()
|
||||
|
||||
if (this.user != null) {
|
||||
this.updateAvatar()
|
||||
}
|
||||
}
|
||||
|
||||
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
|
||||
super.setUserVisibleHint(isVisibleToUser)
|
||||
if (isVisibleToUser && context != null) {
|
||||
speechBubbleView?.animateText(context?.getString(R.string.avatar_setup_description))
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
private fun loadCustomizations() {
|
||||
if (this.user == null || this.adapter == null || this.activeCategory == null) {
|
||||
return
|
||||
}
|
||||
|
||||
this.adapter?.setCustomizationList(customizationRepository.getCustomizations(activeCategory, activeSubCategory, user))
|
||||
}
|
||||
|
||||
fun setUser(user: User?) {
|
||||
this.user = user
|
||||
if (avatarView != null) {
|
||||
updateAvatar()
|
||||
}
|
||||
if (this.adapter != null) {
|
||||
this.adapter?.user = user
|
||||
this.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAvatar() {
|
||||
user.notNull {
|
||||
avatarView?.setAvatar(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun selectedBodyCategory() {
|
||||
activateButton(bodyButton)
|
||||
this.activeCategory = "body"
|
||||
this.subCategoryTabs?.removeAllTabs()
|
||||
this.subcategories = Arrays.asList("size", "shirt")
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_size).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_shirt).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
loadCustomizations()
|
||||
}
|
||||
|
||||
fun selectedSkinCategory() {
|
||||
activateButton(skinButton)
|
||||
this.activeCategory = "skin"
|
||||
this.subCategoryTabs?.removeAllTabs()
|
||||
this.subcategories = listOf("color")
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_skin_color).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
loadCustomizations()
|
||||
}
|
||||
|
||||
fun selectedHairCategory() {
|
||||
activateButton(hairButton)
|
||||
this.activeCategory = "hair"
|
||||
this.subCategoryTabs?.removeAllTabs()
|
||||
this.subcategories = Arrays.asList("bangs", "color", "ponytail")
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_hair_bangs).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_hair_color).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_hair_ponytail).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
loadCustomizations()
|
||||
}
|
||||
|
||||
fun selectedExtrasCategory() {
|
||||
activateButton(extrasButton)
|
||||
this.activeCategory = "extras"
|
||||
this.subCategoryTabs?.removeAllTabs()
|
||||
this.subcategories = Arrays.asList("glasses", "flower", "wheelchair")
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_glasses).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_flower).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
subCategoryTabs?.newTab()?.setText(R.string.avatar_wheelchair).notNull { this.subCategoryTabs?.addTab(it) }
|
||||
loadCustomizations()
|
||||
}
|
||||
|
||||
fun randomizeCharacter() {
|
||||
if (user == null) {
|
||||
return
|
||||
}
|
||||
val command = UpdateUserCommand()
|
||||
val updateData = HashMap<String, Any>()
|
||||
updateData["preferences.size"] = chooseRandomKey(customizationRepository.getCustomizations("body", "size", user), false)
|
||||
updateData["preferences.shirt"] = chooseRandomKey(customizationRepository.getCustomizations("body", "shirt", user), false)
|
||||
updateData["preferences.skin"] = chooseRandomKey(customizationRepository.getCustomizations("skin", "color", user), false)
|
||||
updateData["preferences.hair.color"] = chooseRandomKey(customizationRepository.getCustomizations("hair", "color", user), false)
|
||||
updateData["preferences.hair.base"] = chooseRandomKey(customizationRepository.getCustomizations("hair", "ponytail", user), false)
|
||||
updateData["preferences.hair.bangs"] = chooseRandomKey(customizationRepository.getCustomizations("hair", "bangs", user), false)
|
||||
updateData["preferences.hair.flower"] = chooseRandomKey(customizationRepository.getCustomizations("extras", "flower", user), true)
|
||||
updateData["preferences.chair"] = chooseRandomKey(customizationRepository.getCustomizations("extras", "wheelchair", user), true)
|
||||
command.updateData = updateData
|
||||
|
||||
EventBus.getDefault().post(command)
|
||||
}
|
||||
|
||||
private fun chooseRandomKey(customizations: List<SetupCustomization>, weighFirstOption: Boolean): String {
|
||||
if (customizations.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
if (weighFirstOption) {
|
||||
if (random.nextInt(10) > 3) {
|
||||
return customizations[0].key
|
||||
}
|
||||
}
|
||||
return customizations[random.nextInt(customizations.size)].key
|
||||
}
|
||||
|
||||
private fun activateButton(button: AvatarCategoryView?) {
|
||||
if (this.activeButton != null) {
|
||||
this.activeButton?.setActive(false)
|
||||
}
|
||||
this.activeButton = button
|
||||
this.activeButton?.setActive(true)
|
||||
val location = IntArray(2)
|
||||
val params = this.caretView?.layoutParams as RelativeLayout.LayoutParams
|
||||
this.activeButton?.getLocationOnScreen(location)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val r = resources
|
||||
val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40f, r.displayMetrics).toInt()
|
||||
params.marginStart = location[0] + px
|
||||
this.caretView?.layoutParams = params
|
||||
} else {
|
||||
caretView?.visibility = View.GONE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
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.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class IntroFragment extends BaseFragment {
|
||||
|
||||
@BindView(R.id.subtitleTextView)
|
||||
TextView subtitleTextView;
|
||||
|
||||
@BindView(R.id.titleTextView)
|
||||
TextView titleTextView;
|
||||
|
||||
@BindView(R.id.titleImageView)
|
||||
ImageView titleImageView;
|
||||
|
||||
@BindView(R.id.descriptionTextView)
|
||||
TextView descriptionTextView;
|
||||
|
||||
@BindView(R.id.imageView)
|
||||
ImageView imageView;
|
||||
|
||||
@BindView(R.id.container_view)
|
||||
ViewGroup containerView;
|
||||
|
||||
Drawable image;
|
||||
Drawable titleImage;
|
||||
String subtitle;
|
||||
String title;
|
||||
String description;
|
||||
Integer backgroundColor;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View v = inflater.inflate(R.layout.fragment_intro, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, v));
|
||||
|
||||
if (this.image != null) {
|
||||
this.imageView.setImageDrawable(this.image);
|
||||
}
|
||||
|
||||
if (this.titleImage != null) {
|
||||
this.titleImageView.setImageDrawable(this.titleImage);
|
||||
}
|
||||
|
||||
if (this.subtitle != null) {
|
||||
this.subtitleTextView.setText(this.subtitle);
|
||||
}
|
||||
|
||||
if (this.title != null) {
|
||||
this.titleTextView.setText(this.title);
|
||||
}
|
||||
|
||||
if (this.description != null) {
|
||||
this.descriptionTextView.setText(this.description);
|
||||
}
|
||||
|
||||
if (this.backgroundColor != null) {
|
||||
this.containerView.setBackgroundColor(this.backgroundColor);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
public void setImage(Drawable image) {
|
||||
this.image = image;
|
||||
if (this.imageView != null && image != null) {
|
||||
this.imageView.setImageDrawable(image);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitleImage(Drawable image) {
|
||||
this.titleImage = image;
|
||||
if (this.titleImageView != null && image != null) {
|
||||
this.titleImageView.setImageDrawable(image);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSubtitle(String text) {
|
||||
this.subtitle = text;
|
||||
if (this.subtitleTextView != null && text != null) {
|
||||
this.subtitleTextView.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(String text) {
|
||||
this.title = text;
|
||||
if (this.titleTextView != null && text != null) {
|
||||
this.titleTextView.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDescription(String text) {
|
||||
this.description = text;
|
||||
if (this.descriptionTextView != null && text != null) {
|
||||
this.descriptionTextView.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBackgroundColor(int color) {
|
||||
this.backgroundColor = color;
|
||||
if (containerView != null) {
|
||||
containerView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
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.components.AppComponent
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
|
||||
class IntroFragment : BaseFragment() {
|
||||
|
||||
private val subtitleTextView: TextView? by bindView(R.id.subtitleTextView)
|
||||
private val titleTextView: TextView? by bindView(R.id.titleTextView)
|
||||
private val titleImageView: ImageView? by bindView(R.id.titleImageView)
|
||||
private val descriptionTextView: TextView? by bindView(R.id.descriptionTextView)
|
||||
private val imageView: ImageView? by bindView(R.id.imageView)
|
||||
private val containerView: ViewGroup? by bindView(R.id.container_view)
|
||||
|
||||
private var image: Drawable? = null
|
||||
private var titleImage: Drawable? = null
|
||||
private var subtitle: String? = null
|
||||
private var title: String? = null
|
||||
private var description: String? = null
|
||||
private var backgroundColor: Int? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_intro)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
if (this.image != null) {
|
||||
this.imageView?.setImageDrawable(this.image)
|
||||
}
|
||||
|
||||
if (this.titleImage != null) {
|
||||
this.titleImageView?.setImageDrawable(this.titleImage)
|
||||
}
|
||||
|
||||
if (this.subtitle != null) {
|
||||
this.subtitleTextView?.text = this.subtitle
|
||||
}
|
||||
|
||||
if (this.title != null) {
|
||||
this.titleTextView?.text = this.title
|
||||
}
|
||||
|
||||
if (this.description != null) {
|
||||
this.descriptionTextView?.text = this.description
|
||||
}
|
||||
|
||||
backgroundColor.notNull {
|
||||
this.containerView?.setBackgroundColor(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
fun setImage(image: Drawable?) {
|
||||
this.image = image
|
||||
if (image != null) {
|
||||
this.imageView?.setImageDrawable(image)
|
||||
}
|
||||
}
|
||||
|
||||
fun setTitleImage(image: Drawable?) {
|
||||
this.titleImage = image
|
||||
this.titleImageView?.setImageDrawable(image)
|
||||
}
|
||||
|
||||
fun setSubtitle(text: String?) {
|
||||
this.subtitle = text
|
||||
subtitleTextView?.text = text
|
||||
}
|
||||
|
||||
fun setTitle(text: String?) {
|
||||
this.title = text
|
||||
titleTextView?.text = text
|
||||
}
|
||||
|
||||
fun setDescription(text: String?) {
|
||||
descriptionTextView?.text = text
|
||||
}
|
||||
|
||||
fun setBackgroundColor(color: Int) {
|
||||
this.backgroundColor = color
|
||||
containerView?.setBackgroundColor(color)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.models.tasks.Days;
|
||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||
import com.habitrpg.android.habitica.models.user.User;
|
||||
import com.habitrpg.android.habitica.ui.AvatarView;
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView;
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.TaskSetupAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class TaskSetupFragment extends BaseFragment {
|
||||
|
||||
|
||||
public SetupActivity activity;
|
||||
public int width;
|
||||
View view;
|
||||
@BindView(R.id.recyclerView)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(R.id.avatarView)
|
||||
AvatarView avatarView;
|
||||
@BindView(R.id.speech_bubble)
|
||||
SpeechBubbleView speechBubbleView;
|
||||
TaskSetupAdapter adapter;
|
||||
private String[][] taskGroups;
|
||||
private Object[][] tasks;
|
||||
private User user;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
view = inflater.inflate(R.layout.fragment_setup_tasks, container, false);
|
||||
|
||||
this.setTasks();
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
this.adapter = new TaskSetupAdapter();
|
||||
this.adapter.setTaskList(this.taskGroups);
|
||||
this.recyclerView.setLayoutManager(new GridLayoutManager(activity, 2));
|
||||
this.recyclerView.setAdapter(this.adapter);
|
||||
|
||||
if (this.user != null) {
|
||||
this.updateAvatar();
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
if (isVisibleToUser && getContext() != null) {
|
||||
speechBubbleView.animateText(getContext().getString(R.string.task_setup_description));
|
||||
}
|
||||
}
|
||||
|
||||
public void setUser(@Nullable User user) {
|
||||
this.user = user;
|
||||
if (avatarView != null) {
|
||||
updateAvatar();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAvatar() {
|
||||
avatarView.setAvatar(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void setTasks() {
|
||||
this.taskGroups = new String[][]{
|
||||
{getString(R.string.setup_group_work), "work"},
|
||||
{getString(R.string.setup_group_exercise), "exercise"},
|
||||
{getString(R.string.setup_group_health), "healthWellness"},
|
||||
{getString(R.string.setup_group_school), "school"},
|
||||
{getString(R.string.setup_group_teams), "teams"},
|
||||
{getString(R.string.setup_group_chores), "chores"},
|
||||
{getString(R.string.setup_group_creativity), "creativity"},
|
||||
{getString(R.string.setuP_group_other), "other"}
|
||||
};
|
||||
|
||||
this.tasks = new Object[][]{
|
||||
{"work", "habit", getString(R.string.setup_task_work_1), true, false},
|
||||
{"work", "daily", getString(R.string.setup_task_work_2)},
|
||||
{"work", "todo", getString(R.string.setup_task_work_3)},
|
||||
|
||||
{"exercise", "habit", getString(R.string.setup_task_exercise_1), true, false},
|
||||
{"exercise", "daily", getString(R.string.setup_task_exercise_2)},
|
||||
{"exercise", "todo", getString(R.string.setup_task_exercise_3)},
|
||||
|
||||
{"healthWellness", "habit", getString(R.string.setup_task_healthWellness_1), true, true},
|
||||
{"healthWellness", "daily", getString(R.string.setup_task_healthWellness_2)},
|
||||
{"healthWellness", "todo", getString(R.string.setup_task_healthWellness_3)},
|
||||
|
||||
{"school", "habit", getString(R.string.setup_task_school_1), true, true},
|
||||
{"school", "daily", getString(R.string.setup_task_school_2)},
|
||||
{"school", "todo", getString(R.string.setup_task_school_3)},
|
||||
|
||||
{"teams", "habit", getString(R.string.setup_task_teams_1), true, false},
|
||||
{"teams", "daily", getString(R.string.setup_task_teams_2)},
|
||||
{"teams", "todo", getString(R.string.setup_task_teams_3)},
|
||||
|
||||
{"chores", "habit", getString(R.string.setup_task_chores_1), true, false},
|
||||
{"chores", "daily", getString(R.string.setup_task_chores_2)},
|
||||
{"chores", "todo", getString(R.string.setup_task_chores_3)},
|
||||
|
||||
{"creativity", "habit", getString(R.string.setup_task_creativity_1), true, false},
|
||||
{"creativity", "daily", getString(R.string.setup_task_creativity_2)},
|
||||
{"creativity", "todo", getString(R.string.setup_task_creativity_3)},
|
||||
};
|
||||
}
|
||||
|
||||
public List<Task> createSampleTasks() {
|
||||
List<String> groups = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (Boolean checked : this.adapter.checkedList) {
|
||||
if (checked) {
|
||||
groups.add(this.taskGroups[i][1]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
List<Task> tasks = new ArrayList<>();
|
||||
for (Object[] task : this.tasks) {
|
||||
String taskGroup = (String) task[0];
|
||||
if (groups.contains(taskGroup)) {
|
||||
Task taskObject;
|
||||
if (task.length == 5) {
|
||||
taskObject = this.makeTaskObject((String) task[1], (String) task[2], (Boolean) task[3], (Boolean) task[4]);
|
||||
} else {
|
||||
taskObject = this.makeTaskObject((String) task[1], (String) task[2], null, null);
|
||||
}
|
||||
tasks.add(taskObject);
|
||||
}
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
private Task makeTaskObject(String type, String text, @Nullable Boolean up, @Nullable Boolean down) {
|
||||
Task task = new Task();
|
||||
task.setText(text);
|
||||
task.setPriority(1.0f);
|
||||
task.setType(type);
|
||||
|
||||
if (type.equals("habit")) {
|
||||
task.setUp(up);
|
||||
task.setDown(down);
|
||||
}
|
||||
|
||||
if (type.equals("daily")) {
|
||||
task.setFrequency("weekly");
|
||||
task.setStartDate(new Date());
|
||||
Days days = new Days();
|
||||
days.setM(true);
|
||||
days.setT(true);
|
||||
days.setW(true);
|
||||
days.setTh(true);
|
||||
days.setF(true);
|
||||
days.setS(true);
|
||||
days.setSu(true);
|
||||
task.setRepeat(days);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.widget.GridLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.models.tasks.Days
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.AvatarView
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.TaskSetupAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import java.util.*
|
||||
|
||||
class TaskSetupFragment : BaseFragment() {
|
||||
|
||||
|
||||
var activity: SetupActivity? = null
|
||||
var width: Int = 0
|
||||
private val recyclerView: RecyclerView? by bindView(R.id.recyclerView)
|
||||
private val avatarView: AvatarView? by bindView(R.id.avatarView)
|
||||
private val speechBubbleView: SpeechBubbleView? by bindView(R.id.speech_bubble)
|
||||
internal var adapter: TaskSetupAdapter = TaskSetupAdapter()
|
||||
private var taskGroups: Array<Array<String>> = arrayOf()
|
||||
private var tasks: Array<Array<Any>> = arrayOf()
|
||||
private var user: User? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_setup_tasks)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
this.setTasks()
|
||||
|
||||
this.adapter = TaskSetupAdapter()
|
||||
this.adapter.setTaskList(this.taskGroups)
|
||||
this.recyclerView?.layoutManager = GridLayoutManager(activity, 2)
|
||||
this.recyclerView?.adapter = this.adapter
|
||||
|
||||
if (this.user != null) {
|
||||
this.updateAvatar()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
|
||||
super.setUserVisibleHint(isVisibleToUser)
|
||||
if (isVisibleToUser && context != null) {
|
||||
speechBubbleView?.animateText(context?.getString(R.string.task_setup_description))
|
||||
}
|
||||
}
|
||||
|
||||
fun setUser(user: User?) {
|
||||
this.user = user
|
||||
if (avatarView != null) {
|
||||
updateAvatar()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAvatar() {
|
||||
user.notNull {
|
||||
avatarView?.setAvatar(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
private fun setTasks() {
|
||||
this.taskGroups = arrayOf(arrayOf(getString(R.string.setup_group_work), "work"), arrayOf(getString(R.string.setup_group_exercise), "exercise"), arrayOf(getString(R.string.setup_group_health), "healthWellness"), arrayOf(getString(R.string.setup_group_school), "school"), arrayOf(getString(R.string.setup_group_teams), "teams"), arrayOf(getString(R.string.setup_group_chores), "chores"), arrayOf(getString(R.string.setup_group_creativity), "creativity"), arrayOf(getString(R.string.setuP_group_other), "other"))
|
||||
|
||||
this.tasks = arrayOf(arrayOf("work", "habit", getString(R.string.setup_task_work_1), true, false), arrayOf<Any>("work", "daily", getString(R.string.setup_task_work_2)), arrayOf<Any>("work", "todo", getString(R.string.setup_task_work_3)),
|
||||
arrayOf("exercise", "habit", getString(R.string.setup_task_exercise_1), true, false), arrayOf<Any>("exercise", "daily", getString(R.string.setup_task_exercise_2)), arrayOf<Any>("exercise", "todo", getString(R.string.setup_task_exercise_3)),
|
||||
arrayOf("healthWellness", "habit", getString(R.string.setup_task_healthWellness_1), true, true), arrayOf<Any>("healthWellness", "daily", getString(R.string.setup_task_healthWellness_2)), arrayOf<Any>("healthWellness", "todo", getString(R.string.setup_task_healthWellness_3)),
|
||||
arrayOf("school", "habit", getString(R.string.setup_task_school_1), true, true), arrayOf<Any>("school", "daily", getString(R.string.setup_task_school_2)), arrayOf<Any>("school", "todo", getString(R.string.setup_task_school_3)),
|
||||
arrayOf("teams", "habit", getString(R.string.setup_task_teams_1), true, false), arrayOf<Any>("teams", "daily", getString(R.string.setup_task_teams_2)), arrayOf<Any>("teams", "todo", getString(R.string.setup_task_teams_3)),
|
||||
arrayOf("chores", "habit", getString(R.string.setup_task_chores_1), true, false), arrayOf<Any>("chores", "daily", getString(R.string.setup_task_chores_2)), arrayOf<Any>("chores", "todo", getString(R.string.setup_task_chores_3)),
|
||||
arrayOf("creativity", "habit", getString(R.string.setup_task_creativity_1), true, false), arrayOf<Any>("creativity", "daily", getString(R.string.setup_task_creativity_2)), arrayOf<Any>("creativity", "todo", getString(R.string.setup_task_creativity_3)))
|
||||
}
|
||||
|
||||
fun createSampleTasks(): List<Task> {
|
||||
val groups = ArrayList<String>()
|
||||
for ((i, checked) in this.adapter.checkedList.withIndex()) {
|
||||
if (checked) {
|
||||
groups.add(this.taskGroups[i][1])
|
||||
}
|
||||
}
|
||||
val tasks = ArrayList<Task>()
|
||||
for (task in this.tasks) {
|
||||
val taskGroup = task[0] as String
|
||||
if (groups.contains(taskGroup)) {
|
||||
val taskObject: Task = if (task.size == 5) {
|
||||
this.makeTaskObject(task[1] as String, task[2] as String, task[3] as Boolean, task[4] as Boolean)
|
||||
} else {
|
||||
this.makeTaskObject(task[1] as String, task[2] as String, null, null)
|
||||
}
|
||||
tasks.add(taskObject)
|
||||
}
|
||||
}
|
||||
return tasks
|
||||
}
|
||||
|
||||
private fun makeTaskObject(type: String, text: String, up: Boolean?, down: Boolean?): Task {
|
||||
val task = Task()
|
||||
task.text = text
|
||||
task.priority = 1.0f
|
||||
task.type = type
|
||||
|
||||
if (type == "habit") {
|
||||
task.up = up
|
||||
task.down = down
|
||||
}
|
||||
|
||||
if (type == "daily") {
|
||||
task.frequency = "weekly"
|
||||
task.startDate = Date()
|
||||
val days = Days()
|
||||
days.m = true
|
||||
days.t = true
|
||||
days.w = true
|
||||
days.th = true
|
||||
days.f = true
|
||||
days.s = true
|
||||
days.su = true
|
||||
task.repeat = days
|
||||
}
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class WelcomeFragment extends BaseFragment {
|
||||
|
||||
@BindView(R.id.speech_bubble)
|
||||
SpeechBubbleView speechBubbleView;
|
||||
|
||||
@BindView(R.id.heart_icon)
|
||||
ImageView heartIconView;
|
||||
@BindView(R.id.exp_icon)
|
||||
ImageView expIconView;
|
||||
@BindView(R.id.magic_icon)
|
||||
ImageView magicIconView;
|
||||
@BindView(R.id.gold_icon)
|
||||
ImageView goldIconView;
|
||||
@BindView(R.id.gem_icon)
|
||||
ImageView gemIconView;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View v = inflater.inflate(R.layout.fragment_welcome, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, v));
|
||||
|
||||
speechBubbleView.animateText(getContext().getString(R.string.welcome_text));
|
||||
|
||||
heartIconView.setImageBitmap(HabiticaIconsHelper.imageOfHeartLightBg());
|
||||
expIconView.setImageBitmap(HabiticaIconsHelper.imageOfExperience());
|
||||
magicIconView.setImageBitmap(HabiticaIconsHelper.imageOfMagic());
|
||||
goldIconView.setImageBitmap(HabiticaIconsHelper.imageOfGold());
|
||||
gemIconView.setImageBitmap(HabiticaIconsHelper.imageOfGem());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.setup
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.ui.SpeechBubbleView
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
||||
class WelcomeFragment : BaseFragment() {
|
||||
|
||||
private val speechBubbleView: SpeechBubbleView? by bindView(R.id.speech_bubble)
|
||||
private val heartIconView: ImageView? by bindView(R.id.heart_icon)
|
||||
private val magicIconView: ImageView? by bindView(R.id.magic_icon)
|
||||
private val expIconView: ImageView? by bindView(R.id.exp_icon)
|
||||
private val goldIconView: ImageView? by bindView(R.id.gold_icon)
|
||||
private val gemIconView: ImageView? by bindView(R.id.gem_icon)
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
|
||||
return container?.inflate(R.layout.fragment_welcome)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
speechBubbleView?.animateText(context?.getString(R.string.welcome_text))
|
||||
|
||||
heartIconView?.setImageBitmap(HabiticaIconsHelper.imageOfHeartLightBg())
|
||||
expIconView?.setImageBitmap(HabiticaIconsHelper.imageOfExperience())
|
||||
magicIconView?.setImageBitmap(HabiticaIconsHelper.imageOfMagic())
|
||||
goldIconView?.setImageBitmap(HabiticaIconsHelper.imageOfGold())
|
||||
gemIconView?.setImageBitmap(HabiticaIconsHelper.imageOfGem())
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.data.SocialRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.models.social.Group;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.realm.RealmResults;
|
||||
|
||||
public class GuildsOverviewFragment extends BaseMainFragment implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
SocialRepository socialRepository;
|
||||
@Inject
|
||||
ChallengeRepository challengeRepository;
|
||||
|
||||
@BindView(R.id.my_guilds_listview)
|
||||
LinearLayout guildsListView;
|
||||
@BindView(R.id.publicGuildsButton)
|
||||
Button publicGuildsButton;
|
||||
@BindView(R.id.chat_refresh_layout)
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
||||
private List<Group> guilds;
|
||||
private ArrayList<String> guildIDs;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstance) {
|
||||
super.onCreate(savedInstance);
|
||||
this.fetchGuilds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View v = inflater.inflate(R.layout.fragment_guilds_overview, container, false);
|
||||
setUnbinder(ButterKnife.bind(this, v));
|
||||
swipeRefreshLayout.setOnRefreshListener(this);
|
||||
this.publicGuildsButton.setOnClickListener(this);
|
||||
getCompositeSubscription().add(socialRepository.getUserGroups().subscribe(this::setGuilds, RxErrorHandler.handleEmptyError()));
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
socialRepository.close();
|
||||
challengeRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
}
|
||||
fetchGuilds();
|
||||
}
|
||||
|
||||
private void fetchGuilds() {
|
||||
if (this.socialRepository != null) {
|
||||
this.socialRepository.retrieveGroups("guilds")
|
||||
.subscribe(groups -> {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
}
|
||||
|
||||
private void setGuilds(RealmResults<Group> guilds) {
|
||||
this.guilds = guilds;
|
||||
if (this.guildsListView == null) {
|
||||
return;
|
||||
}
|
||||
this.guildIDs = new ArrayList<>();
|
||||
this.guildsListView.removeAllViewsInLayout();
|
||||
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
for (Group guild : this.guilds) {
|
||||
TextView entry = (TextView) inflater.inflate(R.layout.plain_list_item, this.guildsListView, false);
|
||||
entry.setText(guild.getName());
|
||||
entry.setOnClickListener(this);
|
||||
this.guildsListView.addView(entry);
|
||||
this.guildIDs.add(guild.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
BaseMainFragment fragment;
|
||||
if (v == this.publicGuildsButton) {
|
||||
PublicGuildsFragment publicGuildsFragment = new PublicGuildsFragment();
|
||||
publicGuildsFragment.memberGuildIDs = this.guildIDs;
|
||||
fragment = publicGuildsFragment;
|
||||
} else {
|
||||
Integer guildIndex = ((ViewGroup) v.getParent()).indexOfChild(v);
|
||||
GuildFragment guildFragment = new GuildFragment();
|
||||
guildFragment.setGuildId(this.guilds.get(guildIndex).getId());
|
||||
guildFragment.isMember = true;
|
||||
fragment = guildFragment;
|
||||
}
|
||||
if (this.activity != null) {
|
||||
this.activity.displayFragment(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String customTitle() {
|
||||
if (isAdded()) {
|
||||
return getString(R.string.sidebar_guilds);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.widget.SwipeRefreshLayout
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.realm.RealmResults
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class GuildsOverviewFragment : BaseMainFragment(), View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
@Inject
|
||||
lateinit var challengeRepository: ChallengeRepository
|
||||
|
||||
private val guildsListView: LinearLayout? by bindView(R.id.my_guilds_listview)
|
||||
private val publicGuildsButton: Button? by bindView(R.id.publicGuildsButton)
|
||||
private val swipeRefreshLayout: SwipeRefreshLayout? by bindView(R.id.chat_refresh_layout)
|
||||
|
||||
private var guilds: List<Group>? = null
|
||||
private var guildIDs: ArrayList<String>? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
this.fetchGuilds()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_guilds_overview)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
swipeRefreshLayout?.setOnRefreshListener(this)
|
||||
this.publicGuildsButton?.setOnClickListener(this)
|
||||
compositeSubscription.add(socialRepository.getUserGroups().subscribe(Consumer { this.setGuilds(it) }, RxErrorHandler.handleEmptyError()))
|
||||
}
|
||||
override fun onDestroy() {
|
||||
socialRepository.close()
|
||||
challengeRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
if (swipeRefreshLayout != null) {
|
||||
swipeRefreshLayout?.isRefreshing = true
|
||||
}
|
||||
fetchGuilds()
|
||||
}
|
||||
|
||||
private fun fetchGuilds() {
|
||||
this.socialRepository.retrieveGroups("guilds")
|
||||
.subscribe(Consumer {
|
||||
swipeRefreshLayout?.isRefreshing = false
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
private fun setGuilds(guilds: RealmResults<Group>) {
|
||||
this.guilds = guilds
|
||||
if (this.guildsListView == null) {
|
||||
return
|
||||
}
|
||||
this.guildIDs = ArrayList()
|
||||
this.guildsListView?.removeAllViewsInLayout()
|
||||
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
for (guild in guilds) {
|
||||
val entry = inflater.inflate(R.layout.plain_list_item, this.guildsListView, false) as TextView
|
||||
entry.text = guild.name
|
||||
entry.setOnClickListener(this)
|
||||
this.guildsListView?.addView(entry)
|
||||
this.guildIDs?.add(guild.id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
val fragment: BaseMainFragment
|
||||
if (v === this.publicGuildsButton) {
|
||||
val publicGuildsFragment = PublicGuildsFragment()
|
||||
publicGuildsFragment.memberGuildIDs = this.guildIDs
|
||||
fragment = publicGuildsFragment
|
||||
} else {
|
||||
val guildIndex = (v.parent as ViewGroup).indexOfChild(v)
|
||||
val guildFragment = GuildFragment()
|
||||
guildFragment.setGuildId(this.guilds?.get(guildIndex)?.id)
|
||||
guildFragment.isMember = true
|
||||
fragment = guildFragment
|
||||
}
|
||||
activity?.displayFragment(fragment)
|
||||
}
|
||||
|
||||
|
||||
override fun customTitle(): String {
|
||||
return if (isAdded) {
|
||||
getString(R.string.sidebar_guilds)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.SocialRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.PublicGuildsRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator;
|
||||
import com.habitrpg.android.habitica.ui.helpers.UiUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class PublicGuildsFragment extends BaseMainFragment implements SearchView.OnQueryTextListener {
|
||||
|
||||
@Inject
|
||||
SocialRepository socialRepository;
|
||||
|
||||
List<String> memberGuildIDs;
|
||||
|
||||
@BindView(R.id.recyclerView)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
private View view;
|
||||
private PublicGuildsRecyclerViewAdapter viewAdapter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
|
||||
|
||||
setUnbinder(ButterKnife.bind(this, view));
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL));
|
||||
viewAdapter = new PublicGuildsRecyclerViewAdapter(null, true);
|
||||
viewAdapter.setMemberGuildIDs(this.memberGuildIDs);
|
||||
viewAdapter.apiClient = this.apiClient;
|
||||
recyclerView.setAdapter(viewAdapter);
|
||||
recyclerView.setItemAnimator(new SafeDefaultItemAnimator());
|
||||
this.fetchGuilds();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstance) {
|
||||
super.onCreate(savedInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
socialRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void fetchGuilds() {
|
||||
if (this.socialRepository != null) {
|
||||
this.socialRepository.getPublicGuilds()
|
||||
.firstElement()
|
||||
.subscribe(groups -> {
|
||||
if (PublicGuildsFragment.this.viewAdapter != null) {
|
||||
PublicGuildsFragment.this.viewAdapter.updateData(groups);
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError());
|
||||
this.socialRepository.retrieveGroups("publicGuilds").subscribe(groups -> {}, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_public_guild, menu);
|
||||
|
||||
MenuItem searchItem = menu.findItem(R.id.action_guild_search);
|
||||
SearchView guildSearchView = (SearchView) searchItem.getActionView();
|
||||
SearchView.SearchAutoComplete theTextArea = guildSearchView.findViewById(R.id.search_src_text);
|
||||
theTextArea.setHintTextColor(ContextCompat.getColor(getContext(), R.color.white));
|
||||
guildSearchView.setQueryHint(getString(R.string.guild_search_hint));
|
||||
guildSearchView.setOnQueryTextListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String s) {
|
||||
viewAdapter.getFilter().filter(s);
|
||||
if (this.activity != null) {
|
||||
UiUtils.dismissKeyboard(this.activity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String s) {
|
||||
viewAdapter.getFilter().filter(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String customTitle() {
|
||||
if (!isAdded()) {
|
||||
return "";
|
||||
}
|
||||
return getString(R.string.public_guilds);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.widget.DividerItemDecoration
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.SearchView
|
||||
import android.view.*
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.PublicGuildsRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.helpers.UiUtils
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import io.reactivex.functions.Consumer
|
||||
import javax.inject.Inject
|
||||
|
||||
class PublicGuildsFragment : BaseMainFragment(), SearchView.OnQueryTextListener {
|
||||
|
||||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
|
||||
var memberGuildIDs: List<String>? = null
|
||||
|
||||
private val recyclerView: RecyclerView? by bindView(R.id.recyclerView)
|
||||
|
||||
private var viewAdapter = PublicGuildsRecyclerViewAdapter(null, true)
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_recyclerview)
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
recyclerView?.layoutManager = LinearLayoutManager(this.activity)
|
||||
recyclerView?.addItemDecoration(DividerItemDecoration(getActivity()!!, DividerItemDecoration.VERTICAL))
|
||||
viewAdapter.setMemberGuildIDs(this.memberGuildIDs)
|
||||
viewAdapter.apiClient = this.apiClient
|
||||
viewAdapter = PublicGuildsRecyclerViewAdapter(null, true)
|
||||
recyclerView?.adapter = viewAdapter
|
||||
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
this.fetchGuilds()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
socialRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun fetchGuilds() {
|
||||
this.socialRepository.getPublicGuilds()
|
||||
.firstElement()
|
||||
.subscribe(Consumer { groups ->
|
||||
this@PublicGuildsFragment.viewAdapter.updateData(groups)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
this.socialRepository.retrieveGroups("publicGuilds").subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater!!.inflate(R.menu.menu_public_guild, menu)
|
||||
|
||||
val searchItem = menu!!.findItem(R.id.action_guild_search)
|
||||
val guildSearchView = searchItem.actionView as SearchView
|
||||
val theTextArea = guildSearchView.findViewById<SearchView.SearchAutoComplete>(R.id.search_src_text)
|
||||
theTextArea.setHintTextColor(ContextCompat.getColor(context!!, R.color.white))
|
||||
guildSearchView.queryHint = getString(R.string.guild_search_hint)
|
||||
guildSearchView.setOnQueryTextListener(this)
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(s: String): Boolean {
|
||||
viewAdapter.filter.filter(s)
|
||||
if (this.activity != null) {
|
||||
UiUtils.dismissKeyboard(this.activity!!)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(s: String): Boolean {
|
||||
viewAdapter.filter.filter(s)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun customTitle(): String {
|
||||
return if (!isAdded) {
|
||||
""
|
||||
} else getString(R.string.public_guilds)
|
||||
}
|
||||
}
|
||||
|
|
@ -165,7 +165,8 @@ public class QuestDetailFragment extends BaseMainFragment {
|
|||
return;
|
||||
}
|
||||
questTitleView.setText(questContent.getText());
|
||||
questDescriptionView.setText(MarkdownParser.parseMarkdown(questContent.getNotes()));
|
||||
//TODO: FIX
|
||||
//questDescriptionView.setText(MarkdownParser.parseMarkdown(questContent.getNotes()));
|
||||
DataBindingUtils.INSTANCE.loadImage(questScrollImageView, "inventory_quest_scroll_"+questContent.getKey());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,337 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.models.LeaveChallengeBody;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity;
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity;
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser;
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper;
|
||||
import com.habitrpg.android.habitica.utils.Action1;
|
||||
|
||||
import net.pherth.android.emoji_library.EmojiParser;
|
||||
import net.pherth.android.emoji_library.EmojiTextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class ChallengeDetailDialogHolder {
|
||||
|
||||
|
||||
@BindView(R.id.challenge_not_joined_header)
|
||||
LinearLayout notJoinedHeader;
|
||||
|
||||
@BindView(R.id.challenge_joined_header)
|
||||
LinearLayout joinedHeader;
|
||||
|
||||
@BindView(R.id.challenge_join_btn)
|
||||
Button joinButton;
|
||||
|
||||
@BindView(R.id.challenge_leave_btn)
|
||||
Button leaveButton;
|
||||
|
||||
@BindView(R.id.challenge_name)
|
||||
EmojiTextView challengeName;
|
||||
|
||||
@BindView(R.id.challenge_description)
|
||||
EmojiTextView challengeDescription;
|
||||
|
||||
@BindView(R.id.challenge_leader)
|
||||
TextView challengeLeader;
|
||||
|
||||
@BindView(R.id.gem_amount)
|
||||
TextView gem_amount;
|
||||
|
||||
@BindView(R.id.challenge_member_count)
|
||||
TextView member_count;
|
||||
|
||||
@BindView(R.id.task_group_layout)
|
||||
LinearLayout task_group_layout;
|
||||
|
||||
private AlertDialog dialog;
|
||||
private ChallengeRepository challengeRepository;
|
||||
@Nullable
|
||||
private Challenge challenge;
|
||||
private Action1<Challenge> challengeLeftAction;
|
||||
private Activity context;
|
||||
|
||||
|
||||
private ChallengeDetailDialogHolder(View view, Activity context) {
|
||||
this.context = context;
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
public static void showDialog(Activity activity, ChallengeRepository challengeRepository, Challenge challenge, Action1<Challenge> challengeLeftAction) {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
View dialogLayout = activity.getLayoutInflater().inflate(R.layout.dialog_challenge_detail, null);
|
||||
|
||||
ChallengeDetailDialogHolder challengeDetailDialogHolder = new ChallengeDetailDialogHolder(dialogLayout, activity);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||
.setView(dialogLayout);
|
||||
|
||||
challengeDetailDialogHolder.bind(builder.show(), challengeRepository, challenge, challengeLeftAction);
|
||||
}
|
||||
|
||||
public void bind(AlertDialog dialog, ChallengeRepository challengeRepository, Challenge challenge,
|
||||
Action1<Challenge> challengeLeftAction) {
|
||||
this.dialog = dialog;
|
||||
this.challengeRepository = challengeRepository;
|
||||
this.challenge = challenge;
|
||||
this.challengeLeftAction = challengeLeftAction;
|
||||
|
||||
changeViewsByChallenge(challenge);
|
||||
}
|
||||
|
||||
private void changeViewsByChallenge(Challenge challenge) {
|
||||
setJoined(challenge.isParticipating);
|
||||
|
||||
challengeName.setText(EmojiParser.parseEmojis(challenge.name));
|
||||
challengeDescription.setText(MarkdownParser.parseMarkdown(challenge.description));
|
||||
challengeLeader.setText(challenge.leaderName);
|
||||
|
||||
gem_amount.setText(String.valueOf(challenge.prize));
|
||||
member_count.setText(String.valueOf(challenge.memberCount));
|
||||
|
||||
challengeRepository.getChallengeTasks(challenge.id)
|
||||
.subscribe(taskList -> {
|
||||
ArrayList<Task> todos = new ArrayList<>();
|
||||
ArrayList<Task> habits = new ArrayList<>();
|
||||
ArrayList<Task> dailies = new ArrayList<>();
|
||||
ArrayList<Task> rewards = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Task> entry : taskList.tasks.entrySet()) {
|
||||
switch (entry.getValue().getType()) {
|
||||
case Task.TYPE_TODO:
|
||||
todos.add(entry.getValue());
|
||||
break;
|
||||
case Task.TYPE_HABIT:
|
||||
|
||||
habits.add(entry.getValue());
|
||||
break;
|
||||
case Task.TYPE_DAILY:
|
||||
|
||||
dailies.add(entry.getValue());
|
||||
break;
|
||||
case Task.TYPE_REWARD:
|
||||
|
||||
rewards.add(entry.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (habits.size() > 0) {
|
||||
addHabits(habits);
|
||||
}
|
||||
|
||||
if (dailies.size() > 0) {
|
||||
addDailys(dailies);
|
||||
}
|
||||
|
||||
if (todos.size() > 0) {
|
||||
addTodos(todos);
|
||||
}
|
||||
|
||||
if (rewards.size() > 0) {
|
||||
addRewards(rewards);
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
|
||||
private void addHabits(ArrayList<Task> habits) {
|
||||
LinearLayout taskGroup = (LinearLayout) context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_task_group, task_group_layout, false);
|
||||
TextView groupName = (TextView) taskGroup.findViewById(R.id.task_group_name);
|
||||
|
||||
LinearLayout tasks_layout = (LinearLayout) taskGroup.findViewById(R.id.tasks_layout);
|
||||
|
||||
groupName.setText(habits.size() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_HABITS, habits.size()));
|
||||
|
||||
int size = habits.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Task task = habits.get(i);
|
||||
|
||||
View entry = context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_habit, tasks_layout, false);
|
||||
TextView habitTitle = (TextView) entry.findViewById(R.id.habit_title);
|
||||
ImageView plusImg = (ImageView) entry.findViewById(task.getUp() ? R.id.plus_img_tinted : R.id.plus_img);
|
||||
ImageView minusImg = (ImageView) entry.findViewById(task.getDown() ? R.id.minus_img_tinted : R.id.minus_img);
|
||||
|
||||
plusImg.setVisibility(View.VISIBLE);
|
||||
minusImg.setVisibility(View.VISIBLE);
|
||||
|
||||
habitTitle.setText(EmojiParser.parseEmojis(task.getText()));
|
||||
tasks_layout.addView(entry);
|
||||
}
|
||||
task_group_layout.addView(taskGroup);
|
||||
}
|
||||
|
||||
private void addDailys(ArrayList<Task> dailies) {
|
||||
LinearLayout taskGroup = (LinearLayout) context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_task_group, task_group_layout, false);
|
||||
TextView groupName = (TextView) taskGroup.findViewById(R.id.task_group_name);
|
||||
|
||||
LinearLayout tasks_layout = (LinearLayout) taskGroup.findViewById(R.id.tasks_layout);
|
||||
|
||||
int size = dailies.size();
|
||||
groupName.setText(dailies.size() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_DAILYS, size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Task task = dailies.get(i);
|
||||
|
||||
View entry = context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_daily, tasks_layout, false);
|
||||
TextView title = (TextView) entry.findViewById(R.id.daily_title);
|
||||
title.setText(EmojiParser.parseEmojis(task.getText()));
|
||||
|
||||
if (task.getChecklist() != null && !task.getChecklist().isEmpty()) {
|
||||
View checklistIndicatorWrapper = entry.findViewById(R.id.checklistIndicatorWrapper);
|
||||
|
||||
checklistIndicatorWrapper.setVisibility(View.VISIBLE);
|
||||
|
||||
TextView checkListAllTextView = (TextView) entry.findViewById(R.id.checkListAllTextView);
|
||||
checkListAllTextView.setText(String.valueOf(task.getChecklist().size()));
|
||||
}
|
||||
tasks_layout.addView(entry);
|
||||
}
|
||||
task_group_layout.addView(taskGroup);
|
||||
}
|
||||
|
||||
private void addTodos(ArrayList<Task> todos) {
|
||||
LinearLayout taskGroup = (LinearLayout) context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_task_group, task_group_layout, false);
|
||||
TextView groupName = (TextView) taskGroup.findViewById(R.id.task_group_name);
|
||||
|
||||
LinearLayout tasks_layout = (LinearLayout) taskGroup.findViewById(R.id.tasks_layout);
|
||||
|
||||
int size = todos.size();
|
||||
groupName.setText(todos.size() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_TODOS, size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Task task = todos.get(i);
|
||||
|
||||
View entry = context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_todo, tasks_layout, false);
|
||||
TextView title = (TextView) entry.findViewById(R.id.todo_title);
|
||||
title.setText(EmojiParser.parseEmojis(task.getText()));
|
||||
|
||||
if (task.getChecklist() != null && !task.getChecklist().isEmpty()) {
|
||||
View checklistIndicatorWrapper = entry.findViewById(R.id.checklistIndicatorWrapper);
|
||||
|
||||
checklistIndicatorWrapper.setVisibility(View.VISIBLE);
|
||||
|
||||
TextView checkListAllTextView = (TextView) entry.findViewById(R.id.checkListAllTextView);
|
||||
checkListAllTextView.setText(String.valueOf(task.getChecklist().size()));
|
||||
}
|
||||
tasks_layout.addView(entry);
|
||||
}
|
||||
task_group_layout.addView(taskGroup);
|
||||
}
|
||||
|
||||
private void addRewards(ArrayList<Task> rewards) {
|
||||
LinearLayout taskGroup = (LinearLayout) context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_task_group, task_group_layout, false);
|
||||
TextView groupName = (TextView) taskGroup.findViewById(R.id.task_group_name);
|
||||
|
||||
LinearLayout tasks_layout = (LinearLayout) taskGroup.findViewById(R.id.tasks_layout);
|
||||
|
||||
int size = rewards.size();
|
||||
groupName.setText(rewards.size() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_REWARDS, size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Task task = rewards.get(i);
|
||||
|
||||
View entry = context.getLayoutInflater().inflate(R.layout.dialog_challenge_detail_reward, tasks_layout, false);
|
||||
((ImageView)entry.findViewById(R.id.gold_icon)).setImageBitmap(HabiticaIconsHelper.imageOfGold());
|
||||
TextView title = (TextView) entry.findViewById(R.id.reward_title);
|
||||
title.setText(EmojiParser.parseEmojis(task.getText()));
|
||||
tasks_layout.addView(entry);
|
||||
}
|
||||
task_group_layout.addView(taskGroup);
|
||||
}
|
||||
|
||||
private String getLabelByTypeAndCount(String type, int count) {
|
||||
if (Challenge.TASK_ORDER_DAILYS.equals(type)) {
|
||||
return context.getString(count == 1 ? R.string.daily : R.string.dailies);
|
||||
} else if (Challenge.TASK_ORDER_HABITS.equals(type)) {
|
||||
return context.getString(count == 1 ? R.string.habit : R.string.habits);
|
||||
} else if (Challenge.TASK_ORDER_REWARDS.equals(type)) {
|
||||
return context.getString(count == 1 ? R.string.reward : R.string.rewards);
|
||||
} else {
|
||||
return context.getString(count == 1 ? R.string.todo : R.string.todos);
|
||||
}
|
||||
}
|
||||
|
||||
private void setJoined(boolean joined) {
|
||||
joinedHeader.setVisibility(joined ? View.VISIBLE : View.GONE);
|
||||
leaveButton.setVisibility(joined ? View.VISIBLE : View.GONE);
|
||||
|
||||
notJoinedHeader.setVisibility(joined ? View.GONE : View.VISIBLE);
|
||||
joinButton.setVisibility(joined ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_leader)
|
||||
void openLeaderProfile() {
|
||||
FullProfileActivity.open(context, challenge.leaderId);
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_go_to_btn)
|
||||
void openChallengeActivity() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(ChallengeDetailActivity.CHALLENGE_ID, challenge.id);
|
||||
|
||||
Intent intent = new Intent(context, ChallengeDetailActivity.class);
|
||||
intent.putExtras(bundle);
|
||||
context.startActivity(intent);
|
||||
this.dialog.dismiss();
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_join_btn)
|
||||
void joinChallenge() {
|
||||
this.challengeRepository.joinChallenge(challenge).subscribe(this::changeViewsByChallenge, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_leave_btn)
|
||||
void leaveChallenge() {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(context.getString(R.string.challenge_leave_title))
|
||||
.setMessage(context.getString(R.string.challenge_leave_text, challenge.name))
|
||||
.setPositiveButton(context.getString(R.string.yes), (dialog, which) ->
|
||||
showRemoveTasksDialog(keepTasks -> this.challengeRepository.leaveChallenge(challenge, new LeaveChallengeBody(keepTasks))
|
||||
.subscribe(aVoid -> {
|
||||
if (challengeLeftAction != null) {
|
||||
challengeLeftAction.call(challenge);
|
||||
}
|
||||
this.dialog.dismiss();
|
||||
}, RxErrorHandler.handleEmptyError())))
|
||||
.setNegativeButton(context.getString(R.string.no), (dialog, which) -> dialog.dismiss()).show();
|
||||
}
|
||||
|
||||
// refactor as an UseCase later - see ChallengeDetailActivity
|
||||
private void showRemoveTasksDialog(Action1<String> callback){
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(context.getString(R.string.challenge_remove_tasks_title))
|
||||
.setMessage(context.getString(R.string.challenge_remove_tasks_text))
|
||||
.setPositiveButton(context.getString(R.string.remove_tasks), (dialog, which) -> {
|
||||
callback.call("remove-all");
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton(context.getString(R.string.keep_tasks), (dialog, which) -> {
|
||||
callback.call("keep-all");
|
||||
dialog.dismiss();
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.LeaveChallengeBody
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.activities.ChallengeDetailActivity
|
||||
import com.habitrpg.android.habitica.ui.activities.FullProfileActivity
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.utils.Action1
|
||||
import io.reactivex.functions.Consumer
|
||||
import net.pherth.android.emoji_library.EmojiParser
|
||||
import net.pherth.android.emoji_library.EmojiTextView
|
||||
import java.util.*
|
||||
|
||||
class ChallengeDetailDialogHolder private constructor(view: View, private val context: Activity) {
|
||||
|
||||
private val notJoinedHeader: LinearLayout? by bindView(view, R.id.challenge_not_joined_header)
|
||||
private val joinedHeader: LinearLayout? by bindView(view, R.id.challenge_joined_header)
|
||||
private val joinButton: Button? by bindView(view, R.id.challenge_join_btn)
|
||||
private val leaveButton: Button? by bindView(view, R.id.challenge_leave_btn)
|
||||
private val challengeName: EmojiTextView? by bindView(view, R.id.challenge_name)
|
||||
private val challengeDescription: EmojiTextView? by bindView(view, R.id.challenge_description)
|
||||
private val challengeLeader: TextView? by bindView(view, R.id.challenge_leader)
|
||||
private val gemAmountView: TextView? by bindView(view, R.id.gem_amount)
|
||||
private val memberCountView: TextView? by bindView(view, R.id.challenge_member_count)
|
||||
private val taskGrouplayout: LinearLayout? by bindView(view, R.id.task_group_layout)
|
||||
private val openChallengeButton: Button? by bindView(view, R.id.challenge_go_to_btn)
|
||||
|
||||
private var dialog: AlertDialog? = null
|
||||
lateinit var challengeRepository: ChallengeRepository
|
||||
private var challenge: Challenge? = null
|
||||
private var challengeLeftAction: Action1<Challenge>? = null
|
||||
|
||||
init {
|
||||
joinButton?.setOnClickListener { joinChallenge() }
|
||||
leaveButton?.setOnClickListener { leaveChallenge() }
|
||||
challengeLeader?.setOnClickListener { openLeaderProfile() }
|
||||
openChallengeButton?.setOnClickListener { openChallengeActivity() }
|
||||
}
|
||||
|
||||
fun bind(dialog: AlertDialog, challengeRepository: ChallengeRepository, challenge: Challenge,
|
||||
challengeLeftAction: Action1<Challenge>) {
|
||||
this.dialog = dialog
|
||||
this.challengeRepository = challengeRepository
|
||||
this.challenge = challenge
|
||||
this.challengeLeftAction = challengeLeftAction
|
||||
|
||||
changeViewsByChallenge(challenge)
|
||||
}
|
||||
|
||||
private fun changeViewsByChallenge(challenge: Challenge) {
|
||||
setJoined(challenge.isParticipating)
|
||||
|
||||
challengeName?.text = EmojiParser.parseEmojis(challenge.name)
|
||||
challengeDescription?.text = MarkdownParser.parseMarkdown(challenge.description)
|
||||
challengeLeader?.text = challenge.leaderName
|
||||
|
||||
gemAmountView?.text = challenge.prize.toString()
|
||||
memberCountView?.text = challenge.memberCount.toString()
|
||||
|
||||
challengeRepository.getChallengeTasks(challenge.id)
|
||||
.subscribe(Consumer { taskList ->
|
||||
val todos = ArrayList<Task>()
|
||||
val habits = ArrayList<Task>()
|
||||
val dailies = ArrayList<Task>()
|
||||
val rewards = ArrayList<Task>()
|
||||
|
||||
for (entry in taskList.tasks.entries) {
|
||||
when (entry.value.type) {
|
||||
Task.TYPE_TODO -> todos.add(entry.value)
|
||||
Task.TYPE_HABIT ->
|
||||
|
||||
habits.add(entry.value)
|
||||
Task.TYPE_DAILY ->
|
||||
|
||||
dailies.add(entry.value)
|
||||
Task.TYPE_REWARD ->
|
||||
|
||||
rewards.add(entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (habits.size > 0) {
|
||||
addHabits(habits)
|
||||
}
|
||||
|
||||
if (dailies.size > 0) {
|
||||
addDailys(dailies)
|
||||
}
|
||||
|
||||
if (todos.size > 0) {
|
||||
addTodos(todos)
|
||||
}
|
||||
|
||||
if (rewards.size > 0) {
|
||||
addRewards(rewards)
|
||||
}
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
private fun addHabits(habits: ArrayList<Task>) {
|
||||
val taskGroup = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_task_group, taskGrouplayout, false) as LinearLayout
|
||||
val groupName = taskGroup.findViewById<View>(R.id.task_group_name) as TextView
|
||||
|
||||
val tasksLayout = taskGroup.findViewById<View>(R.id.tasks_layout) as LinearLayout
|
||||
|
||||
groupName.text = habits.size.toString() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_HABITS, habits.size)
|
||||
|
||||
val size = habits.size
|
||||
for (i in 0 until size) {
|
||||
val task = habits[i]
|
||||
|
||||
val entry = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_habit, tasksLayout, false)
|
||||
val habitTitle = entry.findViewById<View>(R.id.habit_title) as TextView
|
||||
val plusImg = entry.findViewById<View>(if (task.up == true) R.id.plus_img_tinted else R.id.plus_img) as ImageView
|
||||
val minusImg = entry.findViewById<View>(if (task.down == true) R.id.minus_img_tinted else R.id.minus_img) as ImageView
|
||||
|
||||
plusImg.visibility = View.VISIBLE
|
||||
minusImg.visibility = View.VISIBLE
|
||||
|
||||
habitTitle.text = EmojiParser.parseEmojis(task.text)
|
||||
tasksLayout.addView(entry)
|
||||
}
|
||||
taskGrouplayout?.addView(taskGroup)
|
||||
}
|
||||
|
||||
private fun addDailys(dailies: ArrayList<Task>) {
|
||||
val taskGroup = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_task_group, taskGrouplayout, false) as LinearLayout
|
||||
val groupName = taskGroup.findViewById<View>(R.id.task_group_name) as TextView
|
||||
|
||||
val tasksLayout = taskGroup.findViewById<View>(R.id.tasks_layout) as LinearLayout
|
||||
|
||||
val size = dailies.size
|
||||
groupName.text = dailies.size.toString() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_DAILYS, size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
val task = dailies[i]
|
||||
|
||||
val entry = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_daily, tasksLayout, false)
|
||||
val title = entry.findViewById<View>(R.id.daily_title) as TextView
|
||||
title.text = EmojiParser.parseEmojis(task.text)
|
||||
|
||||
if (task.checklist != null && task.checklist?.isEmpty() == false) {
|
||||
val checklistIndicatorWrapper = entry.findViewById<View>(R.id.checklistIndicatorWrapper)
|
||||
|
||||
checklistIndicatorWrapper.visibility = View.VISIBLE
|
||||
|
||||
val checkListAllTextView = entry.findViewById<View>(R.id.checkListAllTextView) as TextView
|
||||
checkListAllTextView.text = task.checklist?.size.toString()
|
||||
}
|
||||
tasksLayout.addView(entry)
|
||||
}
|
||||
taskGrouplayout?.addView(taskGroup)
|
||||
}
|
||||
|
||||
private fun addTodos(todos: ArrayList<Task>) {
|
||||
val taskGroup = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_task_group, taskGrouplayout, false) as LinearLayout
|
||||
val groupName = taskGroup.findViewById<View>(R.id.task_group_name) as TextView
|
||||
|
||||
val tasksLayout = taskGroup.findViewById<View>(R.id.tasks_layout) as LinearLayout
|
||||
|
||||
val size = todos.size
|
||||
groupName.text = todos.size.toString() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_TODOS, size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
val task = todos[i]
|
||||
|
||||
val entry = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_todo, tasksLayout, false)
|
||||
val title = entry.findViewById<View>(R.id.todo_title) as TextView
|
||||
title.text = EmojiParser.parseEmojis(task.text)
|
||||
|
||||
if (task.checklist != null && task.checklist?.isEmpty() == false) {
|
||||
val checklistIndicatorWrapper = entry.findViewById<View>(R.id.checklistIndicatorWrapper)
|
||||
|
||||
checklistIndicatorWrapper.visibility = View.VISIBLE
|
||||
|
||||
val checkListAllTextView = entry.findViewById<View>(R.id.checkListAllTextView) as TextView
|
||||
checkListAllTextView.text = task.checklist?.size.toString()
|
||||
}
|
||||
tasksLayout.addView(entry)
|
||||
}
|
||||
taskGrouplayout?.addView(taskGroup)
|
||||
}
|
||||
|
||||
private fun addRewards(rewards: ArrayList<Task>) {
|
||||
val taskGroup = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_task_group, taskGrouplayout, false) as LinearLayout
|
||||
val groupName = taskGroup.findViewById<View>(R.id.task_group_name) as TextView
|
||||
|
||||
val tasksLayout = taskGroup.findViewById<View>(R.id.tasks_layout) as LinearLayout
|
||||
|
||||
val size = rewards.size
|
||||
groupName.text = rewards.size.toString() + " " + getLabelByTypeAndCount(Challenge.TASK_ORDER_REWARDS, size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
val task = rewards[i]
|
||||
|
||||
val entry = context.layoutInflater.inflate(R.layout.dialog_challenge_detail_reward, tasksLayout, false)
|
||||
(entry.findViewById<View>(R.id.gold_icon) as ImageView).setImageBitmap(HabiticaIconsHelper.imageOfGold())
|
||||
val title = entry.findViewById<View>(R.id.reward_title) as TextView
|
||||
title.text = EmojiParser.parseEmojis(task.text)
|
||||
tasksLayout.addView(entry)
|
||||
}
|
||||
taskGrouplayout?.addView(taskGroup)
|
||||
}
|
||||
|
||||
private fun getLabelByTypeAndCount(type: String, count: Int): String {
|
||||
return when (type) {
|
||||
Challenge.TASK_ORDER_DAILYS -> context.getString(if (count == 1) R.string.daily else R.string.dailies)
|
||||
Challenge.TASK_ORDER_HABITS -> context.getString(if (count == 1) R.string.habit else R.string.habits)
|
||||
Challenge.TASK_ORDER_REWARDS -> context.getString(if (count == 1) R.string.reward else R.string.rewards)
|
||||
else -> context.getString(if (count == 1) R.string.todo else R.string.todos)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setJoined(joined: Boolean) {
|
||||
joinedHeader?.visibility = if (joined) View.VISIBLE else View.GONE
|
||||
leaveButton?.visibility = if (joined) View.VISIBLE else View.GONE
|
||||
|
||||
notJoinedHeader?.visibility = if (joined) View.GONE else View.VISIBLE
|
||||
joinButton?.visibility = if (joined) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
private fun openLeaderProfile() {
|
||||
FullProfileActivity.open(context, challenge?.leaderId)
|
||||
}
|
||||
|
||||
private fun openChallengeActivity() {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(ChallengeDetailActivity.CHALLENGE_ID, challenge?.id)
|
||||
|
||||
val intent = Intent(context, ChallengeDetailActivity::class.java)
|
||||
intent.putExtras(bundle)
|
||||
context.startActivity(intent)
|
||||
this.dialog?.dismiss()
|
||||
}
|
||||
|
||||
private fun joinChallenge() {
|
||||
this.challengeRepository.joinChallenge(challenge).subscribe(Consumer<Challenge> { this.changeViewsByChallenge(it) }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
private fun leaveChallenge() {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(context.getString(R.string.challenge_leave_title))
|
||||
.setMessage(context.getString(R.string.challenge_leave_text, challenge?.name))
|
||||
.setPositiveButton(context.getString(R.string.yes)) { dialog, _ ->
|
||||
showRemoveTasksDialog(object : Action1<String> {
|
||||
override fun call(t: String) {
|
||||
challengeRepository.leaveChallenge(challenge, LeaveChallengeBody(t))
|
||||
.subscribe(Consumer {
|
||||
challenge.notNull {
|
||||
challengeLeftAction?.call(it)
|
||||
}
|
||||
dialog.dismiss()
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
})
|
||||
}
|
||||
.setNegativeButton(context.getString(R.string.no)) { dialog, _ -> dialog.dismiss() }.show()
|
||||
}
|
||||
|
||||
// refactor as an UseCase later - see ChallengeDetailActivity
|
||||
private fun showRemoveTasksDialog(callback: Action1<String>) {
|
||||
AlertDialog.Builder(context)
|
||||
.setTitle(context.getString(R.string.challenge_remove_tasks_title))
|
||||
.setMessage(context.getString(R.string.challenge_remove_tasks_text))
|
||||
.setPositiveButton(context.getString(R.string.remove_tasks)) { dialog, _ ->
|
||||
callback.call("remove-all")
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(context.getString(R.string.keep_tasks)) { dialog, _ ->
|
||||
callback.call("keep-all")
|
||||
dialog.dismiss()
|
||||
}.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun showDialog(activity: Activity?, challengeRepository: ChallengeRepository, challenge: Challenge, challengeLeftAction: Action1<Challenge>) {
|
||||
if (activity == null) {
|
||||
return
|
||||
}
|
||||
val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_challenge_detail, null)
|
||||
|
||||
val challengeDetailDialogHolder = ChallengeDetailDialogHolder(dialogLayout, activity)
|
||||
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
.setView(dialogLayout)
|
||||
|
||||
challengeDetailDialogHolder.bind(builder.show(), challengeRepository, challenge, challengeLeftAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.models.social.Group;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengesFilterRecyclerViewAdapter;
|
||||
import com.habitrpg.android.habitica.utils.Action1;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
class ChallengeFilterDialogHolder {
|
||||
|
||||
@BindView(R.id.challenge_filter_recycler_view)
|
||||
RecyclerView groupRecyclerView;
|
||||
|
||||
@BindView(R.id.challenge_filter_button_all)
|
||||
Button allButton;
|
||||
|
||||
@BindView(R.id.challenge_filter_button_none)
|
||||
Button noneButton;
|
||||
|
||||
@BindView(R.id.challenge_filter_owned)
|
||||
CheckBox checkboxOwned;
|
||||
|
||||
@BindView(R.id.challenge_filter_not_owned)
|
||||
CheckBox checkboxNotOwned;
|
||||
|
||||
private AlertDialog dialog;
|
||||
private List<Challenge> challengesViewed;
|
||||
private ChallengeFilterOptions currentFilter;
|
||||
private Action1<ChallengeFilterOptions> selectedGroupsCallback;
|
||||
private Activity context;
|
||||
private ChallengesFilterRecyclerViewAdapter adapter;
|
||||
|
||||
|
||||
private ChallengeFilterDialogHolder(View view, Activity context) {
|
||||
this.context = context;
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
static void showDialog(Activity activity, List<Challenge> challengesViewed,
|
||||
ChallengeFilterOptions currentFilter,
|
||||
Action1<ChallengeFilterOptions> selectedGroupsCallback) {
|
||||
View dialogLayout = activity.getLayoutInflater().inflate(R.layout.dialog_challenge_filter, null);
|
||||
|
||||
ChallengeFilterDialogHolder challengeFilterDialogHolder = new ChallengeFilterDialogHolder(dialogLayout, activity);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.filter)
|
||||
.setView(dialogLayout);
|
||||
|
||||
challengeFilterDialogHolder.bind(builder, challengesViewed, currentFilter, selectedGroupsCallback);
|
||||
}
|
||||
|
||||
public void bind(AlertDialog.Builder builder, List<Challenge> challengesViewed,
|
||||
ChallengeFilterOptions currentFilter,
|
||||
Action1<ChallengeFilterOptions> selectedGroupsCallback) {
|
||||
builder = builder
|
||||
.setPositiveButton(context.getString(R.string.done), (dialog1, which) -> doneClicked());
|
||||
this.dialog = builder.show();
|
||||
this.challengesViewed = challengesViewed;
|
||||
this.currentFilter = currentFilter;
|
||||
this.selectedGroupsCallback = selectedGroupsCallback;
|
||||
fillChallengeGroups();
|
||||
|
||||
if(currentFilter != null ){
|
||||
checkboxOwned.setChecked(currentFilter.showOwned);
|
||||
checkboxNotOwned.setChecked(currentFilter.notOwned);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillChallengeGroups() {
|
||||
|
||||
this.groupRecyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
adapter = new ChallengesFilterRecyclerViewAdapter(getGroups(challengesViewed));
|
||||
if(currentFilter != null && currentFilter.showByGroups != null){
|
||||
adapter.selectAll(currentFilter.showByGroups);
|
||||
}
|
||||
|
||||
this.groupRecyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private Collection<Group> getGroups(@Nullable List<Challenge> challenges){
|
||||
Map<String, Group> groupMap = new HashMap<>();
|
||||
|
||||
if (challenges != null) {
|
||||
for (Challenge challenge : challenges) {
|
||||
if (groupMap.containsKey(challenge.groupName)) {
|
||||
continue;
|
||||
}
|
||||
Group group = new Group();
|
||||
group.setId(challenge.groupId);
|
||||
group.setName(challenge.groupName);
|
||||
|
||||
groupMap.put(challenge.groupName, group);
|
||||
}
|
||||
}
|
||||
|
||||
return groupMap.values();
|
||||
}
|
||||
|
||||
private void doneClicked() {
|
||||
ChallengeFilterOptions options = new ChallengeFilterOptions();
|
||||
options.showByGroups = this.adapter.getCheckedEntries();
|
||||
options.showOwned = checkboxOwned.isChecked();
|
||||
options.notOwned = checkboxNotOwned.isChecked();
|
||||
|
||||
selectedGroupsCallback.call(options);
|
||||
this.dialog.hide();
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.challenge_filter_button_all)
|
||||
void allClicked() {
|
||||
this.adapter.selectAll();
|
||||
}
|
||||
|
||||
@OnClick(R.id.challenge_filter_button_none)
|
||||
void noneClicked() {
|
||||
this.adapter.deSelectAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.CheckBox
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengesFilterRecyclerViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.utils.Action1
|
||||
import java.util.*
|
||||
|
||||
internal class ChallengeFilterDialogHolder private constructor(view: View, private val context: Activity) {
|
||||
|
||||
private val groupRecyclerView: RecyclerView? by bindView(view, R.id.challenge_filter_recycler_view)
|
||||
private val allButton: Button? by bindView(view, R.id.challenge_filter_button_all)
|
||||
private val noneButton: Button? by bindView(view, R.id.challenge_filter_button_none)
|
||||
private val checkboxOwned: CheckBox? by bindView(view, R.id.challenge_filter_owned)
|
||||
private val checkboxNotOwned: CheckBox? by bindView(view, R.id.challenge_filter_not_owned)
|
||||
|
||||
private var dialog: AlertDialog? = null
|
||||
private var challengesViewed: List<Challenge>? = null
|
||||
private var currentFilter: ChallengeFilterOptions? = null
|
||||
private var selectedGroupsCallback: Action1<ChallengeFilterOptions>? = null
|
||||
private var adapter: ChallengesFilterRecyclerViewAdapter? = null
|
||||
|
||||
init {
|
||||
allButton?.setOnClickListener { allClicked() }
|
||||
noneButton?.setOnClickListener { noneClicked() }
|
||||
}
|
||||
|
||||
fun bind(builder: AlertDialog.Builder, challengesViewed: List<Challenge>,
|
||||
currentFilter: ChallengeFilterOptions?,
|
||||
selectedGroupsCallback: Action1<ChallengeFilterOptions>) {
|
||||
var dialogBuilder = builder
|
||||
dialogBuilder = builder
|
||||
.setPositiveButton(context.getString(R.string.done)) { _, _ -> doneClicked() }
|
||||
this.dialog = dialogBuilder.show()
|
||||
this.challengesViewed = challengesViewed
|
||||
this.currentFilter = currentFilter
|
||||
this.selectedGroupsCallback = selectedGroupsCallback
|
||||
fillChallengeGroups()
|
||||
|
||||
if (currentFilter != null) {
|
||||
checkboxOwned?.isChecked = currentFilter.showOwned
|
||||
checkboxNotOwned?.isChecked = currentFilter.notOwned
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillChallengeGroups() {
|
||||
|
||||
this.groupRecyclerView?.layoutManager = LinearLayoutManager(context)
|
||||
adapter = ChallengesFilterRecyclerViewAdapter(getGroups(challengesViewed))
|
||||
if (currentFilter != null && currentFilter?.showByGroups != null) {
|
||||
adapter?.selectAll(currentFilter?.showByGroups)
|
||||
}
|
||||
|
||||
this.groupRecyclerView?.adapter = adapter
|
||||
}
|
||||
|
||||
private fun getGroups(challenges: List<Challenge>?): Collection<Group> {
|
||||
val groupMap = HashMap<String, Group>()
|
||||
|
||||
if (challenges != null) {
|
||||
for (challenge in challenges) {
|
||||
if (groupMap.containsKey(challenge.groupName)) {
|
||||
continue
|
||||
}
|
||||
val group = Group()
|
||||
group.id = challenge.groupId
|
||||
group.name = challenge.groupName
|
||||
|
||||
groupMap[challenge.groupName] = group
|
||||
}
|
||||
}
|
||||
|
||||
return groupMap.values
|
||||
}
|
||||
|
||||
private fun doneClicked() {
|
||||
val options = ChallengeFilterOptions()
|
||||
options.showByGroups = this.adapter?.checkedEntries
|
||||
options.showOwned = checkboxOwned?.isChecked ?: false
|
||||
options.notOwned = checkboxNotOwned?.isChecked ?: false
|
||||
|
||||
selectedGroupsCallback?.call(options)
|
||||
this.dialog?.hide()
|
||||
}
|
||||
|
||||
|
||||
fun allClicked() {
|
||||
this.adapter?.selectAll()
|
||||
}
|
||||
|
||||
fun noneClicked() {
|
||||
this.adapter?.deSelectAll()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun showDialog(activity: Activity, challengesViewed: List<Challenge>,
|
||||
currentFilter: ChallengeFilterOptions?,
|
||||
selectedGroupsCallback: Action1<ChallengeFilterOptions>) {
|
||||
val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_challenge_filter, null)
|
||||
|
||||
val challengeFilterDialogHolder = ChallengeFilterDialogHolder(dialogLayout, activity)
|
||||
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
.setTitle(R.string.filter)
|
||||
.setView(dialogLayout)
|
||||
|
||||
challengeFilterDialogHolder.bind(builder, challengesViewed, currentFilter, selectedGroupsCallback)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.ChallengeRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.models.social.Challenge;
|
||||
import com.habitrpg.android.habitica.modules.AppModule;
|
||||
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity;
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport;
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import io.reactivex.Flowable;
|
||||
import io.realm.RealmResults;
|
||||
|
||||
public class ChallengeListFragment extends BaseMainFragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
ChallengeRepository challengeRepository;
|
||||
@Inject
|
||||
@Named(AppModule.NAMED_USER_ID)
|
||||
String userId;
|
||||
|
||||
@BindView(R.id.refreshLayout)
|
||||
SwipeRefreshLayout swipeRefreshLayout;
|
||||
@BindView(R.id.recyclerView)
|
||||
RecyclerViewEmptySupport recyclerView;
|
||||
@BindView(R.id.emptyView)
|
||||
public View emptyView;
|
||||
|
||||
private ChallengesListViewAdapter challengeAdapter;
|
||||
private boolean viewUserChallengesOnly;
|
||||
|
||||
public void setViewUserChallengesOnly(boolean only) {
|
||||
this.viewUserChallengesOnly = only;
|
||||
}
|
||||
|
||||
|
||||
private RealmResults<Challenge> challenges;
|
||||
|
||||
private ChallengeFilterOptions filterOptions;
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
challengeRepository.close();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View v = inflater.inflate(R.layout.fragment_challengeslist, container, false);
|
||||
setUnbinder(ButterKnife.bind(this, v));
|
||||
|
||||
challengeAdapter = new ChallengesListViewAdapter(null, true, viewUserChallengesOnly, userId);
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(this);
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
|
||||
recyclerView.setAdapter(challengeAdapter);
|
||||
if (!viewUserChallengesOnly) {
|
||||
this.recyclerView.setBackgroundResource(R.color.white);
|
||||
}
|
||||
|
||||
recyclerView.setEmptyView(emptyView);
|
||||
recyclerView.setItemAnimator(new SafeDefaultItemAnimator());
|
||||
|
||||
loadLocalChallenges();
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(@NonNull AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
fetchOnlineChallenges();
|
||||
}
|
||||
|
||||
private void setRefreshing(boolean state) {
|
||||
if (swipeRefreshLayout != null && swipeRefreshLayout.getVisibility() == View.VISIBLE) {
|
||||
swipeRefreshLayout.setRefreshing(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLocalChallenges() {
|
||||
Flowable<RealmResults<Challenge>> observable;
|
||||
|
||||
if (viewUserChallengesOnly && user != null) {
|
||||
observable = challengeRepository.getUserChallenges(user.getId());
|
||||
} else {
|
||||
observable = challengeRepository.getChallenges();
|
||||
}
|
||||
|
||||
observable.firstElement().subscribe(challenges -> {
|
||||
if (challenges.size() == 0) {
|
||||
fetchOnlineChallenges();
|
||||
}
|
||||
this.challenges = challenges;
|
||||
challengeAdapter.updateUnfilteredData(challenges);
|
||||
}, RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
|
||||
private void fetchOnlineChallenges() {
|
||||
setRefreshing(true);
|
||||
challengeRepository.retrieveChallenges(user).subscribe(challenges -> {}, RxErrorHandler.handleEmptyError(), () -> setRefreshing(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String customTitle() {
|
||||
if (!isAdded()) {
|
||||
return "";
|
||||
}
|
||||
return getString(R.string.sidebar_challenges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_list_challenges, menu);
|
||||
|
||||
|
||||
RelativeLayout badgeLayout = (RelativeLayout) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
|
||||
if (badgeLayout != null) {
|
||||
TextView filterCountTextView = badgeLayout.findViewById(R.id.badge_textview);
|
||||
filterCountTextView.setText(null);
|
||||
filterCountTextView.setVisibility(View.GONE);
|
||||
badgeLayout.setOnClickListener(view -> showFilterDialog());
|
||||
}
|
||||
}
|
||||
|
||||
private void showFilterDialog() {
|
||||
ChallengeFilterDialogHolder.showDialog(getActivity(),
|
||||
challenges,
|
||||
filterOptions, this::changeFilter);
|
||||
}
|
||||
|
||||
private void changeFilter(ChallengeFilterOptions challengeFilterOptions) {
|
||||
filterOptions = challengeFilterOptions;
|
||||
if (challengeAdapter != null) {
|
||||
challengeAdapter.filter(filterOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.action_create_challenge:
|
||||
Intent intent = new Intent(getActivity(), CreateChallengeActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_reload:
|
||||
fetchOnlineChallenges();
|
||||
return true;
|
||||
case R.id.action_search:
|
||||
showFilterDialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.challenges
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v4.view.MenuItemCompat
|
||||
import android.support.v4.widget.SwipeRefreshLayout
|
||||
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
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.social.Challenge
|
||||
import com.habitrpg.android.habitica.modules.AppModule
|
||||
import com.habitrpg.android.habitica.ui.activities.CreateChallengeActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.social.ChallengesListViewAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewEmptySupport
|
||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import com.habitrpg.android.habitica.utils.Action1
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.functions.Consumer
|
||||
import io.realm.RealmResults
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
||||
class ChallengeListFragment : BaseMainFragment(), SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
lateinit var challengeRepository: ChallengeRepository
|
||||
@field:[Inject Named(AppModule.NAMED_USER_ID)]
|
||||
lateinit var userId: String
|
||||
|
||||
private val swipeRefreshLayout: SwipeRefreshLayout? by bindView(R.id.refreshLayout)
|
||||
private val recyclerView: RecyclerViewEmptySupport? by bindView(R.id.recyclerView)
|
||||
private val emptyView: View? by bindView(R.id.emptyView)
|
||||
|
||||
private var challengeAdapter: ChallengesListViewAdapter? = null
|
||||
private var viewUserChallengesOnly: Boolean = false
|
||||
|
||||
|
||||
private var challenges: RealmResults<Challenge>? = null
|
||||
|
||||
private var filterOptions: ChallengeFilterOptions? = null
|
||||
|
||||
fun setViewUserChallengesOnly(only: Boolean) {
|
||||
this.viewUserChallengesOnly = only
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
challengeRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return container?.inflate(R.layout.fragment_challengeslist)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
challengeAdapter = ChallengesListViewAdapter(null, true, viewUserChallengesOnly, userId)
|
||||
|
||||
swipeRefreshLayout?.setOnRefreshListener(this)
|
||||
|
||||
recyclerView?.layoutManager = LinearLayoutManager(this.activity)
|
||||
recyclerView?.adapter = challengeAdapter
|
||||
if (!viewUserChallengesOnly) {
|
||||
this.recyclerView?.setBackgroundResource(R.color.white)
|
||||
}
|
||||
|
||||
recyclerView?.setEmptyView(emptyView)
|
||||
recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||
|
||||
loadLocalChallenges()
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
override fun onRefresh() {
|
||||
fetchOnlineChallenges()
|
||||
}
|
||||
|
||||
private fun setRefreshing(state: Boolean) {
|
||||
if (swipeRefreshLayout != null && swipeRefreshLayout!!.visibility == View.VISIBLE) {
|
||||
swipeRefreshLayout!!.isRefreshing = state
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadLocalChallenges() {
|
||||
val observable: Flowable<RealmResults<Challenge>> = if (viewUserChallengesOnly && user != null) {
|
||||
challengeRepository.getUserChallenges(user?.id)
|
||||
} else {
|
||||
challengeRepository.challenges
|
||||
}
|
||||
|
||||
observable.firstElement().subscribe(Consumer { challenges ->
|
||||
if (challenges.size == 0) {
|
||||
fetchOnlineChallenges()
|
||||
}
|
||||
this.challenges = challenges
|
||||
challengeAdapter!!.updateUnfilteredData(challenges)
|
||||
}, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
private fun fetchOnlineChallenges() {
|
||||
setRefreshing(true)
|
||||
challengeRepository.retrieveChallenges(user).doOnComplete {
|
||||
setRefreshing(false)
|
||||
} .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
override fun customTitle(): String {
|
||||
return if (!isAdded) {
|
||||
""
|
||||
} else getString(R.string.sidebar_challenges)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater?.inflate(R.menu.menu_list_challenges, menu)
|
||||
|
||||
|
||||
val badgeLayout = MenuItemCompat.getActionView(menu!!.findItem(R.id.action_search)) as RelativeLayout?
|
||||
if (badgeLayout != null) {
|
||||
val filterCountTextView = badgeLayout.findViewById<TextView>(R.id.badge_textview)
|
||||
filterCountTextView.text = null
|
||||
filterCountTextView.visibility = View.GONE
|
||||
badgeLayout.setOnClickListener { showFilterDialog() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun showFilterDialog() {
|
||||
ChallengeFilterDialogHolder.showDialog(getActivity()!!,
|
||||
challenges ?: emptyList(),
|
||||
filterOptions, object : Action1<ChallengeFilterOptions> {
|
||||
override fun call(t: ChallengeFilterOptions) {
|
||||
changeFilter(t)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun changeFilter(challengeFilterOptions: ChallengeFilterOptions) {
|
||||
filterOptions = challengeFilterOptions
|
||||
challengeAdapter?.filter(filterOptions)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
val id = item!!.itemId
|
||||
|
||||
when (id) {
|
||||
R.id.action_create_challenge -> {
|
||||
val intent = Intent(getActivity(), CreateChallengeActivity::class.java)
|
||||
startActivity(intent)
|
||||
return true
|
||||
}
|
||||
R.id.action_reload -> {
|
||||
fetchOnlineChallenges()
|
||||
return true
|
||||
}
|
||||
R.id.action_search -> {
|
||||
showFilterDialog()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ public class ChallengesOverviewFragment extends BaseMainFragment {
|
|||
|
||||
@Subscribe
|
||||
public void onEvent(ShowChallengeDetailDialogCommand cmd) {
|
||||
challengeRepository.getChallenge(cmd.challengeId).firstElement().subscribe(challenge -> ChallengeDetailDialogHolder.showDialog(getActivity(), challengeRepository, challenge,
|
||||
challengeRepository.getChallenge(cmd.challengeId).firstElement().subscribe(challenge -> ChallengeDetailDialogHolder.Companion.showDialog(getActivity(), challengeRepository, challenge,
|
||||
challenge1 -> {
|
||||
// challenge left
|
||||
}), RxErrorHandler.handleEmptyError());
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ public class PartyDetailFragment extends BaseFragment {
|
|||
return;
|
||||
}
|
||||
titleView.setText(party.getName());
|
||||
descriptionView.setText(MarkdownParser.parseMarkdown(party.getDescription()));
|
||||
//TODO: FIX
|
||||
//descriptionView.setText(MarkdownParser.parseMarkdown(party.getDescription()));
|
||||
|
||||
if (quest != null && !quest.getKey().isEmpty()) {
|
||||
newQuestButton.setVisibility(View.GONE);
|
||||
|
|
@ -216,8 +217,8 @@ public class PartyDetailFragment extends BaseFragment {
|
|||
@OnClick(R.id.new_quest_button)
|
||||
public void inviteNewQuest() {
|
||||
ItemRecyclerFragment fragment = new ItemRecyclerFragment();
|
||||
fragment.itemType = "quests";
|
||||
fragment.itemTypeText = getString(R.string.quest);
|
||||
fragment.setItemType("quests");
|
||||
fragment.setItemTypeText(getString(R.string.quest));
|
||||
fragment.show(getFragmentManager(), "questDialog");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.party;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.prefs.scanner.IntentIntegrator;
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class PartyInviteFragment extends BaseFragment {
|
||||
|
||||
public boolean isEmailInvite;
|
||||
|
||||
@BindView(R.id.inviteDescription)
|
||||
TextView inviteDescription;
|
||||
|
||||
@BindView(R.id.invitationWrapper)
|
||||
LinearLayout invitationWrapper;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View v = inflater.inflate(R.layout.fragment_party_invite, container, false);
|
||||
setUnbinder(ButterKnife.bind(this, v));
|
||||
|
||||
if (isEmailInvite) {
|
||||
inviteDescription.setText(getString(R.string.invite_email_description));
|
||||
} else {
|
||||
inviteDescription.setText(getString(R.string.invite_id_description));
|
||||
}
|
||||
|
||||
addInviteField();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectFragment(AppComponent component) {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
@OnClick(R.id.addInviteButton)
|
||||
public void addInviteField() {
|
||||
EditText editText = new EditText(getContext());
|
||||
|
||||
if (isEmailInvite) {
|
||||
editText.setHint(R.string.email);
|
||||
editText.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
} else {
|
||||
editText.setHint(R.string.user_id);
|
||||
}
|
||||
invitationWrapper.addView(editText);
|
||||
}
|
||||
|
||||
@OnClick(R.id.InviteByQR)
|
||||
public void startQRInvite() {
|
||||
IntentIntegrator scanIntegrator = new IntentIntegrator(getActivity());
|
||||
scanIntegrator.initiateScan();
|
||||
}
|
||||
|
||||
public String[] getValues() {
|
||||
List<String> values = new ArrayList<>();
|
||||
for (int i = 0; i < invitationWrapper.getChildCount(); i++) {
|
||||
EditText valueEditText = (EditText) invitationWrapper.getChildAt(i);
|
||||
if (valueEditText.getText().toString().length() > 0) {
|
||||
values.add(valueEditText.getText().toString());
|
||||
}
|
||||
}
|
||||
return values.toArray(new String[values.size()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.party
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.prefs.scanner.IntentIntegrator
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.resetViews
|
||||
import java.util.*
|
||||
|
||||
class PartyInviteFragment : BaseFragment() {
|
||||
|
||||
var isEmailInvite: Boolean = false
|
||||
|
||||
private val inviteDescription: TextView? by bindView(R.id.inviteDescription)
|
||||
private val invitationWrapper: LinearLayout? by bindView(R.id.invitationWrapper)
|
||||
private val addInviteButton: Button? by bindView(R.id.addInviteButton)
|
||||
private val inviteQRButton: Button? by bindView(R.id.InviteByQR)
|
||||
|
||||
val values: Array<String>
|
||||
get() {
|
||||
val values = ArrayList<String>()
|
||||
for (i in 0 until (invitationWrapper?.childCount ?: 0)) {
|
||||
val valueEditText = invitationWrapper?.getChildAt(i) as EditText
|
||||
if (valueEditText.text.toString().isNotEmpty()) {
|
||||
values.add(valueEditText.text.toString())
|
||||
}
|
||||
}
|
||||
return values.toTypedArray()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
super.onCreateView(inflater, container, savedInstanceState)
|
||||
return inflater.inflate(R.layout.fragment_party_invite, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
resetViews()
|
||||
|
||||
if (isEmailInvite) {
|
||||
inviteDescription?.text = getString(R.string.invite_email_description)
|
||||
} else {
|
||||
inviteDescription?.text = getString(R.string.invite_id_description)
|
||||
}
|
||||
|
||||
addInviteField()
|
||||
|
||||
addInviteButton?.setOnClickListener { addInviteField() }
|
||||
inviteQRButton?.setOnClickListener { startQRInvite() }
|
||||
}
|
||||
|
||||
override fun injectFragment(component: AppComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
||||
fun addInviteField() {
|
||||
val editText = EditText(context)
|
||||
|
||||
if (isEmailInvite) {
|
||||
editText.setHint(R.string.email)
|
||||
editText.inputType = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|
||||
} else {
|
||||
editText.setHint(R.string.user_id)
|
||||
}
|
||||
invitationWrapper?.addView(editText)
|
||||
}
|
||||
|
||||
fun startQRInvite() {
|
||||
val scanIntegrator = IntentIntegrator(activity)
|
||||
scanIntegrator.initiateScan()
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import com.habitrpg.android.habitica.components.AppComponent
|
|||
import com.habitrpg.android.habitica.data.TagRepository
|
||||
import com.habitrpg.android.habitica.events.TaskTappedEvent
|
||||
import com.habitrpg.android.habitica.events.commands.AddNewTaskCommand
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.helpers.TaskFilterHelper
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
|
|
@ -133,33 +134,37 @@ class TasksFragment : BaseMainFragment() {
|
|||
}
|
||||
|
||||
private fun showFilterDialog() {
|
||||
val dialog = TaskFilterDialog(context, HabiticaBaseApplication.getComponent())
|
||||
if (user != null) {
|
||||
dialog.setTags(user?.tags?.createSnapshot())
|
||||
}
|
||||
dialog.setActiveTags(taskFilterHelper.tags)
|
||||
if (activeFragment != null) {
|
||||
val taskType = activeFragment?.classType
|
||||
if (taskType != null) {
|
||||
dialog.setTaskType(taskType, taskFilterHelper.getActiveFilter(taskType))
|
||||
context.notNull {
|
||||
val dialog = TaskFilterDialog(it, HabiticaBaseApplication.getComponent())
|
||||
if (user != null) {
|
||||
dialog.setTags(user?.tags?.createSnapshot() ?: emptyList())
|
||||
}
|
||||
}
|
||||
dialog.setListener { activeTaskFilter, activeTags ->
|
||||
if (viewFragmentsDictionary == null) {
|
||||
return@setListener
|
||||
dialog.setActiveTags(taskFilterHelper.tags)
|
||||
if (activeFragment != null) {
|
||||
val taskType = activeFragment?.classType
|
||||
if (taskType != null) {
|
||||
dialog.setTaskType(taskType, taskFilterHelper.getActiveFilter(taskType))
|
||||
}
|
||||
}
|
||||
val activePos = viewPager?.currentItem ?: 0
|
||||
viewFragmentsDictionary?.get(activePos - 1)?.recyclerAdapter?.filter()
|
||||
viewFragmentsDictionary?.get(activePos + 1)?.recyclerAdapter?.filter()
|
||||
taskFilterHelper.tags = activeTags
|
||||
if (activeTaskFilter != null) {
|
||||
activeFragment?.setActiveFilter(activeTaskFilter)
|
||||
}
|
||||
viewFragmentsDictionary?.values?.forEach { it.recyclerAdapter?.filter() }
|
||||
updateFilterIcon()
|
||||
dialog.setListener(object : TaskFilterDialog.OnFilterCompletedListener {
|
||||
|
||||
override fun onFilterCompleted(activeTaskFilter: String?, activeTags: List<String>?) {
|
||||
if (viewFragmentsDictionary == null) {
|
||||
return
|
||||
}
|
||||
val activePos = viewPager?.currentItem ?: 0
|
||||
viewFragmentsDictionary?.get(activePos - 1)?.recyclerAdapter?.filter()
|
||||
viewFragmentsDictionary?.get(activePos + 1)?.recyclerAdapter?.filter()
|
||||
taskFilterHelper.tags = activeTags
|
||||
if (activeTaskFilter != null) {
|
||||
activeFragment?.setActiveFilter(activeTaskFilter)
|
||||
}
|
||||
viewFragmentsDictionary?.values?.forEach { it.recyclerAdapter?.filter() }
|
||||
updateFilterIcon()
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
package com.habitrpg.android.habitica.ui.helpers
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.support.annotation.ColorRes
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder
|
||||
import android.view.View
|
||||
import java.util.*
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
object ButterKnife {
|
||||
fun reset(target: Any) {
|
||||
LazyRegistry.reset(target)
|
||||
}
|
||||
}
|
||||
|
||||
fun <V : View> View.bindView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<View, V> = required(id, viewFinder)
|
||||
|
||||
fun <V : View> Activity.bindView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Activity, V> = required(id, viewFinder)
|
||||
|
||||
fun <V : View> Dialog.bindView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Dialog, V> = required(id, viewFinder)
|
||||
|
||||
fun <V : View> Fragment.bindView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Fragment, V> = required(id, viewFinder)
|
||||
|
||||
fun <V : View> ViewHolder.bindView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<ViewHolder, V> = required(id, viewFinder)
|
||||
|
||||
fun <V : View> View.bindOptionalView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<View, V?> = optional(id, viewFinder)
|
||||
|
||||
fun <V : View> Activity.bindOptionalView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Activity, V?> = optional(id, viewFinder)
|
||||
|
||||
fun <V : View> Dialog.bindOptionalView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Dialog, V?> = optional(id, viewFinder)
|
||||
|
||||
fun <V : View> Fragment.bindOptionalView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<Fragment, V?> = optional(id, viewFinder)
|
||||
|
||||
fun <V : View> ViewHolder.bindOptionalView(@IdRes id: Int)
|
||||
: ReadOnlyProperty<ViewHolder, V?> = optional(id, viewFinder)
|
||||
|
||||
|
||||
fun <V : View> bindView(container: View, @IdRes res: Int) : Lazy<V> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { container.findViewById<V>(res) }
|
||||
}
|
||||
|
||||
fun <V : View> bindOptionalView(container: View?, @IdRes res: Int) : Lazy<V?> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { container?.findViewById<V>(res) }
|
||||
}
|
||||
|
||||
fun bindColor(context: Context, @ColorRes res: Int) : Lazy<Int> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return lazy(LazyThreadSafetyMode.NONE) { ContextCompat.getColor(context, res) }
|
||||
}
|
||||
|
||||
fun Fragment.resetViews() {
|
||||
LazyRegistry.reset(this)
|
||||
}
|
||||
|
||||
|
||||
private val View.viewFinder: View.(Int) -> View?
|
||||
get() = { findViewById(it) }
|
||||
private val Activity.viewFinder: Activity.(Int) -> View?
|
||||
get() = { findViewById(it) }
|
||||
private val Dialog.viewFinder: Dialog.(Int) -> View?
|
||||
get() = { findViewById(it) }
|
||||
private val Fragment.viewFinder: Fragment.(Int) -> View?
|
||||
get() = { view?.findViewById(it) }
|
||||
private val ViewHolder.viewFinder: ViewHolder.(Int) -> View?
|
||||
get() = { itemView.findViewById(it) }
|
||||
|
||||
private fun viewNotFound(id: Int, desc: KProperty<*>): Nothing =
|
||||
throw IllegalStateException("View ID $id for '${desc.name}' not found.")
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T, V : View> required(id: Int, finder: T.(Int) -> View?)
|
||||
= TargetedLazy { t: T, desc -> t.finder(id) as V? ?: viewNotFound(id, desc) }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T, V : View> optional(id: Int, finder: T.(Int) -> View?)
|
||||
= TargetedLazy { t: T, desc -> t.finder(id) as V? }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T, V : View> required(ids: IntArray, finder: T.(Int) -> View?)
|
||||
= TargetedLazy { t: T, desc -> ids.map { t.finder(it) as V? ?: viewNotFound(it, desc) } }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T, V : View> optional(ids: IntArray, finder: T.(Int) -> View?)
|
||||
= TargetedLazy { t: T, desc -> ids.map { t.finder(it) as V? }.filterNotNull() }
|
||||
|
||||
// Like Kotlin's lazy delegate but the initializer gets the target and metadata passed to it
|
||||
private class TargetedLazy<T, V>(private val initializer: (T, KProperty<*>) -> V) : ReadOnlyProperty<T, V> {
|
||||
private object EMPTY
|
||||
|
||||
private var value: Any? = EMPTY
|
||||
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V {
|
||||
LazyRegistry.register(thisRef!!, this)
|
||||
if (value == EMPTY) {
|
||||
value = initializer(thisRef, property)
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return value as V
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
value = EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
private object LazyRegistry {
|
||||
private val lazyMap = WeakHashMap<Any, MutableCollection<TargetedLazy<*, *>>>()
|
||||
|
||||
fun register(target: Any, lazy: TargetedLazy<*, *>) {
|
||||
lazyMap.getOrPut(target) { Collections.newSetFromMap(WeakHashMap()) }.add(lazy)
|
||||
}
|
||||
|
||||
fun reset(target: Any) {
|
||||
lazyMap[target]?.forEach { it.reset() }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.helpers;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.Html;
|
||||
|
||||
import com.commonsware.cwac.anddown.AndDown;
|
||||
|
||||
import net.pherth.android.emoji_library.EmojiParser;
|
||||
|
||||
import static android.text.Html.FROM_HTML_MODE_LEGACY;
|
||||
|
||||
/**
|
||||
* @author data5tream
|
||||
*/
|
||||
public class MarkdownParser {
|
||||
|
||||
private static AndDown processor = new AndDown();
|
||||
|
||||
/**
|
||||
* Parses formatted markdown and returns it as styled CharSequence
|
||||
*
|
||||
* @param input Markdown formatted String
|
||||
* @return Stylized CharSequence
|
||||
*/
|
||||
public static CharSequence parseMarkdown(String input) {
|
||||
if (input == null) {
|
||||
return "";
|
||||
}
|
||||
CharSequence output;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
output = Html.fromHtml(processor.markdownToHtml(EmojiParser.parseEmojis(input.trim())), FROM_HTML_MODE_LEGACY);
|
||||
} else {
|
||||
output = Html.fromHtml(processor.markdownToHtml(EmojiParser.parseEmojis(input.trim())));
|
||||
}
|
||||
if (output.length() >= 2) output = output.subSequence(0, output.length() - 2);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts stylized CharSequence into markdown
|
||||
*
|
||||
* @param input Stylized CharSequence
|
||||
* @return Markdown formatted String
|
||||
*/
|
||||
@Nullable
|
||||
public static String parseCompiled(CharSequence input) {
|
||||
return EmojiParser.convertToCheatCode(input.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.habitrpg.android.habitica.ui.helpers
|
||||
|
||||
import android.text.Html
|
||||
|
||||
import com.commonsware.cwac.anddown.AndDown
|
||||
|
||||
import net.pherth.android.emoji_library.EmojiParser
|
||||
|
||||
import android.text.Html.FROM_HTML_MODE_LEGACY
|
||||
|
||||
/**
|
||||
* @author data5tream
|
||||
*/
|
||||
object MarkdownParser {
|
||||
|
||||
private val processor = AndDown()
|
||||
|
||||
/**
|
||||
* Parses formatted markdown and returns it as styled CharSequence
|
||||
*
|
||||
* @param input Markdown formatted String
|
||||
* @return Stylized CharSequence
|
||||
*/
|
||||
fun parseMarkdown(input: String?): CharSequence {
|
||||
if (input == null) {
|
||||
return ""
|
||||
}
|
||||
var output: CharSequence = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
Html.fromHtml(processor.markdownToHtml(EmojiParser.parseEmojis(input.trim { it <= ' ' })), FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
Html.fromHtml(processor.markdownToHtml(EmojiParser.parseEmojis(input.trim { it <= ' ' })))
|
||||
}
|
||||
if (output.length >= 2) output = output.subSequence(0, output.length - 2)
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts stylized CharSequence into markdown
|
||||
*
|
||||
* @param input Stylized CharSequence
|
||||
* @return Markdown formatted String
|
||||
*/
|
||||
fun parseCompiled(input: CharSequence): String? {
|
||||
return EmojiParser.convertToCheatCode(input.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import android.widget.Button
|
|||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
|
||||
class SectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import android.widget.TextView
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
import com.habitrpg.android.habitica.ui.views.CurrencyView
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ import android.widget.LinearLayout
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.TaskTappedEvent
|
||||
import com.habitrpg.android.habitica.extensions.bindColor
|
||||
import com.habitrpg.android.habitica.extensions.bindOptionalView
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindColor
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindOptionalView
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import org.greenrobot.eventbus.EventBus
|
|||
|
||||
import butterknife.BindView
|
||||
import butterknife.OnClick
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Consumer
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.ui.viewHolders.tasks
|
|||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
|
||||
class DailyViewHolder(itemView: View) : ChecklistedViewHolder(itemView) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import android.widget.TextView
|
|||
import butterknife.OnClick
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.HabitScoreEvent
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import butterknife.OnClick
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.TaskTappedEvent
|
||||
import com.habitrpg.android.habitica.events.commands.BuyRewardCommand
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.helpers.NumberAbbreviator
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.ItemDetailDialog
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import android.widget.ImageView
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.extensions.notNull
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
|
||||
class CollapsibleSectionView(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
|
||||
|
|
|
|||
|
|
@ -8,15 +8,15 @@ import android.view.View
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.layoutInflater
|
||||
|
||||
open class HabiticaAlertDialog(context: Context) : AlertDialog(context) {
|
||||
|
||||
private val view: LinearLayout = LayoutInflater.from(context).inflate(R.layout.dialog_habitica_base, null) as LinearLayout
|
||||
private val titleTextView: TextView by bindView(view, R.id.titleTextView)
|
||||
private val subtitleTextView: TextView by bindView(view, R.id.subtitleTextView)
|
||||
private val messageTextView: TextView by bindView(view, R.id.messageTextView)
|
||||
private val titleTextView: TextView by bindView(R.id.titleTextView)
|
||||
private val subtitleTextView: TextView by bindView(R.id.subtitleTextView)
|
||||
private val messageTextView: TextView by bindView(R.id.messageTextView)
|
||||
|
||||
private var additionalContentView: View? = null
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import android.view.View
|
|||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import android.widget.ImageView
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import android.widget.FrameLayout
|
|||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import java.text.NumberFormat
|
||||
|
||||
class ValueBar(context: Context?, attrs: AttributeSet?) : FrameLayout(context, attrs) {
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* Created by phillip on 27.09.17.
|
||||
*/
|
||||
|
||||
abstract public class InsufficientCurrencyDialog extends AlertDialog {
|
||||
|
||||
@BindView(R.id.imageView)
|
||||
ImageView imageView;
|
||||
@BindView(R.id.textView)
|
||||
TextView textView;
|
||||
|
||||
public InsufficientCurrencyDialog(Context context) {
|
||||
super(context);
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
View view = inflater.inflate(R.layout.dialog_insufficient_currency, null);
|
||||
ButterKnife.bind(this, view);
|
||||
setView(view);
|
||||
|
||||
this.setButton(AlertDialog.BUTTON_NEUTRAL, context.getString(R.string.close), (dialogInterface, i) -> {
|
||||
this.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
|
||||
/**
|
||||
* Created by phillip on 27.09.17.
|
||||
*/
|
||||
|
||||
abstract class InsufficientCurrencyDialog(context: Context) : AlertDialog(context) {
|
||||
|
||||
protected val imageView: ImageView by bindView(R.id.imageView)
|
||||
protected val textView: TextView by bindView(R.id.textView)
|
||||
|
||||
init {
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val view = inflater.inflate(R.layout.dialog_insufficient_currency, null)
|
||||
setView(view)
|
||||
|
||||
this.setButton(AlertDialog.BUTTON_NEUTRAL, context.getString(R.string.close)) { _, _ -> this.dismiss() }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Created by phillip on 27.09.17.
|
||||
*/
|
||||
|
||||
public class InsufficientGemsDialog extends InsufficientCurrencyDialog {
|
||||
|
||||
public InsufficientGemsDialog(Context context) {
|
||||
super(context);
|
||||
|
||||
imageView.setImageResource(R.drawable.gems_84);
|
||||
textView.setText(R.string.insufficientGems);
|
||||
|
||||
setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.purchase_gems), (dialogInterface, i) -> {
|
||||
EventBus.getDefault().post(new OpenGemPurchaseFragmentCommand());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand
|
||||
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
/**
|
||||
* Created by phillip on 27.09.17.
|
||||
*/
|
||||
|
||||
class InsufficientGemsDialog(context: Context) : InsufficientCurrencyDialog(context) {
|
||||
|
||||
init {
|
||||
|
||||
imageView.setImageResource(R.drawable.gems_84)
|
||||
textView.setText(R.string.insufficientGems)
|
||||
|
||||
setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.purchase_gems)) { _, _ -> EventBus.getDefault().post(OpenGemPurchaseFragmentCommand()) }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper;
|
||||
|
||||
public class InsufficientGoldDialog extends InsufficientCurrencyDialog {
|
||||
public InsufficientGoldDialog(Context context) {
|
||||
super(context);
|
||||
|
||||
imageView.setImageBitmap(HabiticaIconsHelper.imageOfGoldReward());
|
||||
textView.setText(context.getString(R.string.insufficientGold));
|
||||
setTitle(R.string.insufficientSubscriberGemsTitle);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
||||
class InsufficientGoldDialog(context: Context) : InsufficientCurrencyDialog(context) {
|
||||
init {
|
||||
|
||||
imageView.setImageBitmap(HabiticaIconsHelper.imageOfGoldReward())
|
||||
textView.text = context.getString(R.string.insufficientGold)
|
||||
setTitle(R.string.insufficientSubscriberGemsTitle)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand;
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
public class InsufficientHourglassesDialog extends InsufficientCurrencyDialog {
|
||||
public InsufficientHourglassesDialog(Context context) {
|
||||
super(context);
|
||||
|
||||
imageView.setImageBitmap(HabiticaIconsHelper.imageOfHourglassShop());
|
||||
textView.setText(R.string.insufficientHourglasses);
|
||||
|
||||
|
||||
setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.get_hourglasses), (dialogInterface, i) -> {
|
||||
EventBus.getDefault().post(new OpenGemPurchaseFragmentCommand());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.habitrpg.android.habitica.ui.views.insufficientCurrency
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v7.app.AlertDialog
|
||||
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class InsufficientHourglassesDialog(context: Context) : InsufficientCurrencyDialog(context) {
|
||||
init {
|
||||
|
||||
imageView.setImageBitmap(HabiticaIconsHelper.imageOfHourglassShop())
|
||||
textView.setText(R.string.insufficientHourglasses)
|
||||
|
||||
setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.get_hourglasses)) { _, _ -> EventBus.getDefault().post(OpenGemPurchaseFragmentCommand()) }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,151 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.login;
|
||||
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class LoginBackgroundView extends RelativeLayout {
|
||||
|
||||
private static float SIZE_FACTOR = 1.5f;
|
||||
private static int STAR_SIZE = 30;
|
||||
private static int STAR_OFFSET = 18;
|
||||
private final Random random;
|
||||
|
||||
@BindView(R.id.left_cloud_view)
|
||||
ImageView leftCloudView;
|
||||
@BindView(R.id.right_cloud_view)
|
||||
ImageView rightCloudView;
|
||||
|
||||
private List<StarView> starViews;
|
||||
private int width;
|
||||
private int height;
|
||||
private boolean didLayoutStars = false;
|
||||
private FrameLayout.LayoutParams params;
|
||||
|
||||
public LoginBackgroundView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.random = new Random();
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
windowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
height = (int) (metrics.heightPixels*SIZE_FACTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
ButterKnife.bind(this, this);
|
||||
starViews = new ArrayList<>();
|
||||
params = new FrameLayout.LayoutParams(0, 0);
|
||||
generateStars();
|
||||
animateClouds();
|
||||
}
|
||||
|
||||
private void animateClouds() {
|
||||
ValueAnimator leftAnimator = ObjectAnimator.ofFloat(leftCloudView, View.TRANSLATION_Y, 10.0f).setDuration(5000);
|
||||
leftAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||
leftAnimator.setRepeatMode(ValueAnimator.REVERSE);
|
||||
leftAnimator.start();
|
||||
ValueAnimator rightAnimator = ObjectAnimator.ofFloat(rightCloudView, View.TRANSLATION_Y, -10.0f).setDuration(8000);
|
||||
rightAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||
rightAnimator.setRepeatMode(ValueAnimator.REVERSE);
|
||||
rightAnimator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
this.width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
this.setMeasuredDimension(width, height);
|
||||
params.width = width;
|
||||
params.height = height;
|
||||
this.setLayoutParams(params);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
updateStarLayoutParams();
|
||||
}
|
||||
|
||||
public void generateStars() {
|
||||
generateStars(1, 12, 25);
|
||||
}
|
||||
|
||||
private void generateStars(int largeCount, int mediumCount, int smallCount) {
|
||||
removeStarViews();
|
||||
for (int x = 0; x < largeCount; x++) {
|
||||
generateStar(2);
|
||||
}
|
||||
for (int x = 0; x < mediumCount; x++) {
|
||||
generateStar(1);
|
||||
}
|
||||
for (int x = 0; x < smallCount; x++) {
|
||||
generateStar(0);
|
||||
}
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
private void removeStarViews() {
|
||||
if (starViews.size() > 0) {
|
||||
starViews.forEach(this::removeView);
|
||||
starViews.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateStar(int size) {
|
||||
StarView starView = new StarView(getContext()
|
||||
);
|
||||
starView.setStarSize(size);
|
||||
if (random.nextInt(10) > 2) {
|
||||
starView.setBlinkDurations(Arrays.asList(getBlinkDuration(), getBlinkDuration(), getBlinkDuration()));
|
||||
}
|
||||
starViews.add(starView);
|
||||
if (width > 0 && height > 0) {
|
||||
this.addView(starView, 0, getStarParams());
|
||||
} else {
|
||||
this.addView(starView, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int getBlinkDuration() {
|
||||
return random.nextInt(30)*800+4;
|
||||
}
|
||||
|
||||
private void updateStarLayoutParams() {
|
||||
if (width <= 0 || height <= 0 || didLayoutStars || starViews.size() == 0) {
|
||||
return;
|
||||
}
|
||||
for (StarView view : starViews) {
|
||||
view.setLayoutParams(getStarParams());
|
||||
}
|
||||
didLayoutStars = true;
|
||||
}
|
||||
|
||||
private RelativeLayout.LayoutParams getStarParams() {
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(STAR_SIZE, STAR_SIZE);
|
||||
params.leftMargin = random.nextInt(width);
|
||||
params.topMargin = random.nextInt(height);
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
package com.habitrpg.android.habitica.ui.views.login
|
||||
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import java.util.*
|
||||
|
||||
class LoginBackgroundView(context: Context, attrs: AttributeSet?) : RelativeLayout(context, attrs) {
|
||||
private val random: Random = Random()
|
||||
|
||||
private val leftCloudView: ImageView by bindView(R.id.left_cloud_view)
|
||||
private val rightCloudView: ImageView by bindView(R.id.right_cloud_view)
|
||||
|
||||
private var starViews: MutableList<StarView>? = null
|
||||
private var viewWidth: Int = 0
|
||||
private val viewHeight: Int
|
||||
private var didLayoutStars = false
|
||||
private var params = FrameLayout.LayoutParams(0, 0)
|
||||
|
||||
private val blinkDuration: Int
|
||||
get() = random.nextInt(30) * 800 + 4
|
||||
|
||||
private val starParams: RelativeLayout.LayoutParams
|
||||
get() {
|
||||
val params = RelativeLayout.LayoutParams(STAR_SIZE, STAR_SIZE)
|
||||
params.leftMargin = random.nextInt(viewWidth)
|
||||
params.topMargin = random.nextInt(viewHeight)
|
||||
return params
|
||||
}
|
||||
|
||||
init {
|
||||
val metrics = DisplayMetrics()
|
||||
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
windowManager.defaultDisplay.getMetrics(metrics)
|
||||
viewHeight = (metrics.heightPixels * SIZE_FACTOR).toInt()
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
starViews = ArrayList()
|
||||
generateStars()
|
||||
animateClouds()
|
||||
}
|
||||
|
||||
private fun animateClouds() {
|
||||
val leftAnimator = ObjectAnimator.ofFloat(leftCloudView, View.TRANSLATION_Y, 10.0f).setDuration(5000)
|
||||
leftAnimator.repeatCount = ValueAnimator.INFINITE
|
||||
leftAnimator.repeatMode = ValueAnimator.REVERSE
|
||||
leftAnimator.start()
|
||||
val rightAnimator = ObjectAnimator.ofFloat(rightCloudView, View.TRANSLATION_Y, -10.0f).setDuration(8000)
|
||||
rightAnimator.repeatCount = ValueAnimator.INFINITE
|
||||
rightAnimator.repeatMode = ValueAnimator.REVERSE
|
||||
rightAnimator.start()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
this.viewWidth = View.MeasureSpec.getSize(widthMeasureSpec)
|
||||
this.setMeasuredDimension(viewWidth, viewHeight)
|
||||
params.width = viewWidth
|
||||
params.height = viewHeight
|
||||
this.layoutParams = params
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
}
|
||||
|
||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||
super.onLayout(changed, l, t, r, b)
|
||||
updateStarLayoutParams()
|
||||
}
|
||||
|
||||
private fun generateStars() {
|
||||
generateStars(1, 12, 25)
|
||||
}
|
||||
|
||||
private fun generateStars(largeCount: Int, mediumCount: Int, smallCount: Int) {
|
||||
removeStarViews()
|
||||
for (x in 0 until largeCount) {
|
||||
generateStar(2)
|
||||
}
|
||||
for (x in 0 until mediumCount) {
|
||||
generateStar(1)
|
||||
}
|
||||
for (x in 0 until smallCount) {
|
||||
generateStar(0)
|
||||
}
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
private fun removeStarViews() {
|
||||
if (starViews?.size ?: 0 > 0) {
|
||||
starViews?.forEach { this.removeView(it) }
|
||||
starViews?.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateStar(size: Int) {
|
||||
val starView = StarView(context)
|
||||
starView.setStarSize(size)
|
||||
if (random.nextInt(10) > 2) {
|
||||
starView.setBlinkDurations(Arrays.asList(blinkDuration, blinkDuration, blinkDuration))
|
||||
}
|
||||
starViews?.add(starView)
|
||||
if (viewWidth > 0 && viewHeight > 0) {
|
||||
this.addView(starView, 0, starParams)
|
||||
} else {
|
||||
this.addView(starView, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateStarLayoutParams() {
|
||||
if (viewWidth <= 0 ||viewHeight <= 0 || didLayoutStars || starViews?.size == 0) {
|
||||
return
|
||||
}
|
||||
for (view in starViews ?: emptyList<StarView>()) {
|
||||
view.layoutParams = starParams
|
||||
}
|
||||
didLayoutStars = true
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val SIZE_FACTOR = 1.5f
|
||||
private const val STAR_SIZE = 30
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import android.support.v4.content.ContextCompat
|
|||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import butterknife.ButterKnife
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.setup;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public class AvatarCategoryView extends LinearLayout {
|
||||
|
||||
private final Drawable icon;
|
||||
@BindView(R.id.text_view)
|
||||
TextView textView;
|
||||
|
||||
public AvatarCategoryView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
inflate(context, R.layout.avatar_category, this);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.AvatarCategoryView,
|
||||
0, 0);
|
||||
|
||||
textView.setText(a.getText(R.styleable.AvatarCategoryView_categoryTitle));
|
||||
|
||||
icon = a.getDrawable(R.styleable.AvatarCategoryView_iconDrawable);
|
||||
if (icon != null) {
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
|
||||
}
|
||||
setActive(false);
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
int color;
|
||||
if (active) {
|
||||
color = ContextCompat.getColor(getContext(), R.color.white);
|
||||
} else {
|
||||
color = ContextCompat.getColor(getContext(), R.color.white_50_alpha);
|
||||
}
|
||||
textView.setTextColor(color);
|
||||
if (icon != null) {
|
||||
icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.habitrpg.android.habitica.ui.views.setup
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
|
||||
class AvatarCategoryView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
|
||||
|
||||
private val icon: Drawable?
|
||||
private val textView: TextView by bindView(R.id.text_view)
|
||||
|
||||
init {
|
||||
View.inflate(context, R.layout.avatar_category, this)
|
||||
|
||||
val a = context.theme.obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.AvatarCategoryView,
|
||||
0, 0)
|
||||
|
||||
textView.text = a.getText(R.styleable.AvatarCategoryView_categoryTitle)
|
||||
|
||||
icon = a.getDrawable(R.styleable.AvatarCategoryView_iconDrawable)
|
||||
if (icon != null) {
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null)
|
||||
}
|
||||
setActive(false)
|
||||
}
|
||||
|
||||
fun setActive(active: Boolean) {
|
||||
val color: Int = if (active) {
|
||||
ContextCompat.getColor(context, R.color.white)
|
||||
} else {
|
||||
ContextCompat.getColor(context, R.color.white_50_alpha)
|
||||
}
|
||||
textView.setTextColor(color)
|
||||
if (icon != null) {
|
||||
icon.setColorFilter(color, PorterDuff.Mode.MULTIPLY)
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import com.habitrpg.android.habitica.data.UserRepository
|
|||
import com.habitrpg.android.habitica.events.GearPurchasedEvent
|
||||
import com.habitrpg.android.habitica.events.ShowSnackbarEvent
|
||||
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.helpers.RemoteConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import android.widget.LinearLayout
|
|||
import android.widget.TextView
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import android.support.v4.content.ContextCompat
|
|||
import android.util.AttributeSet
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.inventory.Equipment
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.ui.views.shops
|
|||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
|
||||
internal class PurchaseDialogGemsContent(context: Context) : PurchaseDialogContent(context) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
|||
import android.util.AttributeSet
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
|
||||
class PurchaseDialogItemContent : PurchaseDialogContent {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import android.widget.RatingBar
|
|||
import android.widget.TextView
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestDropItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ import android.util.AttributeSet
|
|||
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 butterknife.ButterKnife
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.setScaledPadding
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestProgress
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import android.widget.TextView
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import android.widget.TextView
|
|||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.backgroundCompat
|
||||
import com.habitrpg.android.habitica.extensions.bindView
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
|
|
|
|||
|
|
@ -1,133 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.subscriptions;
|
||||
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.BuildConfig;
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.models.user.SubscriptionPlan;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class SubscriptionDetailsView extends LinearLayout {
|
||||
|
||||
@BindView(R.id.subscriptionDurationTextView)
|
||||
TextView subscriptionDurationTextView;
|
||||
|
||||
@BindView(R.id.subscriptionStatusActive)
|
||||
TextView subscriptionStatusActive;
|
||||
@BindView(R.id.subscriptionStatusInactive)
|
||||
TextView getSubscriptionStatusInactive;
|
||||
|
||||
@BindView(R.id.paymentProcessorTextView)
|
||||
TextView paymentProcessorTextView;
|
||||
|
||||
@BindView(R.id.monthsSubscribedTextView)
|
||||
TextView monthsSubscribedTextView;
|
||||
|
||||
@BindView(R.id.gemCapTextView)
|
||||
TextView gemCapTextView;
|
||||
|
||||
@BindView(R.id.currentHourglassesTextView)
|
||||
TextView currentHourglassesTextView;
|
||||
|
||||
@BindView(R.id.cancelSubscriptionDescription)
|
||||
TextView cancelSubscripnDescription;
|
||||
|
||||
@BindView(R.id.visitWebsiteButton)
|
||||
Button visitWebsiteButton;
|
||||
|
||||
private SubscriptionPlan plan;
|
||||
|
||||
public SubscriptionDetailsView(Context context, AttributeSet attributeSet) {
|
||||
super(context, attributeSet);
|
||||
setupView();
|
||||
}
|
||||
|
||||
public SubscriptionDetailsView(Context context) {
|
||||
super(context);
|
||||
setupView();
|
||||
}
|
||||
|
||||
private void setupView() {
|
||||
inflate(getContext(), R.layout.subscription_details, this);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
}
|
||||
|
||||
public void setPlan(SubscriptionPlan plan) {
|
||||
this.plan = plan;
|
||||
|
||||
if (plan.isActive()) {
|
||||
subscriptionStatusActive.setVisibility(View.VISIBLE);
|
||||
getSubscriptionStatusInactive.setVisibility(View.GONE);
|
||||
} else {
|
||||
subscriptionStatusActive.setVisibility(View.GONE);
|
||||
getSubscriptionStatusInactive.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
String duration = null;
|
||||
|
||||
if (plan.planId != null) {
|
||||
if (plan.planId.equals(SubscriptionPlan.PLANID_BASIC) || plan.planId.equals(SubscriptionPlan.PLANID_BASICEARNED)) {
|
||||
duration = getResources().getString(R.string.month);
|
||||
} else if (plan.planId.equals(SubscriptionPlan.PLANID_BASIC3MONTH)) {
|
||||
duration = getResources().getString(R.string.three_months);
|
||||
} else if (plan.planId.equals(SubscriptionPlan.PLANID_BASIC6MONTH) || plan.planId.equals(SubscriptionPlan.PLANID_GOOGLE6MONTH)) {
|
||||
duration = getResources().getString(R.string.six_months);
|
||||
} else if (plan.planId.equals(SubscriptionPlan.PLANID_BASIC12MONTH)) {
|
||||
duration = getResources().getString(R.string.twelve_months);
|
||||
}
|
||||
}
|
||||
|
||||
if (duration != null) {
|
||||
subscriptionDurationTextView.setText(getResources().getString(R.string.subscription_duration, duration));
|
||||
}
|
||||
|
||||
paymentProcessorTextView.setText(plan.paymentMethod);
|
||||
|
||||
if (plan.consecutive.getCount() == 1) {
|
||||
monthsSubscribedTextView.setText(getResources().getString(R.string.one_month));
|
||||
} else {
|
||||
monthsSubscribedTextView.setText(getResources().getString(R.string.months, plan.consecutive.getCount()));
|
||||
}
|
||||
gemCapTextView.setText(String.valueOf(plan.consecutive.getGemCapExtra() + 25));
|
||||
currentHourglassesTextView.setText(String.valueOf(plan.consecutive.getTrinkets()));
|
||||
|
||||
if (plan.paymentMethod != null) {
|
||||
if (plan.paymentMethod.equals("Google")) {
|
||||
cancelSubscripnDescription.setText(R.string.cancel_subscription_google_description);
|
||||
visitWebsiteButton.setText(R.string.open_in_store);
|
||||
} else {
|
||||
cancelSubscripnDescription.setText(R.string.cancel_subscription_notgoogle_description);
|
||||
visitWebsiteButton.setText(R.string.visit_habitica_website);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.visitWebsiteButton)
|
||||
public void openSubscriptionWebsite() {
|
||||
if (plan.paymentMethod != null) {
|
||||
Intent intent;
|
||||
if (plan.paymentMethod.equals("Google")) {
|
||||
intent = new Intent(Intent.ACTION_VIEW)
|
||||
.setComponent(new ComponentName("com.android.vending",
|
||||
"com.google.android.finsky.activities.MainActivity"))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
} else {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.BASE_URL + "/"));
|
||||
}
|
||||
getContext().startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.habitrpg.android.habitica.ui.views.subscriptions
|
||||
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import butterknife.OnClick
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.user.SubscriptionPlan
|
||||
|
||||
class SubscriptionDetailsView : LinearLayout {
|
||||
|
||||
internal val subscriptionDurationTextView: TextView by bindView(R.id.subscriptionDurationTextView)
|
||||
internal val subscriptionStatusActive: TextView by bindView(R.id.subscriptionStatusActive)
|
||||
private val getSubscriptionStatusInactive: TextView by bindView(R.id.subscriptionStatusInactive)
|
||||
internal val paymentProcessorTextView: TextView by bindView(R.id.paymentProcessorTextView)
|
||||
internal val monthsSubscribedTextView: TextView by bindView(R.id.monthsSubscribedTextView)
|
||||
internal val gemCapTextView: TextView by bindView(R.id.gemCapTextView)
|
||||
internal val currentHourglassesTextView: TextView by bindView(R.id.currentHourglassesTextView)
|
||||
private val cancelSubscripnDescription: TextView by bindView(R.id.cancelSubscriptionDescription)
|
||||
internal val visitWebsiteButton: Button by bindView(R.id.visitWebsiteButton)
|
||||
|
||||
private var plan: SubscriptionPlan? = null
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
|
||||
setupView()
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
setupView()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
inflate(R.layout.subscription_details)
|
||||
}
|
||||
|
||||
fun setPlan(plan: SubscriptionPlan) {
|
||||
this.plan = plan
|
||||
|
||||
if (plan.isActive) {
|
||||
subscriptionStatusActive.visibility = View.VISIBLE
|
||||
getSubscriptionStatusInactive.visibility = View.GONE
|
||||
} else {
|
||||
subscriptionStatusActive.visibility = View.GONE
|
||||
getSubscriptionStatusInactive.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
var duration: String? = null
|
||||
|
||||
if (plan.planId != null) {
|
||||
if (plan.planId == SubscriptionPlan.PLANID_BASIC || plan.planId == SubscriptionPlan.PLANID_BASICEARNED) {
|
||||
duration = resources.getString(R.string.month)
|
||||
} else if (plan.planId == SubscriptionPlan.PLANID_BASIC3MONTH) {
|
||||
duration = resources.getString(R.string.three_months)
|
||||
} else if (plan.planId == SubscriptionPlan.PLANID_BASIC6MONTH || plan.planId == SubscriptionPlan.PLANID_GOOGLE6MONTH) {
|
||||
duration = resources.getString(R.string.six_months)
|
||||
} else if (plan.planId == SubscriptionPlan.PLANID_BASIC12MONTH) {
|
||||
duration = resources.getString(R.string.twelve_months)
|
||||
}
|
||||
}
|
||||
|
||||
if (duration != null) {
|
||||
subscriptionDurationTextView.text = resources.getString(R.string.subscription_duration, duration)
|
||||
}
|
||||
|
||||
paymentProcessorTextView.text = plan.paymentMethod
|
||||
|
||||
if (plan.consecutive.count == 1) {
|
||||
monthsSubscribedTextView.text = resources.getString(R.string.one_month)
|
||||
} else {
|
||||
monthsSubscribedTextView.text = resources.getString(R.string.months, plan.consecutive.count)
|
||||
}
|
||||
gemCapTextView.text = (plan.consecutive.gemCapExtra + 25).toString()
|
||||
currentHourglassesTextView.text = plan.consecutive.trinkets.toString()
|
||||
|
||||
if (plan.paymentMethod != null) {
|
||||
if (plan.paymentMethod == "Google") {
|
||||
cancelSubscripnDescription.setText(R.string.cancel_subscription_google_description)
|
||||
visitWebsiteButton.setText(R.string.open_in_store)
|
||||
} else {
|
||||
cancelSubscripnDescription.setText(R.string.cancel_subscription_notgoogle_description)
|
||||
visitWebsiteButton.setText(R.string.visit_habitica_website)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.visitWebsiteButton)
|
||||
fun openSubscriptionWebsite() {
|
||||
if (plan?.paymentMethod != null) {
|
||||
val intent: Intent = if (plan?.paymentMethod == "Google") {
|
||||
Intent(Intent.ACTION_VIEW)
|
||||
.setComponent(ComponentName("com.android.vending",
|
||||
"com.google.android.finsky.activities.MainActivity"))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
} else {
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.BASE_URL + "/"))
|
||||
}
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.subscriptions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
|
||||
public class SubscriptionOptionView extends FrameLayout {
|
||||
|
||||
@BindView(R.id.priceLabel)
|
||||
TextView priceTextView;
|
||||
|
||||
@BindView(R.id.descriptionTextView)
|
||||
TextView descriptionTextView;
|
||||
|
||||
@BindView(R.id.subscriptionSelectedView)
|
||||
View subscriptionSelectedView;
|
||||
|
||||
@BindView(R.id.subscriptionSelectedFrameView)
|
||||
View subscriptionSelectedFrameView;
|
||||
|
||||
@BindView(R.id.gemCapTextView)
|
||||
TextView gemCapTextView;
|
||||
|
||||
@BindView(R.id.hourglassTextView)
|
||||
TextView hourGlassTextView;
|
||||
|
||||
private String sku;
|
||||
|
||||
public SubscriptionOptionView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
inflate(context, R.layout.purchase_subscription_view, this);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.SubscriptionOptionView,
|
||||
0, 0);
|
||||
|
||||
descriptionTextView.setText(context.getString(R.string.subscription_duration, a.getText(R.styleable.SubscriptionOptionView_recurringText)));
|
||||
|
||||
gemCapTextView.setText(a.getText(R.styleable.SubscriptionOptionView_gemCapText));
|
||||
Integer hourGlassCount = a.getInteger(R.styleable.SubscriptionOptionView_hourGlassCount, 0);
|
||||
if (hourGlassCount != 0) {
|
||||
hourGlassTextView.setText(context.getString(R.string.subscription_hourglasses, hourGlassCount));
|
||||
hourGlassTextView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
hourGlassTextView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setOnPurchaseClickListener(Button.OnClickListener listener) {
|
||||
this.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
public void setPriceText(String text) {
|
||||
this.priceTextView.setText(text);
|
||||
}
|
||||
|
||||
public String getSku() {
|
||||
return sku;
|
||||
}
|
||||
|
||||
public void setSku(String sku) {
|
||||
this.sku = sku;
|
||||
}
|
||||
|
||||
public void setIsPurchased(boolean purchased) {
|
||||
int horizontalPadding = (int) getResources().getDimension(R.dimen.pill_horizontal_padding);
|
||||
int verticalPadding = (int) getResources().getDimension(R.dimen.pill_vertical_padding);
|
||||
if (purchased) {
|
||||
subscriptionSelectedView.setBackgroundResource(R.drawable.subscription_selected);
|
||||
subscriptionSelectedFrameView.setBackgroundResource(R.color.brand_300);
|
||||
gemCapTextView.setBackgroundResource(R.drawable.pill_bg_green);
|
||||
gemCapTextView.setTextColor(getContext().getResources().getColor(R.color.white));
|
||||
gemCapTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||
hourGlassTextView.setBackgroundResource(R.drawable.pill_bg_green);
|
||||
hourGlassTextView.setTextColor(getContext().getResources().getColor(R.color.white));
|
||||
hourGlassTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||
} else {
|
||||
subscriptionSelectedView.setBackgroundResource(R.drawable.subscription_unselected);
|
||||
subscriptionSelectedFrameView.setBackgroundResource(R.color.brand_700);
|
||||
gemCapTextView.setBackgroundResource(R.drawable.pill_bg);
|
||||
gemCapTextView.setTextColor(getContext().getResources().getColor(R.color.text_light));
|
||||
gemCapTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||
hourGlassTextView.setBackgroundResource(R.drawable.pill_bg);
|
||||
hourGlassTextView.setTextColor(getContext().getResources().getColor(R.color.text_light));
|
||||
hourGlassTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.habitrpg.android.habitica.ui.views.subscriptions
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
|
||||
|
||||
class SubscriptionOptionView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {
|
||||
|
||||
private val priceTextView: TextView by bindView(R.id.priceLabel)
|
||||
internal val descriptionTextView: TextView by bindView(R.id.descriptionTextView)
|
||||
internal val subscriptionSelectedView: View by bindView(R.id.subscriptionSelectedView)
|
||||
internal val subscriptionSelectedFrameView: View by bindView(R.id.subscriptionSelectedFrameView)
|
||||
internal val gemCapTextView: TextView by bindView(R.id.gemCapTextView)
|
||||
private val hourGlassTextView: TextView by bindView(R.id.hourglassTextView)
|
||||
|
||||
var sku: String? = null
|
||||
|
||||
init {
|
||||
inflate(R.layout.purchase_subscription_view)
|
||||
|
||||
val a = context.theme.obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.SubscriptionOptionView,
|
||||
0, 0)
|
||||
|
||||
descriptionTextView.text = context.getString(R.string.subscription_duration, a.getText(R.styleable.SubscriptionOptionView_recurringText))
|
||||
|
||||
gemCapTextView.text = a.getText(R.styleable.SubscriptionOptionView_gemCapText)
|
||||
val hourGlassCount = a.getInteger(R.styleable.SubscriptionOptionView_hourGlassCount, 0)
|
||||
if (hourGlassCount != 0) {
|
||||
hourGlassTextView.text = context.getString(R.string.subscription_hourglasses, hourGlassCount)
|
||||
hourGlassTextView.visibility = View.VISIBLE
|
||||
} else {
|
||||
hourGlassTextView.visibility = View.GONE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun setOnPurchaseClickListener(listener: OnClickListener) {
|
||||
this.setOnClickListener(listener)
|
||||
}
|
||||
|
||||
fun setPriceText(text: String) {
|
||||
this.priceTextView.text = text
|
||||
}
|
||||
|
||||
fun setIsPurchased(purchased: Boolean) {
|
||||
val horizontalPadding = resources.getDimension(R.dimen.pill_horizontal_padding).toInt()
|
||||
val verticalPadding = resources.getDimension(R.dimen.pill_vertical_padding).toInt()
|
||||
if (purchased) {
|
||||
subscriptionSelectedView.setBackgroundResource(R.drawable.subscription_selected)
|
||||
subscriptionSelectedFrameView.setBackgroundResource(R.color.brand_300)
|
||||
gemCapTextView.setBackgroundResource(R.drawable.pill_bg_green)
|
||||
gemCapTextView.setTextColor(context.resources.getColor(R.color.white))
|
||||
gemCapTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
|
||||
hourGlassTextView.setBackgroundResource(R.drawable.pill_bg_green)
|
||||
hourGlassTextView.setTextColor(context.resources.getColor(R.color.white))
|
||||
hourGlassTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
|
||||
} else {
|
||||
subscriptionSelectedView.setBackgroundResource(R.drawable.subscription_unselected)
|
||||
subscriptionSelectedFrameView.setBackgroundResource(R.color.brand_700)
|
||||
gemCapTextView.setBackgroundResource(R.drawable.pill_bg)
|
||||
gemCapTextView.setTextColor(context.resources.getColor(R.color.text_light))
|
||||
gemCapTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
|
||||
hourGlassTextView.setBackgroundResource(R.drawable.pill_bg)
|
||||
hourGlassTextView.setTextColor(context.resources.getColor(R.color.text_light))
|
||||
hourGlassTextView.setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,434 +0,0 @@
|
|||
package com.habitrpg.android.habitica.ui.views.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.CompoundButtonCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.AppCompatCheckBox;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.habitrpg.android.habitica.R;
|
||||
import com.habitrpg.android.habitica.components.AppComponent;
|
||||
import com.habitrpg.android.habitica.data.TagRepository;
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
|
||||
import com.habitrpg.android.habitica.models.Tag;
|
||||
import com.habitrpg.android.habitica.models.tasks.Task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.functions.Function;
|
||||
|
||||
public class TaskFilterDialog extends AlertDialog implements RadioGroup.OnCheckedChangeListener {
|
||||
|
||||
@Inject
|
||||
TagRepository repository;
|
||||
|
||||
@BindView(R.id.task_type_title)
|
||||
TextView taskTypeTitle;
|
||||
|
||||
@BindView(R.id.task_filter_wrapper)
|
||||
RadioGroup taskFilters;
|
||||
@BindView(R.id.all_task_filter)
|
||||
RadioButton allTaskFilter;
|
||||
@BindView(R.id.second_task_filter)
|
||||
RadioButton secondTaskFilter;
|
||||
@BindView(R.id.third_task_filter)
|
||||
RadioButton thirdTaskFilter;
|
||||
|
||||
@BindView(R.id.tags_title)
|
||||
TextView tagsTitleView;
|
||||
@BindView(R.id.tag_edit_button)
|
||||
Button tagsEditButton;
|
||||
@BindView(R.id.tags_list)
|
||||
LinearLayout tagsList;
|
||||
private String taskType;
|
||||
private OnFilterCompletedListener listener;
|
||||
|
||||
private String filterType;
|
||||
private List<Tag> tags;
|
||||
private List<String> activeTags;
|
||||
private Map<String, Tag> editedTags = new HashMap<>();
|
||||
private Map<String, Tag> createdTags = new HashMap<>();
|
||||
private List<String> deletedTags = new ArrayList<>();
|
||||
|
||||
private Drawable addIcon;
|
||||
private boolean isEditing;
|
||||
|
||||
public TaskFilterDialog(Context context, AppComponent component) {
|
||||
super(context);
|
||||
component.inject(this);
|
||||
addIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_purple_300_36dp);
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
View view = inflater.inflate(R.layout.dialog_task_filter, null);
|
||||
|
||||
ButterKnife.bind(this, view);
|
||||
|
||||
taskFilters.setOnCheckedChangeListener(this);
|
||||
|
||||
setTitle(R.string.filters);
|
||||
setView(view);
|
||||
this.setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.done), (dialog, which) -> {
|
||||
if (isEditing) {
|
||||
stopEditing();
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onFilterCompleted(filterType, activeTags);
|
||||
}
|
||||
this.dismiss();
|
||||
});
|
||||
|
||||
setButton(AlertDialog.BUTTON_NEUTRAL, getContext().getString(R.string.clear), (dialog, which) -> {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Button clearButton = getButton(AlertDialog.BUTTON_NEUTRAL);
|
||||
if (clearButton != null) {
|
||||
clearButton.setOnClickListener(view1 -> {
|
||||
if (isEditing) {
|
||||
stopEditing();
|
||||
}
|
||||
setActiveFilter(null);
|
||||
setActiveTags(null);
|
||||
});
|
||||
clearButton.setEnabled(hasActiveFilters());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
super.show();
|
||||
if (this.getWindow() != null) {
|
||||
this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTags(List<Tag> tags) {
|
||||
this.tags = repository.getUnmanagedCopy(tags);
|
||||
createTagViews();
|
||||
}
|
||||
|
||||
private void createTagViews() {
|
||||
ColorStateList colorStateList = new ColorStateList(
|
||||
new int[][]{
|
||||
new int[]{-android.R.attr.state_checked}, //disabled
|
||||
new int[]{android.R.attr.state_checked} //enabled
|
||||
},
|
||||
new int[] {
|
||||
Color.LTGRAY, //disabled
|
||||
ContextCompat.getColor(getContext(), R.color.brand_400) //enabled
|
||||
}
|
||||
);
|
||||
int leftPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, getContext().getResources().getDisplayMetrics());
|
||||
int verticalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getContext().getResources().getDisplayMetrics());
|
||||
for (Tag tag : tags) {
|
||||
AppCompatCheckBox tagCheckbox = new AppCompatCheckBox(getContext());
|
||||
tagCheckbox.setText(tag.getName());
|
||||
tagCheckbox.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
|
||||
tagCheckbox.setPadding(tagCheckbox.getPaddingLeft()+ leftPadding,
|
||||
verticalPadding,
|
||||
tagCheckbox.getPaddingRight(),
|
||||
verticalPadding);
|
||||
tagCheckbox.setTextColor(ContextCompat.getColor(getContext(), R.color.textColorLight));
|
||||
CompoundButtonCompat.setButtonTintList(tagCheckbox, colorStateList);
|
||||
tagCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
if (!activeTags.contains(tag.getId())) {
|
||||
activeTags.add(tag.getId());
|
||||
}
|
||||
} else {
|
||||
if (activeTags.contains(tag.getId())) {
|
||||
activeTags.remove(tag.getId());
|
||||
}
|
||||
}
|
||||
filtersChanged();
|
||||
});
|
||||
tagsList.addView(tagCheckbox);
|
||||
}
|
||||
createAddTagButton();
|
||||
}
|
||||
|
||||
private void createAddTagButton() {
|
||||
Button button = new Button(getContext());
|
||||
button.setText(R.string.add_tag);
|
||||
button.setOnClickListener(v -> createTag());
|
||||
button.setCompoundDrawablesWithIntrinsicBounds(addIcon, null, null, null);
|
||||
button.setBackgroundResource(R.drawable.layout_rounded_bg_lighter_gray);
|
||||
button.setTextColor(ContextCompat.getColor(getContext(), R.color.text_light));
|
||||
tagsList.addView(button);
|
||||
}
|
||||
|
||||
private void createTag() {
|
||||
Tag tag = new Tag();
|
||||
tag.id = UUID.randomUUID().toString();
|
||||
tags.add(tag);
|
||||
createdTags.put(tag.getId(), tag);
|
||||
startEditing();
|
||||
}
|
||||
|
||||
private void startEditing() {
|
||||
isEditing = true;
|
||||
tagsList.removeAllViews();
|
||||
createTagEditViews();
|
||||
tagsEditButton.setText(R.string.done);
|
||||
if (this.getWindow() != null) {
|
||||
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopEditing() {
|
||||
isEditing = false;
|
||||
tagsList.removeAllViews();
|
||||
createTagViews();
|
||||
tagsEditButton.setText(R.string.edit_tag_btn_edit);
|
||||
if (this.getWindow() != null) {
|
||||
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||
}
|
||||
repository.updateTags(editedTags.values()).toObservable() .flatMap(tags -> Observable.fromIterable(tags)).subscribe(tag -> editedTags.remove(tag.id), RxErrorHandler.handleEmptyError());
|
||||
repository.createTags(createdTags.values()).toObservable() .flatMap(tags -> Observable.fromIterable(tags)).subscribe(tag -> createdTags.remove(tag.getId()), RxErrorHandler.handleEmptyError());
|
||||
repository.deleteTags(deletedTags).subscribe(tags1 -> deletedTags.clear(), RxErrorHandler.handleEmptyError());
|
||||
}
|
||||
|
||||
private void createTagEditViews() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
if (tags != null) {
|
||||
for (int index = 0; index < tags.size(); index++) {
|
||||
Tag tag = tags.get(index);
|
||||
createTagEditView(inflater, index, tag);
|
||||
}
|
||||
}
|
||||
createAddTagButton();
|
||||
}
|
||||
|
||||
private void createTagEditView(LayoutInflater inflater, int index, Tag tag) {
|
||||
LinearLayout wrapper = (LinearLayout) inflater.inflate(R.layout.edit_tag_item, tagsList, false);
|
||||
EditText tagEditText = (EditText) wrapper.findViewById(R.id.edit_text);
|
||||
tagEditText.setText(tag.getName());
|
||||
tagEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (index >= tags.size()) {
|
||||
return;
|
||||
}
|
||||
Tag tag = tags.get(index);
|
||||
tag.setName(s.toString());
|
||||
if (createdTags.containsKey(tag.getId())) {
|
||||
createdTags.put(tag.getId(), tag);
|
||||
} else {
|
||||
editedTags.put(tag.getId(), tag);
|
||||
}
|
||||
tags.set(index, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
});
|
||||
Button deleteButton = (Button) wrapper.findViewById(R.id.delete_button);
|
||||
deleteButton.setOnClickListener(v -> {
|
||||
deletedTags.add(tag.getId());
|
||||
if (createdTags.containsKey(tag.getId())) {
|
||||
createdTags.remove(tag.getId());
|
||||
}
|
||||
if (editedTags.containsKey(tag.getId())) {
|
||||
editedTags.remove(tag.getId());
|
||||
}
|
||||
tags.remove(tag);
|
||||
tagsList.removeView(wrapper);
|
||||
});
|
||||
tagsList.addView(wrapper);
|
||||
}
|
||||
|
||||
public void setActiveTags(@Nullable List<String> tagIds) {
|
||||
if (tagIds == null) {
|
||||
this.activeTags.clear();
|
||||
} else {
|
||||
this.activeTags = tagIds;
|
||||
}
|
||||
for (int index = 0; index < tagsList.getChildCount()-1; index++) {
|
||||
((AppCompatCheckBox)tagsList.getChildAt(index)).setChecked(false);
|
||||
}
|
||||
for (String tagId : this.activeTags) {
|
||||
int index = indexForId(tagId);
|
||||
if (index >= 0) {
|
||||
((CheckBox)tagsList.getChildAt(index)).setChecked(true);
|
||||
}
|
||||
}
|
||||
filtersChanged();
|
||||
}
|
||||
|
||||
private int indexForId(String tagId) {
|
||||
for (int index = 0; index < tags.size(); index++) {
|
||||
if (tagId.equals(tags.get(index).id)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setTaskType(String taskType, String activeFilter) {
|
||||
this.taskType = taskType;
|
||||
switch (taskType) {
|
||||
case Task.TYPE_HABIT: {
|
||||
taskTypeTitle.setText(R.string.habits);
|
||||
allTaskFilter.setText(R.string.all);
|
||||
secondTaskFilter.setText(R.string.weak);
|
||||
thirdTaskFilter.setText(R.string.strong);
|
||||
break;
|
||||
}
|
||||
case Task.TYPE_DAILY: {
|
||||
taskTypeTitle.setText(R.string.dailies);
|
||||
allTaskFilter.setText(R.string.all);
|
||||
secondTaskFilter.setText(R.string.active);
|
||||
thirdTaskFilter.setText(R.string.gray);
|
||||
break;
|
||||
}
|
||||
case Task.TYPE_TODO: {
|
||||
taskTypeTitle.setText(R.string.todos);
|
||||
allTaskFilter.setText(R.string.active);
|
||||
secondTaskFilter.setText(R.string.dated);
|
||||
thirdTaskFilter.setText(R.string.completed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
setActiveFilter(activeFilter);
|
||||
}
|
||||
|
||||
private void setActiveFilter(@Nullable String activeFilter) {
|
||||
filterType = activeFilter;
|
||||
int checkedId = -1;
|
||||
if (activeFilter == null) {
|
||||
checkedId = R.id.all_task_filter;
|
||||
} else {
|
||||
switch (activeFilter) {
|
||||
case Task.FILTER_ALL:
|
||||
checkedId = R.id.all_task_filter;
|
||||
break;
|
||||
case Task.FILTER_WEAK:
|
||||
case Task.FILTER_DATED:
|
||||
checkedId = R.id.second_task_filter;
|
||||
break;
|
||||
case Task.FILTER_STRONG:
|
||||
case Task.FILTER_GRAY:
|
||||
case Task.FILTER_COMPLETED:
|
||||
checkedId = R.id.third_task_filter;
|
||||
break;
|
||||
case Task.FILTER_ACTIVE:
|
||||
if (taskType.equals(Task.TYPE_DAILY)) {
|
||||
checkedId = R.id.second_task_filter;
|
||||
} else {
|
||||
checkedId = R.id.all_task_filter;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskFilters.check(checkedId);
|
||||
filtersChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
|
||||
if (taskType == null) {
|
||||
return;
|
||||
}
|
||||
if (checkedId == R.id.all_task_filter) {
|
||||
if (!taskType.equals(Task.TYPE_TODO)) {
|
||||
filterType = Task.FILTER_ALL;
|
||||
} else {
|
||||
filterType = Task.FILTER_ACTIVE;
|
||||
}
|
||||
} else if (checkedId == R.id.second_task_filter) {
|
||||
switch (taskType) {
|
||||
case Task.TYPE_HABIT:
|
||||
filterType = Task.FILTER_WEAK;
|
||||
break;
|
||||
case Task.FREQUENCY_DAILY:
|
||||
filterType = Task.FILTER_ACTIVE;
|
||||
break;
|
||||
case Task.TYPE_TODO:
|
||||
filterType = Task.FILTER_DATED;
|
||||
break;
|
||||
}
|
||||
} else if (checkedId == R.id.third_task_filter) {
|
||||
switch (taskType) {
|
||||
case Task.TYPE_HABIT:
|
||||
filterType = Task.FILTER_STRONG;
|
||||
break;
|
||||
case Task.FREQUENCY_DAILY:
|
||||
filterType = Task.FILTER_GRAY;
|
||||
break;
|
||||
case Task.TYPE_TODO:
|
||||
filterType = Task.FILTER_COMPLETED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
filtersChanged();
|
||||
}
|
||||
|
||||
@OnClick(R.id.tag_edit_button)
|
||||
void editButtonClicked() {
|
||||
isEditing = !isEditing;
|
||||
if (isEditing) {
|
||||
startEditing();
|
||||
} else {
|
||||
stopEditing();
|
||||
}
|
||||
}
|
||||
|
||||
private void filtersChanged() {
|
||||
Button clearButton = getButton(AlertDialog.BUTTON_NEUTRAL);
|
||||
if (clearButton != null) {
|
||||
clearButton.setEnabled(hasActiveFilters());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasActiveFilters() {
|
||||
return taskFilters.getCheckedRadioButtonId() != R.id.all_task_filter || activeTags.size() > 0;
|
||||
}
|
||||
|
||||
public void setListener(OnFilterCompletedListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public interface OnFilterCompletedListener {
|
||||
|
||||
void onFilterCompleted(@Nullable String activeTaskFilter, List<String> activeTags);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
package com.habitrpg.android.habitica.ui.views.tasks
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.widget.CompoundButtonCompat
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.support.v7.widget.AppCompatCheckBox
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.*
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.AppComponent
|
||||
import com.habitrpg.android.habitica.data.TagRepository
|
||||
import com.habitrpg.android.habitica.helpers.RxErrorHandler
|
||||
import com.habitrpg.android.habitica.models.Tag
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.functions.Consumer
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class TaskFilterDialog(context: Context, component: AppComponent) : AlertDialog(context), RadioGroup.OnCheckedChangeListener {
|
||||
|
||||
@Inject
|
||||
lateinit var repository: TagRepository
|
||||
|
||||
private val taskTypeTitle: TextView by bindView(R.id.task_type_title)
|
||||
private val taskFilters: RadioGroup by bindView(R.id.task_filter_wrapper)
|
||||
private val allTaskFilter: RadioButton by bindView(R.id.all_task_filter)
|
||||
private val secondTaskFilter: RadioButton by bindView(R.id.second_task_filter)
|
||||
private val thirdTaskFilter: RadioButton by bindView(R.id.third_task_filter)
|
||||
private val tagsEditButton: Button by bindView(R.id.tag_edit_button)
|
||||
private val tagsList: LinearLayout by bindView(R.id.tags_list)
|
||||
private var taskType: String? = null
|
||||
private var listener: OnFilterCompletedListener? = null
|
||||
|
||||
private var filterType: String? = null
|
||||
private var tags = mutableListOf<Tag>()
|
||||
private var activeTags = mutableListOf<String>()
|
||||
private val editedTags = HashMap<String, Tag>()
|
||||
private val createdTags = HashMap<String, Tag>()
|
||||
private val deletedTags = ArrayList<String>()
|
||||
|
||||
private val addIcon: Drawable?
|
||||
private var isEditing: Boolean = false
|
||||
|
||||
init {
|
||||
component.inject(this)
|
||||
addIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_purple_300_36dp)
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val view = inflater.inflate(R.layout.dialog_task_filter, null)
|
||||
|
||||
taskFilters.setOnCheckedChangeListener(this)
|
||||
|
||||
setTitle(R.string.filters)
|
||||
setView(view)
|
||||
this.setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.done)) { _, _ ->
|
||||
if (isEditing) {
|
||||
stopEditing()
|
||||
}
|
||||
listener?.onFilterCompleted(filterType, activeTags)
|
||||
this.dismiss()
|
||||
}
|
||||
|
||||
setButton(AlertDialog.BUTTON_NEUTRAL, getContext().getString(R.string.clear)) { _, _ -> }
|
||||
|
||||
tagsEditButton.setOnClickListener { editButtonClicked() }
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val clearButton = getButton(AlertDialog.BUTTON_NEUTRAL)
|
||||
if (clearButton != null) {
|
||||
clearButton.setOnClickListener {
|
||||
if (isEditing) {
|
||||
stopEditing()
|
||||
}
|
||||
setActiveFilter(null)
|
||||
setActiveTags(null)
|
||||
}
|
||||
clearButton.isEnabled = hasActiveFilters()
|
||||
}
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
if (this.window != null) {
|
||||
this.window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
|
||||
}
|
||||
}
|
||||
|
||||
fun setTags(tags: List<Tag>) {
|
||||
this.tags = repository.getUnmanagedCopy(tags).toMutableList()
|
||||
createTagViews()
|
||||
}
|
||||
|
||||
private fun createTagViews() {
|
||||
val colorStateList = ColorStateList(
|
||||
arrayOf(intArrayOf(-android.R.attr.state_checked), //disabled
|
||||
intArrayOf(android.R.attr.state_checked) //enabled
|
||||
),
|
||||
intArrayOf(Color.LTGRAY, //disabled
|
||||
ContextCompat.getColor(context, R.color.brand_400) //enabled
|
||||
)
|
||||
)
|
||||
val leftPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f, context.resources.displayMetrics).toInt()
|
||||
val verticalPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12f, context.resources.displayMetrics).toInt()
|
||||
for (tag in tags) {
|
||||
val tagCheckbox = AppCompatCheckBox(context)
|
||||
tagCheckbox.text = tag.name
|
||||
tagCheckbox.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
|
||||
tagCheckbox.setPadding(tagCheckbox.paddingLeft + leftPadding,
|
||||
verticalPadding,
|
||||
tagCheckbox.paddingRight,
|
||||
verticalPadding)
|
||||
tagCheckbox.setTextColor(ContextCompat.getColor(context, R.color.textColorLight))
|
||||
CompoundButtonCompat.setButtonTintList(tagCheckbox, colorStateList)
|
||||
tagCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
if (!activeTags.contains(tag.getId())) {
|
||||
activeTags.add(tag.getId())
|
||||
}
|
||||
} else {
|
||||
if (activeTags.contains(tag.getId())) {
|
||||
activeTags.remove(tag.getId())
|
||||
}
|
||||
}
|
||||
filtersChanged()
|
||||
}
|
||||
tagsList.addView(tagCheckbox)
|
||||
}
|
||||
createAddTagButton()
|
||||
}
|
||||
|
||||
private fun createAddTagButton() {
|
||||
val button = Button(context)
|
||||
button.setText(R.string.add_tag)
|
||||
button.setOnClickListener { createTag() }
|
||||
button.setCompoundDrawablesWithIntrinsicBounds(addIcon, null, null, null)
|
||||
button.setBackgroundResource(R.drawable.layout_rounded_bg_lighter_gray)
|
||||
button.setTextColor(ContextCompat.getColor(context, R.color.text_light))
|
||||
tagsList.addView(button)
|
||||
}
|
||||
|
||||
private fun createTag() {
|
||||
val tag = Tag()
|
||||
tag.id = UUID.randomUUID().toString()
|
||||
tags.add(tag)
|
||||
createdTags[tag.getId()] = tag
|
||||
startEditing()
|
||||
}
|
||||
|
||||
private fun startEditing() {
|
||||
isEditing = true
|
||||
tagsList.removeAllViews()
|
||||
createTagEditViews()
|
||||
tagsEditButton.setText(R.string.done)
|
||||
if (this.window != null) {
|
||||
this.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopEditing() {
|
||||
isEditing = false
|
||||
tagsList.removeAllViews()
|
||||
createTagViews()
|
||||
tagsEditButton.setText(R.string.edit_tag_btn_edit)
|
||||
if (this.window != null) {
|
||||
this.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
}
|
||||
repository.updateTags(editedTags.values).toObservable().flatMap { tags -> Observable.fromIterable(tags) }.subscribe(Consumer { tag -> editedTags.remove(tag.id) }, RxErrorHandler.handleEmptyError())
|
||||
repository.createTags(createdTags.values).toObservable().flatMap { tags -> Observable.fromIterable(tags) }.subscribe(Consumer { tag -> createdTags.remove(tag.getId()) }, RxErrorHandler.handleEmptyError())
|
||||
repository.deleteTags(deletedTags).subscribe(Consumer { deletedTags.clear() }, RxErrorHandler.handleEmptyError())
|
||||
}
|
||||
|
||||
private fun createTagEditViews() {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
for (index in tags.indices) {
|
||||
val tag = tags[index]
|
||||
createTagEditView(inflater, index, tag)
|
||||
}
|
||||
createAddTagButton()
|
||||
}
|
||||
|
||||
private fun createTagEditView(inflater: LayoutInflater, index: Int, tag: Tag) {
|
||||
val wrapper = inflater.inflate(R.layout.edit_tag_item, tagsList, false) as LinearLayout
|
||||
val tagEditText = wrapper.findViewById<View>(R.id.edit_text) as EditText
|
||||
tagEditText.setText(tag.name)
|
||||
tagEditText.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
if (index >= tags.size) {
|
||||
return
|
||||
}
|
||||
val changedTag = tags[index]
|
||||
changedTag.name = s.toString()
|
||||
if (createdTags.containsKey(changedTag.getId())) {
|
||||
createdTags[changedTag.getId()] = changedTag
|
||||
} else {
|
||||
editedTags[changedTag.getId()] = changedTag
|
||||
}
|
||||
tags[index] = changedTag
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
|
||||
}
|
||||
})
|
||||
val deleteButton = wrapper.findViewById<View>(R.id.delete_button) as Button
|
||||
deleteButton.setOnClickListener {
|
||||
deletedTags.add(tag.getId())
|
||||
if (createdTags.containsKey(tag.getId())) {
|
||||
createdTags.remove(tag.getId())
|
||||
}
|
||||
if (editedTags.containsKey(tag.getId())) {
|
||||
editedTags.remove(tag.getId())
|
||||
}
|
||||
tags.remove(tag)
|
||||
tagsList.removeView(wrapper)
|
||||
}
|
||||
tagsList.addView(wrapper)
|
||||
}
|
||||
|
||||
fun setActiveTags(tagIds: MutableList<String>?) {
|
||||
if (tagIds == null) {
|
||||
this.activeTags.clear()
|
||||
} else {
|
||||
this.activeTags = tagIds
|
||||
}
|
||||
for (index in 0 until tagsList.childCount - 1) {
|
||||
(tagsList.getChildAt(index) as AppCompatCheckBox).isChecked = false
|
||||
}
|
||||
for (tagId in this.activeTags) {
|
||||
val index = indexForId(tagId)
|
||||
if (index >= 0) {
|
||||
(tagsList.getChildAt(index) as CheckBox).isChecked = true
|
||||
}
|
||||
}
|
||||
filtersChanged()
|
||||
}
|
||||
|
||||
private fun indexForId(tagId: String): Int {
|
||||
for (index in tags.indices) {
|
||||
if (tagId == tags[index].id) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fun setTaskType(taskType: String, activeFilter: String) {
|
||||
this.taskType = taskType
|
||||
when (taskType) {
|
||||
Task.TYPE_HABIT -> {
|
||||
taskTypeTitle.setText(R.string.habits)
|
||||
allTaskFilter.setText(R.string.all)
|
||||
secondTaskFilter.setText(R.string.weak)
|
||||
thirdTaskFilter.setText(R.string.strong)
|
||||
}
|
||||
Task.TYPE_DAILY -> {
|
||||
taskTypeTitle.setText(R.string.dailies)
|
||||
allTaskFilter.setText(R.string.all)
|
||||
secondTaskFilter.setText(R.string.active)
|
||||
thirdTaskFilter.setText(R.string.gray)
|
||||
}
|
||||
Task.TYPE_TODO -> {
|
||||
taskTypeTitle.setText(R.string.todos)
|
||||
allTaskFilter.setText(R.string.active)
|
||||
secondTaskFilter.setText(R.string.dated)
|
||||
thirdTaskFilter.setText(R.string.completed)
|
||||
}
|
||||
}
|
||||
setActiveFilter(activeFilter)
|
||||
}
|
||||
|
||||
private fun setActiveFilter(activeFilter: String?) {
|
||||
filterType = activeFilter
|
||||
var checkedId = -1
|
||||
if (activeFilter == null) {
|
||||
checkedId = R.id.all_task_filter
|
||||
} else {
|
||||
when (activeFilter) {
|
||||
Task.FILTER_ALL -> checkedId = R.id.all_task_filter
|
||||
Task.FILTER_WEAK, Task.FILTER_DATED -> checkedId = R.id.second_task_filter
|
||||
Task.FILTER_STRONG, Task.FILTER_GRAY, Task.FILTER_COMPLETED -> checkedId = R.id.third_task_filter
|
||||
Task.FILTER_ACTIVE -> checkedId = if (taskType == Task.TYPE_DAILY) {
|
||||
R.id.second_task_filter
|
||||
} else {
|
||||
R.id.all_task_filter
|
||||
}
|
||||
}
|
||||
}
|
||||
taskFilters.check(checkedId)
|
||||
filtersChanged()
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(group: RadioGroup, @IdRes checkedId: Int) {
|
||||
if (taskType == null) {
|
||||
return
|
||||
}
|
||||
when (checkedId) {
|
||||
R.id.all_task_filter -> filterType = if (taskType != Task.TYPE_TODO) {
|
||||
Task.FILTER_ALL
|
||||
} else {
|
||||
Task.FILTER_ACTIVE
|
||||
}
|
||||
R.id.second_task_filter -> when (taskType) {
|
||||
Task.TYPE_HABIT -> filterType = Task.FILTER_WEAK
|
||||
Task.FREQUENCY_DAILY -> filterType = Task.FILTER_ACTIVE
|
||||
Task.TYPE_TODO -> filterType = Task.FILTER_DATED
|
||||
}
|
||||
R.id.third_task_filter -> when (taskType) {
|
||||
Task.TYPE_HABIT -> filterType = Task.FILTER_STRONG
|
||||
Task.FREQUENCY_DAILY -> filterType = Task.FILTER_GRAY
|
||||
Task.TYPE_TODO -> filterType = Task.FILTER_COMPLETED
|
||||
}
|
||||
}
|
||||
filtersChanged()
|
||||
}
|
||||
|
||||
private fun editButtonClicked() {
|
||||
isEditing = !isEditing
|
||||
if (isEditing) {
|
||||
startEditing()
|
||||
} else {
|
||||
stopEditing()
|
||||
}
|
||||
}
|
||||
|
||||
private fun filtersChanged() {
|
||||
val clearButton = getButton(AlertDialog.BUTTON_NEUTRAL)
|
||||
if (clearButton != null) {
|
||||
clearButton.isEnabled = hasActiveFilters()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasActiveFilters(): Boolean {
|
||||
return taskFilters.checkedRadioButtonId != R.id.all_task_filter || activeTags.size > 0
|
||||
}
|
||||
|
||||
fun setListener(listener: OnFilterCompletedListener) {
|
||||
this.listener = listener
|
||||
}
|
||||
|
||||
interface OnFilterCompletedListener {
|
||||
|
||||
fun onFilterCompleted(activeTaskFilter: String?, activeTags: List<String>?)
|
||||
}
|
||||
}
|
||||
|
|
@ -14,9 +14,9 @@ import java.util.Map;
|
|||
|
||||
import io.realm.Realm;
|
||||
|
||||
public class MountMapDeserializer implements JsonDeserializer<HashMap<String, Mount>> {
|
||||
public class MountMapDeserializer implements JsonDeserializer<Map<String, Mount>> {
|
||||
@Override
|
||||
public HashMap<String, Mount> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
public Map<String, Mount> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
HashMap<String, Mount> vals = new HashMap<>();
|
||||
if (json.isJsonObject()) {
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue