diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/GroupsHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/GroupsHelper.java index 6fc980b..c74e7b0 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/GroupsHelper.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/GroupsHelper.java @@ -12,6 +12,7 @@ import org.communiquons.android.comunic.client.data.enums.GroupsMembershipLevels import org.communiquons.android.comunic.client.data.models.APIRequest; import org.communiquons.android.comunic.client.data.models.APIResponse; import org.communiquons.android.comunic.client.data.models.GroupInfo; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -36,6 +37,31 @@ public class GroupsHelper extends BaseHelper { super(context); } + /** + * Get the list of groups of the user + * + * @return The list of groups of the user / null in case of failure + */ + @Nullable + public ArrayList getUserList(){ + APIRequest request = new APIRequest(getContext(), "groups/get_my_list"); + + try { + APIResponse response = new APIRequestHelper().exec(request); + if(response.getResponse_code() != 200) return null; + + JSONArray array = response.getJSONArray(); + ArrayList list = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) + list.add(array.getInt(i)); + return list; + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + /** * Get information about multiple groups @@ -45,12 +71,25 @@ public class GroupsHelper extends BaseHelper { */ @Nullable public ArrayMap getInfoMultiple(ArrayList IDs){ + return getInfoMultiple(IDs, false); + } + + /** + * Get information about multiple groups + * + * @param IDs The ID of the target groups + * @param force Specify whether the request has to be forced or not (if set to true, the cache + * will be ignored) + * @return Information about the related groups + */ + @Nullable + public ArrayMap getInfoMultiple(ArrayList IDs, boolean force){ //Process each group to check if its information are available in the cache or not ArrayList toGet = new ArrayList<>(); for(int id : IDs){ - if(!mInfoCache.containsKey(id)) + if(!mInfoCache.containsKey(id) || force) toGet.add(id); } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java index 5243a5f..d968b0a 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java @@ -43,6 +43,7 @@ import org.communiquons.android.comunic.client.ui.fragments.LatestPostsFragment; import org.communiquons.android.comunic.client.ui.fragments.NotificationsFragment; import org.communiquons.android.comunic.client.ui.fragments.SinglePostFragment; import org.communiquons.android.comunic.client.ui.fragments.UpdateConversationFragment; +import org.communiquons.android.comunic.client.ui.fragments.groups.UserGroupsFragment; import org.communiquons.android.comunic.client.ui.fragments.userpage.UserAccessDeniedFragment; import org.communiquons.android.comunic.client.ui.fragments.userpage.UserPageFragment; import org.communiquons.android.comunic.client.ui.listeners.onOpenUsersPageListener; @@ -234,6 +235,12 @@ public class MainActivity extends BaseActivity implements //Get action id int id = item.getItemId(); + //Display user groups + if(id == R.id.action_user_groups){ + openUserGroups(); + return true; + } + //To search a user if (id == R.id.action_search_user) { searchUser(); @@ -714,6 +721,18 @@ public class MainActivity extends BaseActivity implements transaction.commit(); } + /** + * Open user groups + */ + public void openUserGroups(){ + UserGroupsFragment userGroupsFragment = new UserGroupsFragment(); + + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.replace(R.id.main_fragment, userGroupsFragment); + transaction.addToBackStack(null); + transaction.commit(); + } + /** * Clear the cache database of the application */ diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/GroupsListAdapter.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/GroupsListAdapter.java new file mode 100644 index 0000000..d4033e2 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/GroupsListAdapter.java @@ -0,0 +1,85 @@ +package org.communiquons.android.comunic.client.ui.adapters; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.communiquons.android.comunic.client.R; +import org.communiquons.android.comunic.client.data.models.GroupInfo; +import org.communiquons.android.comunic.client.ui.views.GroupImageView; + +import java.util.ArrayList; + +/** + * Groups list adapter + * + * @author Pierre HUBERT + */ +public class GroupsListAdapter extends BaseRecyclerViewAdapter { + + /** + * The list of groups + */ + private ArrayList mList = new ArrayList<>(); + + public GroupsListAdapter(Context context) { + super(context); + } + + /** + * Set the list of groups + * + * @param List The list of groups + */ + public void setList(ArrayList List) { + this.mList = List; + } + + @Override + public int getItemCount() { + return mList.size(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + View view = LayoutInflater.from(getContext()).inflate( + R.layout.viewholder_group, viewGroup, false); + return new GroupHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { + ((GroupHolder)viewHolder).bind(i); + } + + /** + * Single group holder class + */ + private class GroupHolder extends RecyclerView.ViewHolder { + + private GroupImageView mGroupImageView; + private TextView mGroupName; + + GroupHolder(@NonNull View itemView) { + super(itemView); + + mGroupImageView = itemView.findViewById(R.id.groupImage); + mGroupName = itemView.findViewById(R.id.groupName); + } + + GroupInfo getGroup(int pos){ + return mList.get(pos); + } + + void bind(int pos){ + GroupInfo groupInfo = getGroup(pos); + mGroupImageView.setGroup(groupInfo); + mGroupName.setText(groupInfo.getDisplayName()); + } + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetUserGroupsTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetUserGroupsTask.java new file mode 100644 index 0000000..4ce4aa8 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetUserGroupsTask.java @@ -0,0 +1,34 @@ +package org.communiquons.android.comunic.client.ui.asynctasks; + +import android.content.Context; +import android.util.ArrayMap; + +import org.communiquons.android.comunic.client.data.helpers.GroupsHelper; +import org.communiquons.android.comunic.client.data.models.GroupInfo; + +import java.util.ArrayList; + +/** + * Get user groups AsyncTask + * + * @author Pierre HUBERT + */ +public class GetUserGroupsTask extends SafeAsyncTask> { + public GetUserGroupsTask(Context context) { + super(context); + } + + + @Override + protected ArrayMap doInBackground(Void... voids) { + + GroupsHelper groupsHelper = new GroupsHelper(getContext()); + + ArrayList groups = groupsHelper.getUserList(); + + if(groups == null) + return null; + + return groupsHelper.getInfoMultiple(groups, true); + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java index a6d84a1..9f21dca 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/AbstractFragment.java @@ -39,7 +39,7 @@ public abstract class AbstractFragment extends Fragment { * * @return The task manager */ - SafeAsyncTasksManager getTasksManager() { + public SafeAsyncTasksManager getTasksManager() { return mTasksManager; } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/AbstractGroupFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/AbstractGroupFragment.java new file mode 100644 index 0000000..5156a11 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/AbstractGroupFragment.java @@ -0,0 +1,23 @@ +package org.communiquons.android.comunic.client.ui.fragments.groups; + +import org.communiquons.android.comunic.client.R; +import org.communiquons.android.comunic.client.ui.activities.MainActivity; +import org.communiquons.android.comunic.client.ui.fragments.AbstractFragment; + +import java.util.Objects; + +/** + * Base Group Fragment + * + * @author Pierre HUBERT + */ +abstract class AbstractGroupFragment extends AbstractFragment { + + @Override + public void onResume() { + super.onResume(); + + MainActivity.SetNavbarSelectedOption(Objects.requireNonNull(getActivity()), + R.id.action_personal_page); + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/UserGroupsFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/UserGroupsFragment.java new file mode 100644 index 0000000..350e171 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/groups/UserGroupsFragment.java @@ -0,0 +1,137 @@ +package org.communiquons.android.comunic.client.ui.fragments.groups; + +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.ArrayMap; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.Toast; + +import org.communiquons.android.comunic.client.R; +import org.communiquons.android.comunic.client.data.models.GroupInfo; +import org.communiquons.android.comunic.client.ui.adapters.GroupsListAdapter; +import org.communiquons.android.comunic.client.ui.asynctasks.GetUserGroupsTask; +import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask; + +import java.util.ArrayList; + +/** + * User groups fragment + * + * @author Pierre HUBERT + */ +public class UserGroupsFragment extends AbstractGroupFragment { + + /** + * Views + */ + private ProgressBar mProgressBar; + private RecyclerView mGroupsView; + + /** + * User groups + */ + private ArrayMap mGroupsList; + + /** + * Groups adapter + */ + private GroupsListAdapter mGroupsAdapter; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_user_groups, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + //Get views + mGroupsView = view.findViewById(R.id.groups_list); + mProgressBar = view.findViewById(R.id.progressBar); + + setProgressBarVisiblity(true); + } + + @Override + public void onStart() { + super.onStart(); + + if(mGroupsList == null) + getGroupsList(); + else + displayGroupsList(); + } + + /** + * Get the list of groups of the user + */ + private void getGroupsList(){ + + setProgressBarVisiblity(true); + + getTasksManager().unsetSpecificTasks(GetUserGroupsTask.class); + GetUserGroupsTask getUserGroupsTask = new GetUserGroupsTask(getActivity()); + getUserGroupsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener>() { + @Override + public void OnPostExecute(ArrayMap list) { + getGroupsListCallback(list); + } + }); + getUserGroupsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + getTasksManager().addTask(getUserGroupsTask); + } + + /** + * Get user groups callback + * + * @param list The list of groups of the user + */ + private void getGroupsListCallback(@Nullable ArrayMap list){ + + setProgressBarVisiblity(false); + + if(list == null){ + Toast.makeText(getActivity(), R.string.err_get_user_groups, Toast.LENGTH_SHORT).show(); + return; + } + + mGroupsList = list; + displayGroupsList(); + } + + /** + * Display the list of groups of the user + */ + private void displayGroupsList(){ + + setProgressBarVisiblity(false); + + mGroupsAdapter = new GroupsListAdapter(getActivity()); + mGroupsAdapter.setList(new ArrayList<>(mGroupsList.values())); + + mGroupsView.setAdapter(mGroupsAdapter); + mGroupsView.setLayoutManager(new LinearLayoutManager(getActivity())); + mGroupsView.addItemDecoration(new DividerItemDecoration(getActivity(), + DividerItemDecoration.VERTICAL)); + + } + + /** + * Update (set) progressbar visibility + * + * @param visible Visibility level of the progress bar + */ + private void setProgressBarVisiblity(boolean visible){ + mProgressBar.setVisibility(visible ? View.VISIBLE : View.GONE); + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/views/GroupImageView.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/views/GroupImageView.java new file mode 100644 index 0000000..bb1a49b --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/views/GroupImageView.java @@ -0,0 +1,46 @@ +package org.communiquons.android.comunic.client.ui.views; + +import android.content.Context; +import android.util.AttributeSet; + +import org.communiquons.android.comunic.client.R; +import org.communiquons.android.comunic.client.data.models.GroupInfo; + +/** + * Special view for group images + * + * @author Pierre HUBERT + */ +public class GroupImageView extends WebImageView { + + public GroupImageView(Context context) { + this(context, null); + } + + public GroupImageView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public GroupImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + setDefaultDrawable(R.drawable.ic_friends); + } + + /** + * Set a new group to this view + * + * @param group The new group to set + */ + public void setGroup(GroupInfo group){ + loadURL(group.getIcon_url()); + } + + /** + * Remove any group currently set in this view + */ + public void removeGroup(){ + removeImage(); + applyDefaultDrawable(); + } +} diff --git a/app/src/main/res/layout/fragment_user_groups.xml b/app/src/main/res/layout/fragment_user_groups.xml new file mode 100644 index 0000000..6b875cd --- /dev/null +++ b/app/src/main/res/layout/fragment_user_groups.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/viewholder_group.xml b/app/src/main/res/layout/viewholder_group.xml new file mode 100644 index 0000000..b4280d7 --- /dev/null +++ b/app/src/main/res/layout/viewholder_group.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml index 8a762e6..5a0abcb 100644 --- a/app/src/main/res/menu/main_menu.xml +++ b/app/src/main/res/menu/main_menu.xml @@ -2,6 +2,11 @@ + + + 16dp 16dp + + 64dp + 64dp + 20dp 20dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 677a1d5..7494200 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -296,4 +296,6 @@ Respond Could not cancel your response to the survey! Could not send response to the server! + My groups + Could not get the groups of the user!