mirror of
https://github.com/pierre42100/ComunicAndroid
synced 2024-11-27 07:49:28 +00:00
Can search groups
This commit is contained in:
parent
4e79e299bf
commit
8fa4c5bcc4
@ -39,6 +39,11 @@
|
||||
android:name=".ui.activities.SearchUserActivity"
|
||||
android:label="@string/activity_searchuser_title" />
|
||||
|
||||
<!-- Global search activity -->
|
||||
<activity
|
||||
android:name=".ui.activities.SearchActivity"
|
||||
android:label="@string/activity_search_title" />
|
||||
|
||||
<!-- Notifications background refresh service -->
|
||||
<service
|
||||
android:name=".data.services.NotificationsService"
|
||||
@ -50,8 +55,9 @@
|
||||
android:label="@string/activity_view_pdf_label" />
|
||||
|
||||
<!-- Account settings activity -->
|
||||
<activity android:name=".ui.activities.AccountSettingsActivity"
|
||||
android:label="@string/activity_account_settings_label"/>
|
||||
<activity
|
||||
android:name=".ui.activities.AccountSettingsActivity"
|
||||
android:label="@string/activity_account_settings_label" />
|
||||
|
||||
<!-- Settings activity -->
|
||||
<activity
|
||||
@ -63,7 +69,6 @@
|
||||
android:name=".ui.activities.AboutActivity"
|
||||
android:label="@string/activity_about_title" />
|
||||
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,12 @@
|
||||
package org.communiquons.android.comunic.client.data.enums;
|
||||
|
||||
/**
|
||||
* Different kinds of search result
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public enum KindSearchResult {
|
||||
USER,
|
||||
GROUP,
|
||||
UNKNOWN
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.communiquons.android.comunic.client.data.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import org.communiquons.android.comunic.client.data.enums.KindSearchResult;
|
||||
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.communiquons.android.comunic.client.data.models.SearchResult;
|
||||
import org.communiquons.android.comunic.client.data.models.SearchResultWithInfo;
|
||||
import org.communiquons.android.comunic.client.data.models.UserInfo;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Search helper
|
||||
*
|
||||
* This helper is used to search users and groups
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class SearchHelper extends BaseHelper {
|
||||
|
||||
public SearchHelper(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a global search in the database
|
||||
*
|
||||
* @param query The query to search for
|
||||
* @return The list of results / null in case of failure
|
||||
*/
|
||||
@Nullable
|
||||
public ArrayList<SearchResult> global(String query) {
|
||||
|
||||
//Prepare request
|
||||
APIRequest request = new APIRequest(getContext(), "search/global");
|
||||
request.addString("query", query);
|
||||
|
||||
//Execute request
|
||||
try {
|
||||
APIResponse response = request.exec();
|
||||
|
||||
if(response.getResponse_code() != 200)
|
||||
return null;
|
||||
|
||||
//Get JSON data
|
||||
JSONArray data = response.getJSONArray();
|
||||
if(data == null)
|
||||
return null;
|
||||
|
||||
//Parse and return results
|
||||
ArrayList<SearchResult> results = new ArrayList<>();
|
||||
for(int i = 0; i < data.length(); i++)
|
||||
results.add(JSONObjectToSearchResult(data.getJSONObject(i)));
|
||||
return results;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill search result with information for users, groups...
|
||||
*
|
||||
* @param list The list of results to process
|
||||
* @return Information for groups, users / null in case of failure
|
||||
*/
|
||||
@Nullable
|
||||
public ArrayList<SearchResultWithInfo> fillResults(@NonNull ArrayList<SearchResult> list){
|
||||
|
||||
ArrayList<SearchResultWithInfo> listWithInfo = new ArrayList<>();
|
||||
|
||||
//Extract the ids of the users and the groups to get
|
||||
ArrayList<Integer> usersID = new ArrayList<>();
|
||||
ArrayList<Integer> groupsID = new ArrayList<>();
|
||||
|
||||
for(SearchResult result : list){
|
||||
if(result.getKind() == KindSearchResult.USER)
|
||||
usersID.add(result.getId());
|
||||
|
||||
else if(result.getKind() == KindSearchResult.GROUP)
|
||||
groupsID.add(result.getId());
|
||||
|
||||
SearchResultWithInfo resultWithInfo = new SearchResultWithInfo();
|
||||
result.copyTo(resultWithInfo);
|
||||
listWithInfo.add(resultWithInfo);
|
||||
}
|
||||
|
||||
//Get information about users (if any)
|
||||
if(usersID.size() > 0){
|
||||
|
||||
ArrayMap<Integer, UserInfo> usersInfo = new GetUsersHelper(getContext())
|
||||
.getMultiple(usersID);
|
||||
|
||||
if(usersInfo == null)
|
||||
return null;
|
||||
|
||||
//Process the list of result to apply information
|
||||
for(SearchResultWithInfo result : listWithInfo){
|
||||
|
||||
//Skip non related entries
|
||||
if(result.getKind() != KindSearchResult.USER)
|
||||
continue;
|
||||
|
||||
result.setUserInfo(usersInfo.get(result.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Get information about groups (if any)
|
||||
if(groupsID.size() > 0){
|
||||
|
||||
ArrayMap<Integer, GroupInfo> groupsInfo = new GroupsHelper(getContext())
|
||||
.getInfoMultiple(groupsID);
|
||||
|
||||
if(groupsInfo == null)
|
||||
return null;
|
||||
|
||||
//Process the list of result to apply information
|
||||
for(SearchResultWithInfo result : listWithInfo){
|
||||
|
||||
//Skip non related entries
|
||||
if(result.getKind() != KindSearchResult.GROUP)
|
||||
continue;
|
||||
|
||||
result.setGroupInfo(groupsInfo.get(result.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return listWithInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a string into a search kind result
|
||||
*
|
||||
* @param string The string to convert
|
||||
* @return Matching search result
|
||||
*/
|
||||
private static KindSearchResult StringToKindSearchResult(String string){
|
||||
switch (string){
|
||||
|
||||
case "user":
|
||||
return KindSearchResult.USER;
|
||||
|
||||
case "group":
|
||||
return KindSearchResult.GROUP;
|
||||
|
||||
default:
|
||||
return KindSearchResult.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Turn a JSONObject into a SearchResult object
|
||||
*
|
||||
* @param object The object to convert
|
||||
* @return Generated SearchResult object
|
||||
* @throws JSONException This exception is thrown in case of failure
|
||||
*/
|
||||
private static SearchResult JSONObjectToSearchResult(JSONObject object) throws JSONException {
|
||||
SearchResult result = new SearchResult();
|
||||
|
||||
result.setId(object.getInt("id"));
|
||||
result.setKind(StringToKindSearchResult(object.getString("kind")));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package org.communiquons.android.comunic.client.data.models;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.communiquons.android.comunic.client.data.helpers.APIRequestHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
@ -99,17 +101,17 @@ public class APIRequest {
|
||||
public String get_parameters_encoded(){
|
||||
|
||||
//Return string
|
||||
String result = "";
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
//Process loop
|
||||
for(int i = 0; i < parameters.size(); i++){
|
||||
|
||||
//Make sure to separate parameters
|
||||
result += (i > 0 ? "&" : "");
|
||||
result += parameters.get(i).get_encoded();
|
||||
result.append(i > 0 ? "&" : "");
|
||||
result.append(parameters.get(i).get_encoded());
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,4 +149,16 @@ public class APIRequest {
|
||||
public boolean isTryContinueOnError() {
|
||||
return tryContinueOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
*
|
||||
* This is a convenience method
|
||||
*
|
||||
* @return The result of the operation
|
||||
* @throws Exception In case of failure
|
||||
*/
|
||||
public APIResponse exec() throws Exception {
|
||||
return new APIRequestHelper().exec(this);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package org.communiquons.android.comunic.client.data.models;
|
||||
|
||||
import org.communiquons.android.comunic.client.data.enums.KindSearchResult;
|
||||
|
||||
/**
|
||||
* Single search result
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class SearchResult {
|
||||
|
||||
//Private fields
|
||||
private int id;
|
||||
private KindSearchResult kind;
|
||||
|
||||
/**
|
||||
* Base constructor
|
||||
*/
|
||||
public SearchResult(){}
|
||||
|
||||
/**
|
||||
* Copy the values of the current object to a new object
|
||||
*
|
||||
* @param dst Destination object
|
||||
*/
|
||||
public void copyTo(SearchResult dst){
|
||||
dst.setId(getId());
|
||||
dst.setKind(getKind());
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public KindSearchResult getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setKind(KindSearchResult kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package org.communiquons.android.comunic.client.data.models;
|
||||
|
||||
/**
|
||||
* This object handles a search result and all the information associated with it
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class SearchResultWithInfo extends SearchResult {
|
||||
|
||||
private GroupInfo groupInfo;
|
||||
private UserInfo userInfo;
|
||||
|
||||
public GroupInfo getGroupInfo() {
|
||||
return groupInfo;
|
||||
}
|
||||
|
||||
public void setGroupInfo(GroupInfo groupInfo) {
|
||||
this.groupInfo = groupInfo;
|
||||
}
|
||||
|
||||
public UserInfo getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
public void setUserInfo(UserInfo userInfo) {
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
}
|
@ -28,14 +28,36 @@ public final class Constants {
|
||||
public static final int POST_CREATE_FORM_PICK_PHOTO = 2;
|
||||
|
||||
/**
|
||||
* Intent code : search a user
|
||||
* Main Activity : search a user
|
||||
*/
|
||||
public static final int MAIN_ACTIVITY_SEARCH_USER_INTENT = 3;
|
||||
|
||||
/**
|
||||
* Main Activity : make a global search
|
||||
*/
|
||||
public static final int MAIN_ACTIVITY_GLOBAL_SEARCH_INTENT = 4;
|
||||
|
||||
/**
|
||||
* Pick image to update account image
|
||||
*/
|
||||
public static final int ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT = 4;
|
||||
public static final int ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT = 5;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Intents results
|
||||
*/
|
||||
public final class IntentResults {
|
||||
|
||||
/**
|
||||
* Search user result
|
||||
*/
|
||||
public static final String SEARCH_USER_RESULT = "org.communiquons.android.searchUser.RESULT";
|
||||
|
||||
/**
|
||||
* Global search result
|
||||
*/
|
||||
public static final String SEARCH_GLOBAL_RESULT = "org.communiquons.android.globalSearch.RESULT";
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package org.communiquons.android.comunic.client.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.CallSuper;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTasksManager;
|
||||
|
||||
/**
|
||||
* Base application activity
|
||||
*
|
||||
@ -11,10 +15,40 @@ import android.support.v7.app.AppCompatActivity;
|
||||
*/
|
||||
public abstract class BaseActivity extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* Tasks manager
|
||||
*/
|
||||
private SafeAsyncTasksManager mSafeAsyncTasksManager = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//Initialize task manager
|
||||
mSafeAsyncTasksManager = new SafeAsyncTasksManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
//Unset all task
|
||||
mSafeAsyncTasksManager.unsetAllTasks();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ActionBar getSupportActionBar() {
|
||||
assert super.getSupportActionBar() != null;
|
||||
return super.getSupportActionBar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tasks manager associated with this activity
|
||||
*
|
||||
* @return Task manager associated to this activity
|
||||
*/
|
||||
public SafeAsyncTasksManager getTasksManager() {
|
||||
return mSafeAsyncTasksManager;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
@ -49,14 +50,16 @@ import org.communiquons.android.comunic.client.ui.fragments.groups.GroupPageMain
|
||||
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.OnOpenGroupListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.onOpenUsersPageListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.OnOpenPageListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.onPostOpenListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.openConversationListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.updateConversationListener;
|
||||
import org.communiquons.android.comunic.client.ui.utils.UiUtils;
|
||||
import org.communiquons.android.comunic.client.ui.views.NavigationBar;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.communiquons.android.comunic.client.ui.Constants.IntentRequestCode.MAIN_ACTIVITY_GLOBAL_SEARCH_INTENT;
|
||||
import static org.communiquons.android.comunic.client.ui.Constants.IntentRequestCode.MAIN_ACTIVITY_SEARCH_USER_INTENT;
|
||||
|
||||
|
||||
@ -66,8 +69,8 @@ import static org.communiquons.android.comunic.client.ui.Constants.IntentRequest
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class MainActivity extends BaseActivity implements
|
||||
openConversationListener, updateConversationListener, onOpenUsersPageListener,
|
||||
onPostOpenListener, NavigationBar.OnNavigationItemSelectedListener, OnOpenGroupListener {
|
||||
openConversationListener, updateConversationListener, OnOpenPageListener,
|
||||
onPostOpenListener, NavigationBar.OnNavigationItemSelectedListener {
|
||||
|
||||
/**
|
||||
* Debug tag
|
||||
@ -245,9 +248,9 @@ public class MainActivity extends BaseActivity implements
|
||||
return true;
|
||||
}
|
||||
|
||||
//To search a user
|
||||
if (id == R.id.action_search_user) {
|
||||
searchUser();
|
||||
//To perform a wider search
|
||||
if(id == R.id.action_search) {
|
||||
searchGlobal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -387,9 +390,28 @@ public class MainActivity extends BaseActivity implements
|
||||
|
||||
switch (requestCode) {
|
||||
|
||||
//User search
|
||||
case MAIN_ACTIVITY_SEARCH_USER_INTENT:
|
||||
assert data.getData() != null;
|
||||
openUserPage(Integer.decode(data.getData().getQueryParameter("userID")));
|
||||
openUserPage(Integer.decode(
|
||||
Objects.requireNonNull(
|
||||
data.getData().getQueryParameter("userID"))));
|
||||
break;
|
||||
|
||||
|
||||
//Global search result
|
||||
case MAIN_ACTIVITY_GLOBAL_SEARCH_INTENT:
|
||||
assert data.getData() != null;
|
||||
|
||||
//Open user page or group accordingly to the choice of the user
|
||||
Uri result = data.getData();
|
||||
String type = result.getQueryParameter(SearchActivity.INTENT_ARG_RESULT_TYPE);
|
||||
int id = Integer.decode(Objects.requireNonNull(result.getQueryParameter(SearchActivity.INTENT_ARG_RESULT_ID)));
|
||||
if(Objects.equals(type, SearchActivity.INTENT_RESULT_USER))
|
||||
openUserPage(id);
|
||||
else
|
||||
onOpenGroup(id);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
@ -759,6 +781,17 @@ public class MainActivity extends BaseActivity implements
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a global search
|
||||
*/
|
||||
private void searchGlobal(){
|
||||
|
||||
//Make intent
|
||||
Intent intent = new Intent(this, SearchActivity.class);
|
||||
startActivityForResult(intent, MAIN_ACTIVITY_GLOBAL_SEARCH_INTENT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open group page
|
||||
*
|
||||
|
@ -0,0 +1,178 @@
|
||||
package org.communiquons.android.comunic.client.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.communiquons.android.comunic.client.R;
|
||||
import org.communiquons.android.comunic.client.data.models.SearchResultWithInfo;
|
||||
import org.communiquons.android.comunic.client.ui.Constants;
|
||||
import org.communiquons.android.comunic.client.ui.adapters.SearchResultsAdapter;
|
||||
import org.communiquons.android.comunic.client.ui.asynctasks.GlobalSearchTask;
|
||||
import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.OnOpenPageListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* Search activity
|
||||
*
|
||||
* This activity can be used to search both users and groups
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class SearchActivity extends BaseActivity implements TextWatcher, OnOpenPageListener {
|
||||
|
||||
/**
|
||||
* Debug tag
|
||||
*/
|
||||
private static final String TAG = SearchActivity.class.getSimpleName();
|
||||
|
||||
|
||||
/**
|
||||
* Results type
|
||||
*/
|
||||
public static final String INTENT_ARG_RESULT_ID = "id";
|
||||
public static final String INTENT_ARG_RESULT_TYPE = "type";
|
||||
public static final String INTENT_RESULT_USER = "user";
|
||||
public static final String INTENT_RESULT_GROUP = "group";
|
||||
|
||||
|
||||
/**
|
||||
* Adapters
|
||||
*/
|
||||
private SearchResultsAdapter mAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* Views
|
||||
*/
|
||||
private RecyclerView mRecyclerView;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search);
|
||||
|
||||
//Add go back button
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
((EditText)findViewById(R.id.searchInput)).addTextChangedListener(this);
|
||||
|
||||
//Initialize recycler view
|
||||
mRecyclerView = findViewById(R.id.resultsRecyclerView);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mAdapter = new SearchResultsAdapter(this ,this);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
|
||||
switch (item.getItemId()){
|
||||
|
||||
//Check if we have to finish activity
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
//Check if user did not type at least three characters
|
||||
if(s.length() < 3)
|
||||
return; //We ignore small researches
|
||||
|
||||
//Perform the search
|
||||
getTasksManager().unsetSpecificTasks(GlobalSearchTask.class);
|
||||
GlobalSearchTask task = new GlobalSearchTask(this);
|
||||
|
||||
task.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener<ArrayList<SearchResultWithInfo>>() {
|
||||
@Override
|
||||
public void OnPostExecute(@Nullable ArrayList<SearchResultWithInfo> searchResultWithInfoList) {
|
||||
onGotNewList(searchResultWithInfoList);
|
||||
}
|
||||
});
|
||||
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ""+s);
|
||||
getTasksManager().addTask(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
|
||||
private void onGotNewList(@Nullable ArrayList<SearchResultWithInfo> list){
|
||||
|
||||
//First, check for errors
|
||||
if(list == null){
|
||||
Toast.makeText(this, R.string.err_get_search_results, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
//Apply search results
|
||||
mAdapter.setList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpenGroup(int groupID) {
|
||||
sendResult(groupID, INTENT_RESULT_GROUP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpenGroupAccessDenied(int groupID) {
|
||||
onOpenGroup(groupID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openUserPage(int userID) {
|
||||
sendResult(userID, INTENT_RESULT_USER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openUserAccessDeniedPage(int userID) {
|
||||
openUserPage(userID);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called once the user has made a selection
|
||||
*
|
||||
* @param id The id of the element chosen by the user
|
||||
* @param type The type of the element chosen by the user
|
||||
*/
|
||||
private void sendResult(int id, String type){
|
||||
|
||||
//Send result and terminates activity
|
||||
Intent intent = new Intent(Constants.IntentResults.SEARCH_GLOBAL_RESULT);
|
||||
intent.setData(Uri.parse("?" + INTENT_ARG_RESULT_TYPE+"="+type+"&"+INTENT_ARG_RESULT_ID+"="+id));
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ import android.widget.Toast;
|
||||
import org.communiquons.android.comunic.client.R;
|
||||
import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper;
|
||||
import org.communiquons.android.comunic.client.data.helpers.GetUsersHelper;
|
||||
import org.communiquons.android.comunic.client.ui.Constants;
|
||||
import org.communiquons.android.comunic.client.ui.adapters.UsersBasicAdapter;
|
||||
import org.communiquons.android.comunic.client.data.models.UserInfo;
|
||||
|
||||
@ -81,7 +82,7 @@ public class SearchUserActivity extends AppCompatActivity
|
||||
*/
|
||||
private void onGotUserID(int userID){
|
||||
|
||||
Intent data = new Intent("org.communiquons.android.RESULT");
|
||||
Intent data = new Intent(Constants.IntentResults.SEARCH_USER_RESULT);
|
||||
data.setData(Uri.parse("?userID=" + userID));
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
|
@ -6,13 +6,11 @@ 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.listeners.OnGroupActionListener;
|
||||
import org.communiquons.android.comunic.client.ui.views.GroupImageView;
|
||||
import org.communiquons.android.comunic.client.ui.views.GroupMembershipStatusView;
|
||||
import org.communiquons.android.comunic.client.ui.viewholders.GroupViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -62,55 +60,12 @@ public class GroupsListAdapter extends BaseRecyclerViewAdapter {
|
||||
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);
|
||||
return new GroupViewHolder(view, mOnGroupActionListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
|
||||
((GroupHolder)viewHolder).bind(i);
|
||||
((GroupViewHolder)viewHolder).bind(mList.get(i));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Single group holder class
|
||||
*/
|
||||
private class GroupHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
|
||||
|
||||
private GroupInfo mGroupInfo;
|
||||
|
||||
|
||||
private GroupImageView mGroupImageView;
|
||||
private TextView mGroupName;
|
||||
private GroupMembershipStatusView mGroupMembershipStatus;
|
||||
|
||||
GroupHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
|
||||
mGroupImageView = itemView.findViewById(R.id.groupImage);
|
||||
mGroupName = itemView.findViewById(R.id.groupName);
|
||||
mGroupMembershipStatus = itemView.findViewById(R.id.groupMembershipStatusView);
|
||||
|
||||
mGroupMembershipStatus.setOnGroupMembershipUpdateListener(mOnGroupActionListener);
|
||||
}
|
||||
|
||||
GroupInfo getGroup(int pos){
|
||||
return mList.get(pos);
|
||||
}
|
||||
|
||||
void bind(int pos){
|
||||
mGroupInfo = getGroup(pos);
|
||||
mGroupImageView.setGroup(mGroupInfo);
|
||||
mGroupName.setText(mGroupInfo.getDisplayName());
|
||||
mGroupMembershipStatus.setGroup(mGroupInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(v.equals(itemView))
|
||||
mOnGroupActionListener.onOpenGroup(mGroupInfo.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,112 @@
|
||||
package org.communiquons.android.comunic.client.ui.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.communiquons.android.comunic.client.R;
|
||||
import org.communiquons.android.comunic.client.data.enums.KindSearchResult;
|
||||
import org.communiquons.android.comunic.client.data.models.SearchResultWithInfo;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.OnOpenPageListener;
|
||||
import org.communiquons.android.comunic.client.ui.viewholders.GroupViewHolder;
|
||||
import org.communiquons.android.comunic.client.ui.viewholders.UserViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Search results adapter
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class SearchResultsAdapter extends BaseRecyclerViewAdapter {
|
||||
|
||||
/**
|
||||
* The list of results to the search
|
||||
*/
|
||||
private ArrayList<SearchResultWithInfo> mList;
|
||||
|
||||
/**
|
||||
* Open listener
|
||||
*/
|
||||
private OnOpenPageListener openPageListener;
|
||||
|
||||
/**
|
||||
* Get view types
|
||||
*/
|
||||
private final int VIEW_TYPE_USER = 0;
|
||||
private final int VIEW_TYPE_GROUP = 1;
|
||||
|
||||
public SearchResultsAdapter(Context context, @Nullable OnOpenPageListener openPageListener) {
|
||||
super(context);
|
||||
|
||||
this.mList = new ArrayList<>();
|
||||
this.openPageListener = openPageListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set (update) the list of search results
|
||||
*
|
||||
* @param list New list to apply
|
||||
*/
|
||||
public void setList(ArrayList<SearchResultWithInfo> list){
|
||||
this.mList = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return mList.get(position).getKind() == KindSearchResult.USER ?
|
||||
VIEW_TYPE_USER : VIEW_TYPE_GROUP;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int type) {
|
||||
|
||||
RecyclerView.ViewHolder viewHolder;
|
||||
|
||||
if(type == VIEW_TYPE_USER){
|
||||
viewHolder = new UserViewHolder(LayoutInflater
|
||||
.from(getContext())
|
||||
.inflate(R.layout.viewholder_user, viewGroup, false)
|
||||
, openPageListener);
|
||||
}
|
||||
|
||||
else if(type == VIEW_TYPE_GROUP){
|
||||
viewHolder = new GroupViewHolder(LayoutInflater
|
||||
.from(getContext())
|
||||
.inflate(R.layout.viewholder_group, viewGroup, false)
|
||||
, openPageListener);
|
||||
}
|
||||
|
||||
else
|
||||
throw new RuntimeException("Intend to display a none supported kind of result!");
|
||||
|
||||
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
|
||||
|
||||
SearchResultWithInfo searchResultWithInfo = mList.get(i);
|
||||
|
||||
if(searchResultWithInfo.getKind() == KindSearchResult.USER){
|
||||
((UserViewHolder)viewHolder).bind(searchResultWithInfo.getUserInfo());
|
||||
}
|
||||
|
||||
if(searchResultWithInfo.getKind() == KindSearchResult.GROUP){
|
||||
((GroupViewHolder)viewHolder).bind(searchResultWithInfo.getGroupInfo());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -59,6 +59,7 @@ public class UsersBasicAdapter extends ArrayAdapter<UserInfo> {
|
||||
account_image.setUser(userInfos);
|
||||
}
|
||||
|
||||
|
||||
return convertView;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.communiquons.android.comunic.client.ui.asynctasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.communiquons.android.comunic.client.data.helpers.SearchHelper;
|
||||
import org.communiquons.android.comunic.client.data.models.SearchResult;
|
||||
import org.communiquons.android.comunic.client.data.models.SearchResultWithInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GlobalSearchTask extends SafeAsyncTask<String, Void, ArrayList<SearchResultWithInfo>> {
|
||||
|
||||
public GlobalSearchTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ArrayList<SearchResultWithInfo> doInBackground(String... strings) {
|
||||
|
||||
SearchHelper helper = new SearchHelper(getContext());
|
||||
|
||||
//First, perform the search itself
|
||||
ArrayList<SearchResult> list = helper.global(strings[0]);
|
||||
if(list == null)
|
||||
return null;
|
||||
|
||||
//Then get information about related users and groups
|
||||
return helper.fillResults(list);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.communiquons.android.comunic.client.ui.listeners;
|
||||
|
||||
/**
|
||||
* Implement this interface on activities that can open group and user pages
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public interface OnOpenPageListener extends OnOpenGroupListener, onOpenUsersPageListener {
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.communiquons.android.comunic.client.ui.viewholders;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
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.listeners.OnGroupActionListener;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.OnOpenGroupListener;
|
||||
import org.communiquons.android.comunic.client.ui.views.GroupImageView;
|
||||
import org.communiquons.android.comunic.client.ui.views.GroupMembershipStatusView;
|
||||
|
||||
/**
|
||||
* Single group holder class
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class GroupViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
|
||||
|
||||
private GroupInfo mGroupInfo;
|
||||
|
||||
private OnOpenGroupListener mOnOpenGroupListener;
|
||||
|
||||
private GroupImageView mGroupImageView;
|
||||
private TextView mGroupName;
|
||||
private GroupMembershipStatusView mGroupMembershipStatus;
|
||||
|
||||
|
||||
public GroupViewHolder(@NonNull View itemView, @Nullable OnOpenGroupListener openGroupListener){
|
||||
this(itemView, null);
|
||||
mOnOpenGroupListener = openGroupListener;
|
||||
}
|
||||
|
||||
public GroupViewHolder(@NonNull View itemView, @Nullable OnGroupActionListener actionListener) {
|
||||
super(itemView);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
|
||||
mGroupImageView = itemView.findViewById(R.id.groupImage);
|
||||
mGroupName = itemView.findViewById(R.id.groupName);
|
||||
mGroupMembershipStatus = itemView.findViewById(R.id.groupMembershipStatusView);
|
||||
|
||||
if(actionListener != null) {
|
||||
mGroupMembershipStatus.setOnGroupMembershipUpdateListener(actionListener);
|
||||
mOnOpenGroupListener = actionListener;
|
||||
}
|
||||
else
|
||||
mGroupMembershipStatus.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind (apply) a new group to the view
|
||||
*
|
||||
* @param group The group to apply to the view
|
||||
*/
|
||||
public void bind(GroupInfo group){
|
||||
mGroupInfo = group;
|
||||
mGroupImageView.setGroup(mGroupInfo);
|
||||
mGroupName.setText(mGroupInfo.getDisplayName());
|
||||
mGroupMembershipStatus.setGroup(mGroupInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(v.equals(itemView) && mOnOpenGroupListener != null)
|
||||
mOnOpenGroupListener.onOpenGroup(mGroupInfo.getId());
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package org.communiquons.android.comunic.client.ui.viewholders;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.communiquons.android.comunic.client.R;
|
||||
import org.communiquons.android.comunic.client.data.models.UserInfo;
|
||||
import org.communiquons.android.comunic.client.ui.listeners.onOpenUsersPageListener;
|
||||
import org.communiquons.android.comunic.client.ui.views.WebUserAccountImage;
|
||||
|
||||
/**
|
||||
* User view holder
|
||||
*
|
||||
* Handles displaying of a single user
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
public class UserViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||
|
||||
//Private fields
|
||||
private onOpenUsersPageListener mListener;
|
||||
private WebUserAccountImage mUserAccountImage;
|
||||
private TextView mUserName;
|
||||
private UserInfo mUserInfo;
|
||||
|
||||
public UserViewHolder(@NonNull View itemView, @Nullable onOpenUsersPageListener listener) {
|
||||
super(itemView);
|
||||
|
||||
mUserAccountImage = itemView.findViewById(R.id.user_account_image);
|
||||
mUserName = itemView.findViewById(R.id.user_name);
|
||||
|
||||
this.mListener = listener;
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply a new user to this view
|
||||
*
|
||||
* @param userInfo Information about the user to apply
|
||||
*/
|
||||
public void bind(UserInfo userInfo){
|
||||
this.mUserInfo = userInfo;
|
||||
mUserAccountImage.setUser(userInfo);
|
||||
mUserName.setText(userInfo.getDisplayFullName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(mListener != null && v.equals(itemView))
|
||||
mListener.openUserPage(mUserInfo.getId());
|
||||
}
|
||||
}
|
37
app/src/main/res/layout/activity_search.xml
Normal file
37
app/src/main/res/layout/activity_search.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.activities.SearchActivity">
|
||||
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:ems="10"
|
||||
android:inputType="textPersonName"
|
||||
android:hint="@string/input_search_hint"
|
||||
android:lines="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/resultsRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchInput" />
|
||||
</android.support.constraint.ConstraintLayout>
|
26
app/src/main/res/layout/viewholder_user.xml
Normal file
26
app/src/main/res/layout/viewholder_user.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:background="?selectableItemBackground"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.communiquons.android.comunic.client.ui.views.WebUserAccountImage
|
||||
android:id="@+id/user_account_image"
|
||||
android:layout_width="@dimen/account_image_default_width"
|
||||
android:layout_height="@dimen/account_image_default_height"
|
||||
android:src="@drawable/default_account_image" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/user_name"
|
||||
style="?textAppearanceListItem"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="User name"
|
||||
android:layout_gravity="center"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="1dp"/>
|
||||
</LinearLayout>
|
@ -9,8 +9,8 @@
|
||||
|
||||
<!-- Search user -->
|
||||
<item
|
||||
android:id="@+id/action_search_user"
|
||||
android:title="@string/main_menu_search_user" />
|
||||
android:id="@+id/action_search"
|
||||
android:title="@string/main_menu_search" />
|
||||
|
||||
<!-- Account settings -->
|
||||
<item
|
||||
|
@ -312,4 +312,11 @@
|
||||
<string name="dialog_leave_group_cancel">Annuler</string>
|
||||
<string name="dialog_leave_group_confirm">Quitter</string>
|
||||
<string name="err_update_group_membership">Une erreur a survenue lors de la mise à jour de votre appartenance au groupe !</string>
|
||||
<string name="main_menu_search">Rechercher</string>
|
||||
<string name="activity_search_title">Recherche</string>
|
||||
<string name="input_search_hint">Rechercher un utilisateur, un groupe…</string>
|
||||
<string name="err_get_search_results">Une erreur a survenue lors de la récupération du résultat de votre recherche !</string>
|
||||
<string name="notice_group_access_denied">Accès au groupe refusé.</string>
|
||||
<string name="err_get_group_info">Impossible de récupérer les informations sur le groupe !</string>
|
||||
<string name="notice_closed_registration">Accès sur invitation</string>
|
||||
</resources>
|
@ -314,4 +314,8 @@
|
||||
<string name="err_get_group_info">Could not get group information!</string>
|
||||
<string name="notice_group_access_denied">Access to the group denied.</string>
|
||||
<string name="notice_closed_registration">Invitation only</string>
|
||||
<string name="main_menu_search">Search</string>
|
||||
<string name="activity_search_title">Search</string>
|
||||
<string name="input_search_hint">Search a user, a group…</string>
|
||||
<string name="err_get_search_results">Could not get results of your search!</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user