Add more guild functionality

This commit is contained in:
Phillip Thelen 2016-03-05 14:54:19 +01:00
parent ad3d3e223c
commit ae0ff33e41
25 changed files with 920 additions and 64 deletions

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/group_name_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/name"
android:textColor="@android:color/black"
android:inputType="textCapSentences" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="72dp"
android:orientation="horizontal" >
<ImageButton
android:id="@+id/emoji.toggle.btn"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_emoticon_grey600_24dp"
android:background="@drawable/md_transparent"
android:contentDescription="Toogle Emoji"
android:focusable="true"
android:focusableInTouchMode="true" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:hintTextAppearance="@style/TextAppearance.AppCompat">
<com.github.data5tream.emojilib.EmojiEditText
android:id="@+id/group_description_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/description"
android:textColor="@android:color/black"
android:inputType="textCapSentences" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -10,7 +10,7 @@
<import type="android.text.Html"/>
<variable
name="party"
name="group"
type="Group" />
<variable
@ -36,19 +36,41 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
bind:parsemarkdown="@{party.name}"
bind:parsemarkdown="@{group.name}"
android:textStyle="bold" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@android:drawable/divider_horizontal_dark"
android:dividerPadding="8dp"
android:showDividers="middle"
android:orientation="vertical">
<com.github.data5tream.emojilib.EmojiTextView
android:layout_margin="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
bind:parsemarkdown="@{party.description}" />
bind:parsemarkdown="@{group.description}" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="@dimen/card_padding">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/gems"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(group.balance * 4)}"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>

View file

@ -38,10 +38,13 @@
android:id="@+id/my_guilds_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:showDividers="middle"
android:divider="@android:drawable/divider_horizontal_dark">
</LinearLayout>
</android.support.v7.widget.CardView>
<Button
android:id="@+id/publicGuildsButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"

View file

@ -12,7 +12,6 @@
android:layout_height="match_parent"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/md_grey_500"
android:scrollbars="vertical" />
</android.support.design.widget.CoordinatorLayout>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/nameTextView"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="@+id/memberCountTextView" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/descriptionTextView"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/joinleaveButton" />
</LinearLayout>
</LinearLayout>

View file

@ -1,16 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearLayout"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true">
<TextView
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/card_padding"/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/hairline_height"
android:background="@android:color/darker_gray"/>
</LinearLayout>

View file

@ -6,24 +6,22 @@
android:id="@+id/menu.chat.copy.as.todo"
android:icon="@drawable/ic_action_launch"
android:title="Copy as ToDo" />
android:title="@string/copy_as_todo" />
<item
android:id="@+id/menu.chat.send.pm"
android:icon="@drawable/ic_action_chat"
android:title="Send PM" />
android:title="@string/send_pm" />
<group>
<item
android:id="@+id/menu.chat.flag"
android:icon="@drawable/ic_action_warning"
app:showAsAction="always|withText"
android:title="Flag" />
android:title="@string/flag" />
<item
android:id="@+id/menu.chat.delete"
android:icon="@drawable/ic_action_delete_white_24"
android:title="Delete" />
android:title="@string/delete" />
</group>
</menu>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:abc="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools">
<item
android:id="@+id/menu.guild.edit"
android:orderInCategory="1"
app:showAsAction="ifRoom"
android:title="@string/action_edit"
abc:showAsAction="ifRoom"/>
</menu>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:abc="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools">
<item
android:id="@+id/menu.guild.leave"
android:orderInCategory="1"
app:showAsAction="ifRoom"
android:title="@string/leave"
abc:showAsAction="ifRoom"/>
</menu>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:abc="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools">
<item
android:id="@+id/menu.guild.join"
android:orderInCategory="1"
app:showAsAction="ifRoom"
android:title="@string/join"
abc:showAsAction="ifRoom"/>
</menu>

View file

@ -215,4 +215,15 @@ To start, which parts of your life do you want to improve?</string>
<string name="gem.purchase.support">Want to help us keep Habitica running? You can support the developers by buying gems!\n\nGems allow you to buy fun extras for your account, including: \n\n - Cool costumes for your avatar\n - Awesome backgrounds\n - Fun quests that reward you with pet eggs\n - The ability to change your class before level 100\n\nThank you so much for helping us make Habitica the best it can be. Your support means a lot to us!</string>
<string name="my_guilds">My Guilds</string>
<string name="public_guilds">Public Guilds</string>
<string name="guild">Guild</string>
<string name="leave">Leave</string>
<string name="join">Join</string>
<string name="leader">Leader</string>
<string name="gems">Gems</string>
<string name="copy_as_todo">Copy as ToDo</string>
<string name="send_pm">Send PM</string>
<string name="flag">Flag</string>
<string name="delete">Delete</string>
<string name="name">Name</string>
<string name="description">Description</string>
</resources>

View file

@ -23,6 +23,7 @@ import com.magicmicky.habitrpgwrapper.lib.api.Server;
import com.magicmicky.habitrpgwrapper.lib.api.TypeAdapter.TagsAdapter;
import com.magicmicky.habitrpgwrapper.lib.models.Customization;
import com.magicmicky.habitrpgwrapper.lib.models.FAQArticle;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
import com.magicmicky.habitrpgwrapper.lib.models.Purchases;
@ -40,6 +41,7 @@ import com.magicmicky.habitrpgwrapper.lib.utils.ChecklistItemSerializer;
import com.magicmicky.habitrpgwrapper.lib.utils.CustomizationDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.DateDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.FAQArticleListDeserilializer;
import com.magicmicky.habitrpgwrapper.lib.utils.GroupDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.PurchasedDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.SkillDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.TaskListDeserializer;
@ -117,6 +119,7 @@ public class APIHelper implements ErrorHandler, Profiler {
.registerTypeAdapter(customizationListType, new CustomizationDeserializer())
.registerTypeAdapter(tutorialStepListType, new TutorialStepListDeserializer())
.registerTypeAdapter(faqArticleListType, new FAQArticleListDeserilializer())
.registerTypeAdapter(Group.class, new GroupDeserializer())
.registerTypeAdapter(Date.class, new DateDeserializer())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.create();

View file

@ -0,0 +1,8 @@
package com.habitrpg.android.habitica.events;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
public class DisplayFragmentEvent {
public BaseMainFragment fragment;
}

View file

@ -0,0 +1,151 @@
package com.habitrpg.android.habitica.ui.activities;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import com.github.data5tream.emojilib.EmojiEditText;
import com.github.data5tream.emojilib.EmojiGridView;
import com.github.data5tream.emojilib.EmojiPopup;
import com.github.data5tream.emojilib.emoji.Emojicon;
import com.habitrpg.android.habitica.R;
import butterknife.Bind;
public class GroupFormActivity extends BaseActivity {
@Bind(R.id.group_name_edittext)
EditText groupNameEditText;
@Bind(R.id.group_description_edittext)
EmojiEditText groupDescriptionEditText;
@Bind(R.id.emoji_toggle_btn)
ImageButton emojiButton;
EmojiPopup popup;
@Override
protected int getLayoutResId() {
return R.layout.activity_group_form;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Emoji keyboard stuff
popup = new EmojiPopup(emojiButton.getRootView(), this, ContextCompat.getColor(this, R.color.brand));
popup.setSizeForSoftKeyboard();
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
changeEmojiKeyboardIcon(false);
}
});
popup.setOnSoftKeyboardOpenCloseListener(new EmojiPopup.OnSoftKeyboardOpenCloseListener() {
@Override
public void onKeyboardOpen(int keyBoardHeight) {
}
@Override
public void onKeyboardClose() {
if (popup.isShowing())
popup.dismiss();
}
});
popup.setOnEmojiconClickedListener(new EmojiGridView.OnEmojiconClickedListener() {
@Override
public void onEmojiconClicked(Emojicon emojicon) {
EmojiEditText emojiEditText = null;
if (getCurrentFocus() == null || !isEmojiEditText(getCurrentFocus()) || emojicon == null) {
return;
} else {
emojiEditText = (EmojiEditText) getCurrentFocus();
}
int start = emojiEditText.getSelectionStart();
int end = emojiEditText.getSelectionEnd();
if (start < 0) {
emojiEditText.append(emojicon.getEmoji());
} else {
emojiEditText.getText().replace(Math.min(start, end),
Math.max(start, end), emojicon.getEmoji(), 0,
emojicon.getEmoji().length());
}
}
});
popup.setOnEmojiconBackspaceClickedListener(new EmojiPopup.OnEmojiconBackspaceClickedListener() {
@Override
public void onEmojiconBackspaceClicked(View v) {
if (isEmojiEditText(getCurrentFocus())) {
KeyEvent event = new KeyEvent(
0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
getCurrentFocus().dispatchKeyEvent(event);
}
}
});
emojiButton.setOnClickListener(new emojiClickListener(groupDescriptionEditText));
}
private boolean isEmojiEditText(View view) {
return view instanceof EmojiEditText;
}
private void changeEmojiKeyboardIcon(Boolean keyboardOpened) {
if (keyboardOpened) {
emojiButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_keyboard_grey600_24dp));
} else {
emojiButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_emoticon_grey600_24dp));
}
}
private class emojiClickListener implements View.OnClickListener {
EmojiEditText view;
public emojiClickListener(EmojiEditText view) {
this.view = view;
}
@Override
public void onClick(View v) {
if(!popup.isShowing()){
if(popup.isKeyBoardOpen()){
popup.showAtBottom();
changeEmojiKeyboardIcon(true);
}
else{
view.setFocusableInTouchMode(true);
view.requestFocus();
popup.showAtBottomPending();
final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
changeEmojiKeyboardIcon(true);
}
}
else{
popup.dismiss();
changeEmojiKeyboardIcon(false);
}
}
}
}

View file

@ -31,6 +31,7 @@ import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.HostConfig;
import com.habitrpg.android.habitica.NotificationPublisher;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.events.DisplayFragmentEvent;
import com.habitrpg.android.habitica.events.DisplayTutorialEvent;
import com.habitrpg.android.habitica.ui.TutorialView;
import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback;
@ -223,7 +224,7 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
if (this.activeFragment != null && fragment.getClass() == this.activeFragment.getClass()) {
return;
}
this.activeFragment = fragment;
fragment.setArguments(getIntent().getExtras());
fragment.mAPIHelper = mAPIHelper;
fragment.setUser(user);
@ -492,6 +493,7 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
drawer.getDrawerLayout().closeDrawer(Gravity.RIGHT);
} else {
super.onBackPressed();
}
}
@ -619,6 +621,10 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
this.displayTutorialStep(tutorialEvent.step, tutorialEvent.tutorialText);
}
public void onEvent(DisplayFragmentEvent event) {
this.displayFragment(event.fragment);
}
// endregion
@Override

View file

@ -0,0 +1,137 @@
package com.habitrpg.android.habitica.ui.adapter.social;
import android.content.res.Resources;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.ValueBarBinding;
import com.habitrpg.android.habitica.events.DisplayFragmentEvent;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.fragments.social.GuildFragment;
import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
import com.habitrpg.android.habitica.userpicture.UserPicture;
import com.magicmicky.habitrpgwrapper.lib.api.ApiService;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import java.util.ArrayList;
import butterknife.Bind;
import butterknife.ButterKnife;
import de.greenrobot.event.EventBus;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class PublicGuildsRecyclerViewAdapter extends RecyclerView.Adapter<PublicGuildsRecyclerViewAdapter.GuildViewHolder> {
public APIHelper apiHelper;
private ArrayList<Group> publicGuildList;
private ArrayList<String> memberGuildIDs;
public void setPublicGuildList(ArrayList<Group> publicGuildList) {
this.publicGuildList = publicGuildList;
this.notifyDataSetChanged();
}
public void setMemberGuildIDs(ArrayList<String> memberGuildIDs) {
this.memberGuildIDs = memberGuildIDs;
}
@Override
public GuildViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_public_guild, parent, false);
return new GuildViewHolder(view);
}
@Override
public void onBindViewHolder(GuildViewHolder holder, int position) {
holder.bind(publicGuildList.get(position));
}
@Override
public int getItemCount() {
return this.publicGuildList == null ? 0 : this.publicGuildList.size();
}
class GuildViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, Callback<Group> {
@Bind(R.id.nameTextView)
TextView nameTextView;
@Bind(R.id.memberCountTextView)
TextView memberCountTextView;
@Bind(R.id.descriptionTextView)
TextView descriptionTextView;
@Bind(R.id.joinleaveButton)
Button joinLeaveButton;
Group guild;
Boolean isMember;
public GuildViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(this);
joinLeaveButton.setOnClickListener(this);
}
public void bind(Group guild) {
android.content.Context ctx = itemView.getContext();
this.guild = guild;
this.nameTextView.setText(guild.name);
this.memberCountTextView.setText(String.valueOf(guild.memberCount));
this.descriptionTextView.setText(guild.description);
if (PublicGuildsRecyclerViewAdapter.this.memberGuildIDs.contains(guild.id)) {
this.isMember = true;
this.joinLeaveButton.setText(R.string.leave);
} else {
this.isMember = false;
this.joinLeaveButton.setText(R.string.join);
}
}
@Override
public void onClick(View v) {
if (v == this.joinLeaveButton) {
if (this.isMember) {
PublicGuildsRecyclerViewAdapter.this.apiHelper.apiService.leaveGroup(this.guild.id, this);
} else {
PublicGuildsRecyclerViewAdapter.this.apiHelper.apiService.joinGroup(this.guild.id, this);
}
} else {
GuildFragment guildFragment = new GuildFragment();
guildFragment.setGuild(this.guild);
guildFragment.isMember = this.isMember;
DisplayFragmentEvent event = new DisplayFragmentEvent();
event.fragment = guildFragment;
EventBus.getDefault().post(event);
}
}
@Override
public void success(Group group, Response response) {
this.bind(guild);
}
@Override
public void failure(RetrofitError error) {
}
}
}

View file

@ -1,4 +1,4 @@
package com.habitrpg.android.habitica.ui.fragments.social.party;
package com.habitrpg.android.habitica.ui.fragments.social;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
@ -9,32 +9,31 @@ import android.view.View;
import android.view.ViewGroup;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.databinding.FragmentPartyInfoBinding;
import com.habitrpg.android.habitica.databinding.FragmentGroupInfoBinding;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.QuestContent;
/**
* Created by Negue on 16.09.2015.
*/
public class PartyInformationFragment extends Fragment {
public class GroupInformationFragment extends Fragment {
private View view;
FragmentPartyInfoBinding viewBinding;
FragmentGroupInfoBinding viewBinding;
private Group group;
public static PartyInformationFragment newInstance(Group group) {
public static GroupInformationFragment newInstance(Group group) {
Bundle args = new Bundle();
PartyInformationFragment fragment = new PartyInformationFragment();
GroupInformationFragment fragment = new GroupInformationFragment();
fragment.setArguments(args);
fragment.group = group;
return fragment;
}
public PartyInformationFragment(){
public GroupInformationFragment(){
}
@ -42,7 +41,7 @@ public class PartyInformationFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null)
view = inflater.inflate(R.layout.fragment_party_info, container, false);
view = inflater.inflate(R.layout.fragment_group_info, container, false);
viewBinding = DataBindingUtil.bind(view);
@ -55,7 +54,7 @@ public class PartyInformationFragment extends Fragment {
public void setGroup(Group group) {
if (viewBinding != null) {
viewBinding.setParty(group);
viewBinding.setGroup(group);
}
}

View file

@ -0,0 +1,216 @@
package com.habitrpg.android.habitica.ui.fragments.social;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
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.ContentCache;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.UserParty;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class GuildFragment extends BaseMainFragment implements Callback<Group> {
private Group guild;
public boolean isMember;
public ViewPager viewPager;
private GroupInformationFragment guildInformationFragment;
private ChatListFragment chatListFragment;
public void setGuild(Group guild) {
this.guild = guild;
if (this.guildInformationFragment != null) {
this.guildInformationFragment.setGroup(guild);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.usesTabLayout = true;
super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_party, container, false);
viewPager = (ViewPager) v.findViewById(R.id.view_pager);
viewPager.setCurrentItem(0);
final ContentCache contentCache = new ContentCache(mAPIHelper.apiService);
// Get the full group data
mAPIHelper.apiService.getGroup(this.guild.id, new Callback<Group>() {
@Override
public void success(Group group, Response response) {
if (group == null) {
tabLayout.removeAllTabs();
return;
}
GuildFragment.this.guild = group;
if (guildInformationFragment != null) {
guildInformationFragment.setGroup(group);
}
if (chatListFragment != null) {
chatListFragment.seenGroupId = group.id;
}
}
@Override
public void failure(RetrofitError error) {
}
});
setViewPagerAdapter();
return v;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (this.isMember) {
if (this.user.getId().equals(this.guild.leaderID)) {
this.activity.getMenuInflater().inflate(R.menu.guild_admin, menu);
} else {
this.activity.getMenuInflater().inflate(R.menu.guild_member, menu);
}
} else {
this.activity.getMenuInflater().inflate(R.menu.guild_nonmember, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.menu_guild_join:
this.mAPIHelper.apiService.joinGroup(this.guild.id, this);
return true;
case R.id.menu_guild_leave:
this.mAPIHelper.apiService.leaveGroup(this.guild.id, this);
return true;
case R.id.menu_guild_edit:
this.displayEditForm();
return true;
}
return super.onOptionsItemSelected(item);
}
public void setViewPagerAdapter() {
android.support.v4.app.FragmentManager fragmentManager = getChildFragmentManager();
UserParty party = user.getParty();
if (party == null) {
return;
}
viewPager.setAdapter(new FragmentPagerAdapter(fragmentManager) {
@Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position) {
case 0: {
fragment = guildInformationFragment = GroupInformationFragment.newInstance(GuildFragment.this.guild);
break;
}
case 1: {
chatListFragment = new ChatListFragment();
chatListFragment.configure(activity, GuildFragment.this.guild.id, mAPIHelper, user, activity, false);
fragment = chatListFragment;
break;
}
default:
fragment = new Fragment();
}
return fragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return activity.getString(R.string.guild);
case 1:
return activity.getString(R.string.chat);
}
return "";
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (position == 1 && GuildFragment.this.guild != null) {
chatListFragment.setNavigatedToFragment(GuildFragment.this.guild.id);
}
}
@Override
public void onPageSelected(int position) {
if (position == 1 && GuildFragment.this.guild != null) {
chatListFragment.setNavigatedToFragment(GuildFragment.this.guild.id);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void success(Group group, Response response) {
this.guild = group;
this.guildInformationFragment.setGroup(group);
}
@Override
public void failure(RetrofitError error) {
}
private void displayEditForm() {
Bundle bundle = new Bundle();
bundle.putString("groupID",this.guild.id);
Intent intent = new Intent(activity, TaskFormActivity.class);
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
}

View file

@ -3,8 +3,10 @@ package com.habitrpg.android.habitica.ui.fragments.social;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
@ -18,28 +20,47 @@ import com.raizlabs.android.dbflow.sql.language.OrderBy;
import com.raizlabs.android.dbflow.sql.language.Select;
import com.raizlabs.android.dbflow.sql.language.Where;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class GuildsOverviewFragment extends BaseMainFragment implements Callback<ArrayList<Group>> {
public class GuildsOverviewFragment extends BaseMainFragment implements Callback<ArrayList<Group>>, View.OnClickListener {
@Bind(R.id.my_guilds_listview)
LinearLayout guildsListView;
@Bind(R.id.publicGuildsButton)
Button publicGuildsButton;
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);
ButterKnife.bind(this, v);
this.fetchGuilds();
this.publicGuildsButton.setOnClickListener(this);
if (this.guilds != null) {
this.setGuildsOnListView();
}
return v;
}
@ -56,26 +77,48 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
.from(Group.class)
.where(Condition.column("type").eq("guild"));
List<Group> guilds = select.queryList();
this.guilds = select.queryList();
this.setGuildsOnListView();
}
private void setGuildsOnListView(List<Group> guilds) {
private void setGuildsOnListView() {
if (this.guildsListView == null) {
return;
}
this.guildIDs = new ArrayList<>();
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (Group guild : guilds) {
LinearLayout entry = (LinearLayout) inflater.inflate(R.layout.plain_list_item, null);
TextView textView = (TextView) entry.findViewById(R.id.textView);
textView.setText(guild.name);
for (Group guild : this.guilds) {
TextView entry = (TextView) inflater.inflate(R.layout.plain_list_item, null);
entry.setText(guild.name);
entry.setOnClickListener(this);
this.guildsListView.addView(entry);
this.guildIDs.add(guild.id);
}
}
@Override
public void success(ArrayList<Group> groups, Response response) {
this.setGuildsOnListView(groups);
this.guilds = groups;
this.setGuildsOnListView();
}
@Override
public void failure(RetrofitError error) {
}
@Override
public void onClick(View v) {
if (v == this.publicGuildsButton) {
PublicGuildsFragment publicGuildsFragment = new PublicGuildsFragment();
publicGuildsFragment.memberGuildIDs = this.guildIDs;
this.activity.displayFragment(publicGuildsFragment);
} else {
Integer guildIndex = ((ViewGroup)v.getParent()).indexOfChild(v);
GuildFragment guildFragment = new GuildFragment();
guildFragment.setGuild(this.guilds.get(guildIndex));
guildFragment.isMember = true;
this.activity.displayFragment(guildFragment);
}
}
}

View file

@ -0,0 +1,79 @@
package com.habitrpg.android.habitica.ui.fragments.social;
import android.os.Bundle;
import android.support.annotation.Nullable;
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.ui.adapter.social.PartyMemberRecyclerViewAdapter;
import com.habitrpg.android.habitica.ui.adapter.social.PublicGuildsRecyclerViewAdapter;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class PublicGuildsFragment extends BaseMainFragment implements Callback<ArrayList<Group>> {
ArrayList<String> memberGuildIDs;
ArrayList <Group> guilds;
@Bind(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);
if (view == null) {
view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
ButterKnife.bind(this, view);
recyclerView.setLayoutManager(new LinearLayoutManager(this.activity));
viewAdapter = new PublicGuildsRecyclerViewAdapter();
viewAdapter.setMemberGuildIDs(this.memberGuildIDs);
viewAdapter.apiHelper = this.mAPIHelper;
recyclerView.setAdapter(viewAdapter);
if (this.guilds != null) {
this.viewAdapter.setPublicGuildList(this.guilds);
}
}
return view;
}
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
this.fetchGuilds();
}
private void fetchGuilds() {
this.mAPIHelper.apiService.listGroups("public", this);
}
@Override
public void success(ArrayList<Group> groups, Response response) {
this.guilds = groups;
if (this.viewAdapter!= null) {
this.viewAdapter.setPublicGuildList(groups);
}
}
@Override
public void failure(RetrofitError error) {
}
}

View file

@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.ContentCache;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.habitrpg.android.habitica.ui.fragments.social.ChatListFragment;
import com.habitrpg.android.habitica.ui.fragments.social.GroupInformationFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.QuestContent;
import com.magicmicky.habitrpgwrapper.lib.models.UserParty;
@ -34,7 +35,7 @@ public class PartyFragment extends BaseMainFragment {
private HashMap<Integer, Fragment> fragmentDictionary = new HashMap<>();
private PartyMemberListFragment partyMemberListFragment;
private PartyInformationFragment partyInformationFragment;
private GroupInformationFragment groupInformationFragment;
private ChatListFragment chatListFragment;
@Override
@ -72,8 +73,8 @@ public class PartyFragment extends BaseMainFragment {
partyMemberListFragment.setMemberList(group.members);
}
if (partyInformationFragment != null) {
partyInformationFragment.setGroup(group);
if (groupInformationFragment != null) {
groupInformationFragment.setGroup(group);
}
if(chatListFragment != null){
@ -84,8 +85,8 @@ public class PartyFragment extends BaseMainFragment {
contentCache.GetQuestContent(group.quest.key, new ContentCache.QuestContentCallback() {
@Override
public void GotQuest(QuestContent content) {
if (partyInformationFragment != null) {
partyInformationFragment.setQuestContent(content);
if (groupInformationFragment != null) {
groupInformationFragment.setQuestContent(content);
}
}
});
@ -122,7 +123,7 @@ public class PartyFragment extends BaseMainFragment {
switch (position) {
case 0: {
fragment = partyInformationFragment = PartyInformationFragment.newInstance(group);
fragment = groupInformationFragment = GroupInformationFragment.newInstance(group);
break;
}
case 1: {

View file

@ -446,19 +446,21 @@ public class TasksFragment extends BaseMainFragment implements OnCheckedChangeLi
//endregion Events
public void fillTagFilterDrawer(List<Tag> tagList) {
filterDrawer.removeAllItems();
filterDrawer.addItems(
new SectionDrawerItem().withName("Filter by Tag"),
new EditTextDrawer()
);
for (Tag t : tagList) {
filterDrawer.addItem(new SwitchDrawerItem()
.withName(t.getName())
.withTag(t)
.withChecked(this.tagsHelper.isTagChecked(t.getId()))
.withOnCheckedChangeListener(this)
if (filterDrawer != null) {
filterDrawer.removeAllItems();
filterDrawer.addItems(
new SectionDrawerItem().withName("Filter by Tag"),
new EditTextDrawer()
);
for (Tag t : tagList) {
filterDrawer.addItem(new SwitchDrawerItem()
.withName(t.getName())
.withTag(t)
.withChecked(this.tagsHelper.isTagChecked(t.getId()))
.withOnCheckedChangeListener(this)
);
}
}
}

View file

@ -117,6 +117,12 @@ public interface ApiService {
@GET("/groups/{gid}/chat")
void listGroupChat(@Path("gid") String groupId, Callback<List<ChatMessage>> cb);
@GET("/groups/{gid}/join")
void joinGroup(@Path("gid") String groupId, Callback<Group> cb);
@GET("/groups/{gid}/leave")
void leaveGroup(@Path("gid") String groupId, Callback<Group> cb);
@POST("/groups/{gid}/chat")
void postGroupChat(@Path("gid") String groupId, @Query("message") String message, Callback<PostChatMessageResult> cb);

View file

@ -17,9 +17,7 @@ public class Group extends BaseModel {
public String description;
// TODO Leader
// GET /groups?type={0} => leader is string
// GET /groups/{gid} => leader is user-object
public String leaderID;
public String name;

View file

@ -0,0 +1,54 @@
package com.magicmicky.habitrpgwrapper.lib.utils;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import java.lang.reflect.Type;
import java.util.List;
public class GroupDeserializer implements JsonDeserializer<Group> {
@Override
public Group deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Group group = new Group();
JsonObject obj = json.getAsJsonObject();
group.id = obj.get("_id").getAsString();
group.name = obj.get("name").getAsString();
group.description = obj.get("description").getAsString();
if (obj.has("memberCount")) {
group.memberCount = obj.get("memberCount").getAsInt();
}
if (obj.has("balance")) {
group.balance = obj.get("balance").getAsDouble();
}
if (obj.has("logo")) {
group.logo = obj.get("logo").getAsString();
}
if (obj.has("type")) {
group.type = obj.get("type").getAsString();
}
if (obj.has("chat")) {
group.chat = context.deserialize(obj.get("chat"), new TypeToken<List<ChatMessage>>() {
}.getType());
}
if (obj.has("members")) {
group.members = context.deserialize(obj.get("members"), new TypeToken<List<HabitRPGUser>>(){}.getType());
}
if (obj.has("leader")) {
if (obj.get("leader").isJsonPrimitive()) {
group.leaderID = obj.get("leader").getAsString();
} else {
group.leaderID = obj.get("leader").getAsJsonObject().get("_id").getAsString();
}
}
return group;
}
}