allow guild editing

This commit is contained in:
Phillip Thelen 2016-03-06 16:49:35 +01:00
parent 2f09ab00b3
commit 53329ae75e
15 changed files with 273 additions and 60 deletions

View file

@ -81,7 +81,16 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.activities.MainActivity" />
</activity>
<activity
android:name=".ui.activities.GroupFormActivity"
android:theme="@style/AppThemeWithActionBarBlackText"
android:parentActivityName=".ui.activities.MainActivity"
android:screenOrientation="portrait"
tools:ignore="UnusedAttribute">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.activities.MainActivity" />
</activity>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"

View file

@ -8,14 +8,20 @@
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" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:hintTextAppearance="@style/TextAppearance.AppCompat">
<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" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="72dp"
@ -46,5 +52,23 @@
android:inputType="textCapSentences" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/privacyWrapper">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/privacy"
android:layout_gravity="center_vertical" />
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/privacySpinner" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<import type="com.magicmicky.habitrpgwrapper.lib.models.Preferences" />
@ -10,13 +12,11 @@
</data>
<android.support.v4.widget.NestedScrollView
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/chat.refresh.layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarSize="3dp"
android:scrollbarThumbVertical="@color/md_grey_500"
android:scrollbars="vertical">
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
@ -47,8 +47,8 @@
android:id="@+id/publicGuildsButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_margin="@dimen/card_horizontal_padding"
android:text="@string/public_guilds" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</layout>

View file

@ -1,7 +1,7 @@
<?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:layout_height="wrap_content"
android:padding="8dp">
<LinearLayout

View file

@ -2,7 +2,7 @@
<LinearLayout 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"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView

View file

@ -233,4 +233,5 @@ To start, which parts of your life do you want to improve?</string>
<string name="name">Name</string>
<string name="description">Description</string>
<string name="add_tag">Add Tag</string>
<string name="privacy">Privacy</string>
</resources>

View file

@ -9,6 +9,7 @@
<item name="elevation">0dp</item>
<item name="android:windowContentOverlay">@null</item>
<item name="actionMenuTextColor">@color/white</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->

View file

@ -41,7 +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.GroupSerialization;
import com.magicmicky.habitrpgwrapper.lib.utils.PurchasedDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.SkillDeserializer;
import com.magicmicky.habitrpgwrapper.lib.utils.TaskListDeserializer;
@ -119,7 +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(Group.class, new GroupSerialization())
.registerTypeAdapter(Date.class, new DateDeserializer())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.create();

View file

@ -1,25 +1,42 @@
package com.habitrpg.android.habitica.ui.activities;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Spinner;
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 com.habitrpg.android.habitica.ui.helpers.MarkdownParser;
import com.magicmicky.habitrpgwrapper.lib.models.Tag;
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
import com.raizlabs.android.dbflow.sql.builder.Condition;
import com.raizlabs.android.dbflow.sql.language.Select;
import butterknife.Bind;
public class GroupFormActivity extends BaseActivity {
String groupID;
String groupName;
String groupDescription;
String groupPrivacy;
String groupLeader;
@Bind(R.id.group_name_edittext)
EditText groupNameEditText;
@ -29,6 +46,12 @@ public class GroupFormActivity extends BaseActivity {
@Bind(R.id.emoji_toggle_btn)
ImageButton emojiButton;
@Bind(R.id.privacyWrapper)
LinearLayout privacyWrapper;
@Bind(R.id.privacySpinner)
Spinner privacySpinner;
EmojiPopup popup;
@Override
@ -39,6 +62,15 @@ public class GroupFormActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
this.groupID = bundle.getString("groupID");
this.groupName = bundle.getString("name");
this.groupDescription = bundle.getString("description");
this.groupPrivacy = bundle.getString("privacy");
this.groupLeader = bundle.getString("leader");
// Emoji keyboard stuff
popup = new EmojiPopup(emojiButton.getRootView(), this, ContextCompat.getColor(this, R.color.brand));
@ -100,6 +132,39 @@ public class GroupFormActivity extends BaseActivity {
});
emojiButton.setOnClickListener(new emojiClickListener(groupDescriptionEditText));
if (this.groupID != null) {
this.fillForm();
}
}
private void fillForm() {
this.groupNameEditText.setText(this.groupName);
this.groupDescriptionEditText.setText(this.groupDescription);
this.privacyWrapper.setVisibility(View.GONE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_task_form, menu);
return true;
}
@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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_save_changes) {
finishActivitySuccessfuly();
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean isEmojiEditText(View view) {
@ -148,4 +213,37 @@ public class GroupFormActivity extends BaseActivity {
}
}
}
@Override
public boolean onSupportNavigateUp() {
finish();
dismissKeyboard();
return true;
}
@Override
public void onBackPressed() {
finish();
dismissKeyboard();
}
private void finishActivitySuccessfuly() {
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("leader", this.groupLeader);
resultIntent.putExtras(bundle);
setResult(Activity.RESULT_OK, resultIntent);
finish();
dismissKeyboard();
}
private void dismissKeyboard() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View currentFocus = getCurrentFocus();
if (currentFocus != null) {
imm.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
}
}
}

View file

@ -107,7 +107,7 @@ public class GroupInformationFragment extends Fragment {
private void updateQuestMember(Group group) {
questMemberView.removeAllViewsInLayout();
if (group.quest.key == null) return;
if (group.quest == null || group.quest.key == null) return;
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (HabitRPGUser member : group.members) {
final LinearLayout itemView = (LinearLayout) layoutInflater.inflate(R.layout.party_member_quest, null);

View file

@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.ui.fragments.social;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -14,6 +15,7 @@ import android.view.ViewGroup;
import com.habitrpg.android.habitica.ContentCache;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity;
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity;
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
@ -28,6 +30,7 @@ import retrofit.RetrofitError;
import retrofit.client.Response;
public class GuildFragment extends BaseMainFragment implements Callback<Group> {
private final int GROUP_FORM_ACTIVITY = 11;
private Group guild;
public boolean isMember;
@ -58,28 +61,7 @@ public class GuildFragment extends BaseMainFragment implements Callback<Group> {
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) {
}
});
mAPIHelper.apiService.getGroup(this.guild.id, this);
setViewPagerAdapter();
@ -193,24 +175,84 @@ public class GuildFragment extends BaseMainFragment implements Callback<Group> {
tabLayout.setupWithViewPager(viewPager);
}
private void displayEditForm() {
Bundle bundle = new Bundle();
bundle.putString("groupID",this.guild.id);
bundle.putString("name",this.guild.name);
bundle.putString("description",this.guild.description);
bundle.putString("privacy",this.guild.privacy);
bundle.putString("leader",this.guild.leaderID);
Intent intent = new Intent(activity, GroupFormActivity.class);
intent.putExtras(bundle);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(intent, GROUP_FORM_ACTIVITY);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (GROUP_FORM_ACTIVITY) : {
if (resultCode == Activity.RESULT_OK) {
boolean needsSaving = false;
Bundle bundle = data.getExtras();
if (this.guild.name != null && !this.guild.name.equals(bundle.getString("name"))) {
this.guild.name = bundle.getString("name");
needsSaving = true;
}
if (this.guild.description != null && !this.guild.description.equals(bundle.getString("description"))) {
this.guild.description = bundle.getString("description");
needsSaving = true;
}
if (this.guild.leaderID != null && !this.guild.leaderID.equals(bundle.getString("leader"))) {
this.guild.leaderID = bundle.getString("leader");
needsSaving = true;
}
if (this.guild.privacy != null && !this.guild.privacy.equals(bundle.getString("privacy"))) {
this.guild.privacy = bundle.getString("privacy");
needsSaving = true;
}
if (needsSaving) {
this.mAPIHelper.apiService.updateGroup(this.guild.id, this.guild, new Callback<Void>() {
@Override
public void success(Void aVoid, Response response) {
}
@Override
public void failure(RetrofitError error) {
}
});
this.guildInformationFragment.setGroup(guild);
}
}
break;
}
}
}
@Override
public void success(Group group, Response response) {
if (group == null) {
this.tabLayout.removeAllTabs();
return;
}
this.guild = group;
this.guildInformationFragment.setGroup(group);
if (this.guildInformationFragment != null) {
this.guildInformationFragment.setGroup(group);
}
if (this.chatListFragment != null) {
this.chatListFragment.seenGroupId = group.id;
}
this.guild = group;
this.activity.supportInvalidateOptionsMenu();
}
@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

@ -2,6 +2,7 @@ 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.MotionEvent;
import android.view.View;
@ -33,7 +34,7 @@ import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class GuildsOverviewFragment extends BaseMainFragment implements Callback<ArrayList<Group>>, View.OnClickListener {
public class GuildsOverviewFragment extends BaseMainFragment implements Callback<ArrayList<Group>>, View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
@Bind(R.id.my_guilds_listview)
LinearLayout guildsListView;
@ -41,6 +42,8 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
@Bind(R.id.publicGuildsButton)
Button publicGuildsButton;
@Bind(R.id.chat_refresh_layout)
SwipeRefreshLayout swipeRefreshLayout;
private List<Group> guilds;
private ArrayList<String> guildIDs;
@ -57,6 +60,7 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_guilds_overview, container, false);
ButterKnife.bind(this, v);
swipeRefreshLayout.setOnRefreshListener(this);
this.publicGuildsButton.setOnClickListener(this);
if (this.guilds != null) {
this.setGuildsOnListView();
@ -64,6 +68,13 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
return v;
}
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
fetchGuilds();
}
private void fetchGuilds() {
this.mAPIHelper.apiService.listGroups("guilds", this);
}
@ -86,6 +97,7 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
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, null);
@ -100,6 +112,9 @@ public class GuildsOverviewFragment extends BaseMainFragment implements Callback
public void success(ArrayList<Group> groups, Response response) {
this.guilds = groups;
this.setGuildsOnListView();
if (swipeRefreshLayout != null) {
swipeRefreshLayout.setRefreshing(false);
}
}
@Override

View file

@ -114,6 +114,9 @@ public interface ApiService {
@GET("/groups/{gid}")
void getGroup(@Path("gid") String groupId, Callback<Group> cb);
@POST("/groups/{id}")
void updateGroup(@Path("id") String id, @Body Group item, Callback<Void> habitItemCallback);
@GET("/groups/{gid}/chat")
void listGroupChat(@Path("gid") String groupId, Callback<List<ChatMessage>> cb);

View file

@ -31,6 +31,8 @@ public class Group extends BaseModel {
public Quest quest;
public String privacy;
public ArrayList<ChatMessage> chat;
public ArrayList<HabitRPGUser> members;

View file

@ -5,6 +5,8 @@ import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
@ -13,15 +15,19 @@ import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import java.lang.reflect.Type;
import java.util.List;
public class GroupDeserializer implements JsonDeserializer<Group> {
public class GroupSerialization implements JsonDeserializer<Group>, JsonSerializer<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("description")) {
group.description = obj.get("description").getAsString();
}
if (obj.has("privacy")) {
group.privacy = obj.get("privacy").getAsString();
}
if (obj.has("memberCount")) {
group.memberCount = obj.get("memberCount").getAsInt();
}
@ -51,4 +57,16 @@ public class GroupDeserializer implements JsonDeserializer<Group> {
return group;
}
@Override
public JsonElement serialize(Group src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.addProperty("name", src.name);
obj.addProperty("description", src.description);
obj.addProperty("logo", src.logo);
obj.addProperty("type", src.type);
obj.addProperty("type", src.type);
obj.addProperty("leader", src.leaderID);
return obj;
}
}