From 53329ae75e534b75d2e970d1ccdba1dbcecae27d Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Sun, 6 Mar 2016 16:49:35 +0100 Subject: [PATCH] allow guild editing --- Habitica/AndroidManifest.xml | 11 +- Habitica/res/layout/activity_group_form.xml | 40 +++++-- .../res/layout/fragment_guilds_overview.xml | 16 +-- Habitica/res/layout/item_public_guild.xml | 2 +- .../res/layout/tavern_chat_new_entry_item.xml | 2 +- Habitica/res/values/strings.xml | 1 + Habitica/res/values/styles.xml | 1 + .../habitrpg/android/habitica/APIHelper.java | 4 +- .../ui/activities/GroupFormActivity.java | 98 ++++++++++++++++ .../social/GroupInformationFragment.java | 2 +- .../ui/fragments/social/GuildFragment.java | 110 ++++++++++++------ .../social/GuildsOverviewFragment.java | 17 ++- .../habitrpgwrapper/lib/api/ApiService.java | 3 + .../habitrpgwrapper/lib/models/Group.java | 2 + ...erializer.java => GroupSerialization.java} | 24 +++- 15 files changed, 273 insertions(+), 60 deletions(-) rename Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/{GroupDeserializer.java => GroupSerialization.java} (69%) diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index f862a3dc7..faf184ea3 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -81,7 +81,16 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activities.MainActivity" /> - + + + - + + + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/fragment_guilds_overview.xml b/Habitica/res/layout/fragment_guilds_overview.xml index afb3384a5..590ad6937 100644 --- a/Habitica/res/layout/fragment_guilds_overview.xml +++ b/Habitica/res/layout/fragment_guilds_overview.xml @@ -1,6 +1,8 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + > @@ -10,13 +12,11 @@ - + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + \ No newline at end of file diff --git a/Habitica/res/layout/item_public_guild.xml b/Habitica/res/layout/item_public_guild.xml index 1b88848f3..b1722526a 100644 --- a/Habitica/res/layout/item_public_guild.xml +++ b/Habitica/res/layout/item_public_guild.xml @@ -1,7 +1,7 @@ Name Description Add Tag + Privacy \ No newline at end of file diff --git a/Habitica/res/values/styles.xml b/Habitica/res/values/styles.xml index 2b12db529..bc362b5c2 100644 --- a/Habitica/res/values/styles.xml +++ b/Habitica/res/values/styles.xml @@ -9,6 +9,7 @@ 0dp @null + @color/white diff --git a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java index ec0795ff5..a7babc5f1 100644 --- a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java +++ b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java @@ -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(); diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/activities/GroupFormActivity.java b/Habitica/src/com/habitrpg/android/habitica/ui/activities/GroupFormActivity.java index d6bd3529f..8f4370a54 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/activities/GroupFormActivity.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/activities/GroupFormActivity.java @@ -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); + } + } } diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GroupInformationFragment.java b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GroupInformationFragment.java index 084bbd075..143e6c286 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GroupInformationFragment.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GroupInformationFragment.java @@ -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); diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java index a9509c470..60060379f 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildFragment.java @@ -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 { + private final int GROUP_FORM_ACTIVITY = 11; private Group guild; public boolean isMember; @@ -58,28 +61,7 @@ public class GuildFragment extends BaseMainFragment implements Callback { final ContentCache contentCache = new ContentCache(mAPIHelper.apiService); // Get the full group data - mAPIHelper.apiService.getGroup(this.guild.id, new Callback() { - @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 { 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() { + @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); } } diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildsOverviewFragment.java b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildsOverviewFragment.java index 9bed66faf..6d654a339 100644 --- a/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildsOverviewFragment.java +++ b/Habitica/src/com/habitrpg/android/habitica/ui/fragments/social/GuildsOverviewFragment.java @@ -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>, View.OnClickListener { +public class GuildsOverviewFragment extends BaseMainFragment implements Callback>, 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 guilds; private ArrayList 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 groups, Response response) { this.guilds = groups; this.setGuildsOnListView(); + if (swipeRefreshLayout != null) { + swipeRefreshLayout.setRefreshing(false); + } } @Override diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java index 965b5f25e..632aa1040 100644 --- a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/api/ApiService.java @@ -114,6 +114,9 @@ public interface ApiService { @GET("/groups/{gid}") void getGroup(@Path("gid") String groupId, Callback cb); + @POST("/groups/{id}") + void updateGroup(@Path("id") String id, @Body Group item, Callback habitItemCallback); + @GET("/groups/{gid}/chat") void listGroupChat(@Path("gid") String groupId, Callback> cb); diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/Group.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/Group.java index f5b0ab183..1e4dc7c95 100644 --- a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/Group.java +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/models/Group.java @@ -31,6 +31,8 @@ public class Group extends BaseModel { public Quest quest; + public String privacy; + public ArrayList chat; public ArrayList members; diff --git a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupDeserializer.java b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupSerialization.java similarity index 69% rename from Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupDeserializer.java rename to Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupSerialization.java index 802573086..dce97fdce 100644 --- a/Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupDeserializer.java +++ b/Habitica/src/com/magicmicky/habitrpgwrapper/lib/utils/GroupSerialization.java @@ -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 { +public class GroupSerialization implements JsonDeserializer, JsonSerializer { @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 { 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; + } }