Can create calls

This commit is contained in:
Pierre HUBERT 2019-02-16 16:01:14 +01:00
parent 0a8ecf3fdf
commit 2c0867b1bb
11 changed files with 350 additions and 5 deletions

View File

@ -0,0 +1,15 @@
package org.communiquons.android.comunic.client.data.enums;
/**
* Single member call status
*
* @author Pierre HUBERT
*/
public enum MemberCallStatus {
ACCEPTED,
REJECTED,
UNKNOWN,
HANG_UP
}

View File

@ -3,9 +3,13 @@ package org.communiquons.android.comunic.client.data.helpers;
import android.content.Context;
import android.support.annotation.Nullable;
import org.communiquons.android.comunic.client.data.enums.MemberCallStatus;
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.CallInformation;
import org.communiquons.android.comunic.client.data.models.CallMember;
import org.communiquons.android.comunic.client.data.models.CallsConfiguration;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -48,7 +52,7 @@ public class CallsHelper extends BaseHelper {
APIResponse response = request.exec();
//Parse response
mCallsConfiguration = JSONObjectToCallConfiguration(response.getJSONObject());
mCallsConfiguration = JSONObjectToCallsConfiguration(response.getJSONObject());
} catch (Exception e) {
@ -60,10 +64,13 @@ public class CallsHelper extends BaseHelper {
/**
* Get Calls configuration, if available
*
* Note if IsCallSystemAvailable returned TRUE, it is guaranteed that this method WILL NOT
* return null
*
* @return Calls configuration
*/
@Nullable
public static CallsConfiguration getCallConfiguration(){
public static CallsConfiguration GetCallsConfiguration(){
return mCallsConfiguration;
}
@ -76,10 +83,38 @@ public class CallsHelper extends BaseHelper {
*
* @return TRUE if call system is available / FALSE else
*/
public static boolean isCallSystemAvailable(){
public static boolean IsCallSystemAvailable(){
return mCallsConfiguration != null && mCallsConfiguration.isEnabled();
}
/**
* Create a call for a conversation, returns information about this call then
*
* Note : if a similar call already exists, it will be returned instead of
* creating a new call
*
* @param convID The ID of the target conversation
* @return Information about the created call / null in case of failure
*/
@Nullable
public CallInformation createForConversation(int convID){
APIRequest request = new APIRequest(getContext(), "calls/createForConversation");
request.addInt("conversationID", convID);
try {
//Execute request
APIResponse response = request.exec();
return JSONObjectToCallInformation(response.getJSONObject());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Turn a {@link JSONObject} object into a {@link CallsConfiguration} object.
@ -88,7 +123,7 @@ public class CallsHelper extends BaseHelper {
* @return The result of the operation
* @throws JSONException Exception thrown in case of failure
*/
private static CallsConfiguration JSONObjectToCallConfiguration(JSONObject object)
private static CallsConfiguration JSONObjectToCallsConfiguration(JSONObject object)
throws JSONException {
CallsConfiguration config = new CallsConfiguration();
@ -109,4 +144,60 @@ public class CallsHelper extends BaseHelper {
return config;
}
/**
* Turn a {@link JSONObject} into {@link CallInformation} object
*
* @param object object to convert
* @return Generated CallInformation object
* @throws JSONException in case of failure
*/
private static CallInformation JSONObjectToCallInformation(JSONObject object)
throws JSONException {
CallInformation call = new CallInformation();
call.setId(object.getInt("id"));
call.setConversationID(object.getInt("conversation_id"));
call.setLastActive(object.getInt("last_active"));
JSONArray members = object.getJSONArray("members");
for (int i = 0; i < members.length(); i++) {
JSONObject member_obj = members.getJSONObject(i);
call.addMember(new CallMember(
member_obj.getInt("userID"),
member_obj.getInt("call_id"),
member_obj.getString("user_call_id"),
StringToMemberCallStatus(member_obj.getString("status"))
));
}
return call;
}
/**
* Turn a string into a {@link MemberCallStatus}
*
* @param s String to convert
* @return Generated MemberCallStatus
*/
private static MemberCallStatus StringToMemberCallStatus(String s){
switch (s){
case "accepted":
return MemberCallStatus.ACCEPTED;
case "rejected":
return MemberCallStatus.REJECTED;
case "hang_up":
return MemberCallStatus.HANG_UP;
case "unknown":
default:
return MemberCallStatus.UNKNOWN;
}
}
}

View File

@ -0,0 +1,60 @@
package org.communiquons.android.comunic.client.data.models;
import android.support.annotation.NonNull;
import java.util.ArrayList;
/**
* Single call information
*
* @author Pierre HUBERT
*/
public class CallInformation {
//Private fields
private int id;
private int conversationID;
private int lastActive;
private ArrayList<CallMember> members = null;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getConversationID() {
return conversationID;
}
public void setConversationID(int conversationID) {
this.conversationID = conversationID;
}
public int getLastActive() {
return lastActive;
}
public void setLastActive(int lastActive) {
this.lastActive = lastActive;
}
public ArrayList<CallMember> getMembers() {
return members;
}
public void addMember(@NonNull CallMember member){
if(members == null)
members = new ArrayList<>();
members.add(member);
}
public void setMembers(ArrayList<CallMember> members) {
this.members = members;
}
}

View File

@ -0,0 +1,59 @@
package org.communiquons.android.comunic.client.data.models;
import org.communiquons.android.comunic.client.data.enums.MemberCallStatus;
/**
* Single call member information
*
* @author Pierre HUBERT
*/
public class CallMember {
//Private fields
private int userID;
private int callID;
private String userCallID;
private MemberCallStatus status;
public CallMember() {
}
public CallMember(int userID, int callID, String userCallID, MemberCallStatus status) {
this.userID = userID;
this.callID = callID;
this.userCallID = userCallID;
this.status = status;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public int getCallID() {
return callID;
}
public void setCallID(int callID) {
this.callID = callID;
}
public String getUserCallID() {
return userCallID;
}
public void setUserCallID(String userCallID) {
this.userCallID = userCallID;
}
public MemberCallStatus getStatus() {
return status;
}
public void setStatus(MemberCallStatus status) {
this.status = status;
}
}

View File

@ -2,6 +2,7 @@ package org.communiquons.android.comunic.client.ui.activities;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@ -31,11 +32,13 @@ import org.communiquons.android.comunic.client.data.helpers.AccountHelper;
import org.communiquons.android.comunic.client.data.helpers.ConversationsListHelper;
import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper;
import org.communiquons.android.comunic.client.data.helpers.DebugHelper;
import org.communiquons.android.comunic.client.data.models.CallInformation;
import org.communiquons.android.comunic.client.data.models.NotificationsCount;
import org.communiquons.android.comunic.client.data.models.VirtualDirectory;
import org.communiquons.android.comunic.client.data.runnables.FriendRefreshLoopRunnable;
import org.communiquons.android.comunic.client.data.services.NotificationsService;
import org.communiquons.android.comunic.client.data.utils.PreferencesUtils;
import org.communiquons.android.comunic.client.ui.asynctasks.CreateCallForConversationTask;
import org.communiquons.android.comunic.client.ui.asynctasks.FindVirtualDirectoryTask;
import org.communiquons.android.comunic.client.ui.asynctasks.GetCallConfigurationTask;
import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask;
@ -51,6 +54,7 @@ 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.OnOpenCallListener;
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;
@ -71,7 +75,7 @@ import static org.communiquons.android.comunic.client.ui.Constants.IntentRequest
*/
public class MainActivity extends BaseActivity implements
openConversationListener, updateConversationListener, OnOpenPageListener,
onPostOpenListener, NavigationBar.OnNavigationItemSelectedListener {
onPostOpenListener, NavigationBar.OnNavigationItemSelectedListener, OnOpenCallListener {
/**
* Debug tag
@ -840,4 +844,37 @@ public class MainActivity extends BaseActivity implements
transaction.replace(R.id.main_fragment, fragment);
transaction.commit();
}
@Override
public void createCallForConversation(int convID) {
final Dialog dialog = UiUtils.create_loading_dialog(this);
//Create the call for the conversation
CreateCallForConversationTask task = new CreateCallForConversationTask(this);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, convID);
getTasksManager().addTask(task, true);
task.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener<CallInformation>() {
@Override
public void OnPostExecute(@Nullable CallInformation callInformation) {
dialog.dismiss();
//Check for errors
if(callInformation == null)
Toast.makeText(
MainActivity.this,
R.string.err_create_call_for_conversation,
Toast.LENGTH_SHORT).show();
else
//Open call
openCall(callInformation.getId());
}
});
}
@Override
public void openCall(int callID) {
Log.e(TAG, "Open call " + callID);
}
}

View File

@ -0,0 +1,23 @@
package org.communiquons.android.comunic.client.ui.asynctasks;
import android.content.Context;
import org.communiquons.android.comunic.client.data.helpers.CallsHelper;
import org.communiquons.android.comunic.client.data.models.CallInformation;
/**
* Task used to create new calls from conversations
*
* @author Pierre HUBERT
*/
public class CreateCallForConversationTask extends SafeAsyncTask<Integer, Void, CallInformation> {
public CreateCallForConversationTask(Context context) {
super(context);
}
@Override
protected CallInformation doInBackground(Integer... integers) {
return new CallsHelper(getContext()).createForConversation(integers[0]);
}
}

View File

@ -26,6 +26,7 @@ import android.widget.Toast;
import org.communiquons.android.comunic.client.R;
import org.communiquons.android.comunic.client.data.arrays.ConversationMessagesList;
import org.communiquons.android.comunic.client.data.helpers.CallsHelper;
import org.communiquons.android.comunic.client.data.helpers.ConversationMessagesHelper;
import org.communiquons.android.comunic.client.data.helpers.ConversationsListHelper;
import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper;
@ -43,6 +44,7 @@ import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask;
import org.communiquons.android.comunic.client.ui.asynctasks.SendConversationMessageTask;
import org.communiquons.android.comunic.client.ui.asynctasks.UpdateConversationMessageContentTask;
import org.communiquons.android.comunic.client.ui.listeners.OnConversationMessageActionsListener;
import org.communiquons.android.comunic.client.ui.listeners.OnOpenCallListener;
import org.communiquons.android.comunic.client.ui.listeners.OnScrollChangeDetectListener;
import org.communiquons.android.comunic.client.ui.utils.BitmapUtils;
import org.communiquons.android.comunic.client.ui.utils.UiUtils;
@ -51,6 +53,7 @@ import org.communiquons.android.comunic.client.ui.views.ScrollRecyclerView;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Objects;
import static android.app.Activity.RESULT_OK;
import static org.communiquons.android.comunic.client.ui.Constants.IntentRequestCode.CONVERSATION_MESSAGE_PICK_PHOTO;
@ -174,6 +177,11 @@ public class ConversationFragment extends Fragment
*/
private Bitmap new_message_bitmap = null;
/**
* Contains whether a call button is visible on the conversation or not
*/
private boolean mHasCallButton = false;
/**
* Get user helper
*/
@ -392,6 +400,7 @@ public class ConversationFragment extends Fragment
}
@Override
public void onDestroy() {
super.onDestroy();
@ -516,6 +525,23 @@ public class ConversationFragment extends Fragment
//Update the name of the conversation
setTitle(info.getDisplayName());
//Add call button (if possible)
if(CallsHelper.IsCallSystemAvailable() && info.getMembers().size() > 1 && info.getMembers().size() <=
Objects.requireNonNull(CallsHelper.GetCallsConfiguration()).getMaximumNumberMembers() &&
!mHasCallButton) {
mHasCallButton = true;
mAppBar.addButton(R.drawable.ic_call, new View.OnClickListener() {
@Override
public void onClick(View v) {
((OnOpenCallListener)Objects.requireNonNull(getActivity()))
.createCallForConversation(conversation_id);
}
});
}
}
/**

View File

@ -0,0 +1,23 @@
package org.communiquons.android.comunic.client.ui.listeners;
/**
* Open call listener
*
* @author Pierre HUBERT
*/
public interface OnOpenCallListener {
/**
* Create and open a call for a conversation
*
* @param convID The ID of the target conversation
*/
void createCallForConversation(int convID);
/**
* Open a specifed call
*
* @param callID The ID of the target call
*/
void openCall(int callID);
}

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/default_drawable_color"
android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z"/>
</vector>

View File

@ -319,4 +319,5 @@
<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>
<string name="err_create_call_for_conversation">Une erreur a survenu lors de la création d\'un appel pour la conversation !</string>
</resources>

View File

@ -318,4 +318,5 @@
<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>
<string name="err_create_call_for_conversation">Could not create a call for the conversation!</string>
</resources>