blob: 4737406f80714f1c81d94a9709700a3718ecf973 [file] [log] [blame]
Loïc Siret0202fbf2017-09-28 16:34:28 -04001/*
Pierre Duchemin2802bfd2018-02-21 16:41:32 -05002 * Copyright (C) 2004-2018 Savoir-faire Linux Inc.
Loïc Siret0202fbf2017-09-28 16:34:28 -04003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
Aline Bonnet9c6defe2016-12-21 13:21:02 -050018package cx.ring.fragments;
19
Pierre Duchemin4af6b392018-02-02 11:23:56 -050020import android.Manifest;
Aline Bonnete8e87f62016-12-26 10:54:37 -050021import android.content.Context;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050022import android.content.Intent;
Aline Bonnet830c4c62016-12-27 14:02:02 -050023import android.content.res.Configuration;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050024import android.media.MediaScannerConnection;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050025import android.os.Bundle;
26import android.support.design.widget.Snackbar;
Pierre Duchemin4af6b392018-02-02 11:23:56 -050027import android.support.v4.app.ActivityCompat;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050028import android.support.v7.app.ActionBar;
29import android.support.v7.app.AlertDialog;
Aline Bonnete8e87f62016-12-26 10:54:37 -050030import android.support.v7.app.AppCompatActivity;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050031import android.support.v7.widget.DefaultItemAnimator;
32import android.support.v7.widget.LinearLayoutManager;
33import android.support.v7.widget.RecyclerView;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050034import android.util.Log;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050035import android.view.Menu;
36import android.view.MenuInflater;
37import android.view.MenuItem;
38import android.view.View;
39import android.view.ViewGroup;
40import android.view.inputmethod.EditorInfo;
41import android.widget.EditText;
Pierre Duchemin17542a72018-02-14 16:38:36 -050042import android.widget.ImageButton;
43import android.widget.ProgressBar;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050044import android.widget.Spinner;
Pierre Duchemin1fa61922018-01-18 10:09:02 -050045import android.widget.TextView;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050046import android.widget.Toast;
47
48import java.io.File;
49import java.io.IOException;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050050
Aline Bonnet9c6defe2016-12-21 13:21:02 -050051import butterknife.BindView;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050052import butterknife.OnClick;
53import butterknife.OnEditorAction;
54import cx.ring.R;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050055import cx.ring.adapters.ConversationAdapter;
56import cx.ring.adapters.NumberAdapter;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050057import cx.ring.client.CallActivity;
Aline Bonnet830c4c62016-12-27 14:02:02 -050058import cx.ring.client.ConversationActivity;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050059import cx.ring.client.HomeActivity;
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040060import cx.ring.conversation.ConversationPresenter;
61import cx.ring.conversation.ConversationView;
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -040062import cx.ring.dependencyinjection.RingInjectionComponent;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050063import cx.ring.model.CallContact;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050064import cx.ring.model.Conversation;
65import cx.ring.model.Phone;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050066import cx.ring.model.RingError;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050067import cx.ring.model.Uri;
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040068import cx.ring.mvp.BaseFragment;
Hadrien De Sousaccc947d2017-04-12 14:26:52 -040069import cx.ring.services.NotificationService;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050070import cx.ring.utils.ActionHelper;
71import cx.ring.utils.ClipboardHelper;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050072import cx.ring.utils.FileUtils;
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -050073import cx.ring.utils.MediaButtonsHelper;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050074
Pierre Duchemine0c3a492018-02-01 16:22:45 -050075import static android.app.Activity.RESULT_OK;
76
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040077public class ConversationFragment extends BaseFragment<ConversationPresenter> implements
Aline Bonnet9c6defe2016-12-21 13:21:02 -050078 Conversation.ConversationActionCallback,
79 ClipboardHelper.ClipboardHelperCallback,
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -050080 MediaButtonsHelper.MediaButtonsHelperCallback,
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040081 ConversationView {
Aline Bonnet9c6defe2016-12-21 13:21:02 -050082
Hadrien De Sousaccc947d2017-04-12 14:26:52 -040083 public static final int REQ_ADD_CONTACT = 42;
Hadrien De Sousaccc947d2017-04-12 14:26:52 -040084
Hadrien De Sousa0dc83162017-11-10 16:15:18 -050085 public static final String KEY_CONTACT_RING_ID = "CONTACT_RING_ID";
86 public static final String KEY_ACCOUNT_ID = "ACCOUNT_ID";
87
Aline Bonnet9c6defe2016-12-21 13:21:02 -050088 private static final String CONVERSATION_DELETE = "CONVERSATION_DELETE";
Aline Bonnet830c4c62016-12-27 14:02:02 -050089 private static final int MIN_SIZE_TABLET = 960;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050090
Pierre Duchemine0c3a492018-02-01 16:22:45 -050091 private static final int REQUEST_CODE_FILE_PICKER = 1000;
Pierre Duchemin4af6b392018-02-02 11:23:56 -050092 private static final int REQUEST_PERMISSION_CAMERA = 1001;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050093
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040094 @BindView(R.id.msg_input_txt)
95 protected EditText mMsgEditTxt;
96
97 @BindView(R.id.ongoingcall_pane)
Hadrien De Sousaccc947d2017-04-12 14:26:52 -040098 protected ViewGroup mTopPane;
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040099
100 @BindView(R.id.hist_list)
101 protected RecyclerView mHistList;
102
103 @BindView(R.id.number_selector)
104 protected Spinner mNumberSpinner;
105
Pierre Duchemin17542a72018-02-14 16:38:36 -0500106 @BindView(R.id.pb_data_transfer)
107 protected ProgressBar pbDataTransfer;
108
109 @BindView(R.id.send_data)
110 protected ImageButton sendData;
111
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500112 @BindView(R.id.cvMessageInput)
113 protected View mMessageInput;
114
115 @BindView(R.id.llTrustRequestPrompt)
116 protected View mTrustRequestPrompt;
117
118 @BindView(R.id.llTrustRequestMessage)
119 protected View mLlTrustRequestMessage;
120
121 @BindView(R.id.tvTrustRequestMessage)
122 protected TextView mTvTrustRequestMessage;
123
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500124 private AlertDialog mDeleteDialog;
125 private boolean mDeleteConversation = false;
126
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500127 private MenuItem mAddContactBtn = null;
128
129 private ConversationAdapter mAdapter = null;
130 private NumberAdapter mNumberAdapter = null;
131
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500132 public static boolean isTabletMode(Context context) {
Aline Bonnet830c4c62016-12-27 14:02:02 -0500133 return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE
134 && context.getResources().getConfiguration().screenWidthDp >= MIN_SIZE_TABLET;
135 }
136
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500137 private static int getIndex(Spinner spinner, Uri myString) {
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500138 for (int i = 0, n = spinner.getCount(); i < n; i++)
139 if (((Phone) spinner.getItemAtPosition(i)).getNumber().equals(myString)) {
140 return i;
141 }
142 return 0;
143 }
144
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400145 @Override
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500146 public void refreshView(final Conversation conversation) {
Adrien Béraud20d42212018-03-02 14:40:38 -0500147 if (conversation == null) {
148 return;
149 }
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500150 getActivity().runOnUiThread(() -> {
151 if (mAdapter != null) {
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500152 mAdapter.updateDataset(conversation.getAggregateHistory());
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400153
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500154 // moves to last message
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500155 if (mAdapter.getItemCount() > 0) {
156 mHistList.smoothScrollToPosition(mAdapter.getItemCount() - 1);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400157 }
Aline Bonneteb5f7ff2017-01-17 11:09:17 -0500158 }
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500159 getActivity().invalidateOptionsMenu();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400160 });
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500161 }
162
Aline Bonnete8e87f62016-12-26 10:54:37 -0500163 @Override
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400164 public int getLayout() {
165 return R.layout.frag_conversation;
166 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500167
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400168 @Override
169 public void injectFragment(RingInjectionComponent component) {
170 component.inject(this);
171 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500172
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400173 @Override
174 public void onViewCreated(View view, Bundle savedInstanceState) {
175 super.onViewCreated(view, savedInstanceState);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500176
Hadrien De Sousaccc947d2017-04-12 14:26:52 -0400177 if (mTopPane != null) {
178 mTopPane.setVisibility(View.GONE);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500179 }
180
181 LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
182 mLayoutManager.setStackFromEnd(true);
183
184 if (mHistList != null) {
185 mHistList.setLayoutManager(mLayoutManager);
186 mHistList.setAdapter(mAdapter);
187 mHistList.setItemAnimator(new DefaultItemAnimator());
188 }
189
190 // reload delete conversation state (before rotation)
191 mDeleteConversation = savedInstanceState != null && savedInstanceState.getBoolean(CONVERSATION_DELETE);
192
193 setHasOptionsMenu(true);
Aline Bonnete8e87f62016-12-26 10:54:37 -0500194
Pierre Duchemin4af6b392018-02-02 11:23:56 -0500195 mAdapter = new ConversationAdapter(this, presenter);
Alexandre Lision62c69782017-04-04 17:26:44 -0400196
197 if (mHistList != null) {
198 mHistList.setAdapter(mAdapter);
199 }
200
201 if (mDeleteConversation) {
202 presenter.deleteAction();
Aline Bonnete8e87f62016-12-26 10:54:37 -0500203 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500204 }
205
206 @OnClick(R.id.msg_send)
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500207 public void sendMessageText() {
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500208 presenter.sendTextMessage(mMsgEditTxt.getText().toString());
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500209 }
210
Pierre Duchemin17542a72018-02-14 16:38:36 -0500211 @OnClick(R.id.send_data)
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500212 public void selectFile() {
213 presenter.selectFile();
214 }
215
216 @Override
Pierre Duchemin4af6b392018-02-02 11:23:56 -0500217 public void askWriteExternalStoragePermission() {
218 ActivityCompat.requestPermissions(getActivity(),
219 new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
220 REQUEST_PERMISSION_CAMERA);
221 }
222
223 @Override
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500224 public void openFilePicker() {
225 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
226 intent.addCategory(Intent.CATEGORY_OPENABLE);
227 intent.setType("*/*");
228
229 startActivityForResult(intent, REQUEST_CODE_FILE_PICKER);
230 }
231
232 @Override
Pierre Duchemin17542a72018-02-14 16:38:36 -0500233 public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
234 super.onActivityResult(requestCode, resultCode, resultData);
235
236 if (requestCode == REQUEST_CODE_FILE_PICKER && resultCode == RESULT_OK) {
237 if (resultData != null) {
238 android.net.Uri uri = resultData.getData();
239 if (uri == null) {
240 return;
241 }
242
243 new Thread(() -> {
244 getActivity().runOnUiThread(() -> setLoading(true));
245
246 try {
247 File cacheFile = FileUtils.getCacheFile(getActivity(), uri);
248 presenter.sendFile(cacheFile.toString());
249 } catch (IOException e) {
250 Log.e(TAG, "onActivityResult: not able to create cache file");
251 getActivity().runOnUiThread(() -> displayErrorToast(RingError.INVALID_FILE));
252 }
253
254 getActivity().runOnUiThread(() -> setLoading(false));
255 }).start();
256 }
257 }
258 }
259
260 @Override
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500261 public void writeCacheFile(String cacheFilename) {
Adrien Béraud20d42212018-03-02 14:40:38 -0500262 // todo use rx + move to presenter
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500263 File cacheFile = new File(getActivity().getCacheDir(), cacheFilename);
264 try {
265 String finalFilePath = FileUtils.writeCacheFileToExtStorage(getActivity(), android.net.Uri.fromFile(cacheFile), cacheFile.getName());
266
267 // Tell the media scanner about the new file so that it is immediately available to the user
268 MediaScannerConnection.scanFile(getActivity(), new String[]{finalFilePath}, null, null);
269
270 getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), getActivity().getString(R.string.file_saved_in, finalFilePath), Toast.LENGTH_LONG).show());
271 } catch (IOException e) {
272 Log.e(TAG, "writeCacheFile: ", e);
273 getActivity().runOnUiThread(() -> displayErrorToast(RingError.NOT_ABLE_TO_WRITE_FILE));
274 }
275 }
276
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500277 @OnEditorAction(R.id.msg_input_txt)
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500278 public boolean actionSendMsgText(int actionId) {
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500279 switch (actionId) {
280 case EditorInfo.IME_ACTION_SEND:
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500281 presenter.sendTextMessage(mMsgEditTxt.getText().toString());
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500282 return true;
283 }
284 return false;
285 }
286
287 @OnClick(R.id.ongoingcall_pane)
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500288 public void onClick() {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400289 presenter.clickOnGoingPane();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500290 }
291
292 @Override
293 public void onPause() {
294 super.onPause();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400295 presenter.pause();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500296 }
297
298 @Override
299 public void onResume() {
300 super.onResume();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400301 presenter.resume();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500302 }
303
304 @Override
305 public void onDestroy() {
306 if (mDeleteConversation) {
307 mDeleteDialog.dismiss();
308 }
309
310 super.onDestroy();
311 }
312
313 @Override
314 public void onSaveInstanceState(Bundle outState) {
315 super.onSaveInstanceState(outState);
316
317 // persist the delete popup state in case of Activity rotation
318 mDeleteConversation = mDeleteDialog != null && mDeleteDialog.isShowing();
319 outState.putBoolean(CONVERSATION_DELETE, mDeleteConversation);
320 }
321
322 @Override
323 public void onPrepareOptionsMenu(Menu menu) {
324 super.onPrepareOptionsMenu(menu);
Hadrien De Sousaf5774ee2017-05-17 14:04:17 -0400325 presenter.prepareMenu();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500326 }
327
328 @Override
329 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400330 inflater.inflate(R.menu.conversation_actions, menu);
331 mAddContactBtn = menu.findItem(R.id.menuitem_addcontact);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500332 }
333
334 @Override
335 public boolean onOptionsItemSelected(MenuItem item) {
336 switch (item.getItemId()) {
337 case android.R.id.home:
338 startActivity(new Intent(getActivity(), HomeActivity.class));
339 return true;
340 case R.id.conv_action_audiocall:
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500341 presenter.callWithAudioOnly(true);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500342 return true;
343 case R.id.conv_action_videocall:
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500344 presenter.callWithAudioOnly(false);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500345 return true;
346 case R.id.menuitem_addcontact:
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400347 presenter.addContact();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500348 return true;
349 case R.id.menuitem_delete:
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400350 presenter.deleteAction();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500351 return true;
352 case R.id.menuitem_copy_content:
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400353 presenter.copyToClipboard();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500354 return true;
Aline Bonnet54cf69b2017-03-28 12:03:45 -0400355 case R.id.menuitem_block:
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400356 presenter.blockContact();
Aline Bonnet54cf69b2017-03-28 12:03:45 -0400357 return true;
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500358 default:
359 return super.onOptionsItemSelected(item);
360 }
361 }
362
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500363 @Override
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500364 public void deleteConversation(CallContact callContact) {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400365 presenter.deleteConversation();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500366 }
367
368 @Override
369 public void copyContactNumberToClipboard(String contactNumber) {
370 ClipboardHelper.copyNumberToClipboard(getActivity(), contactNumber, this);
371 }
372
373 @Override
374 public void clipBoardDidCopyNumber(String copiedNumber) {
375 View view = getActivity().findViewById(android.R.id.content);
376 if (view != null) {
377 String snackbarText = getString(R.string.conversation_action_copied_peer_number_clipboard,
Alexandre Lision6fd56c82017-01-30 09:05:54 -0500378 ActionHelper.getShortenedNumber(copiedNumber));
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500379 Snackbar.make(view, snackbarText, Snackbar.LENGTH_LONG).show();
380 }
381 }
382
383 @Override
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400384 protected void initPresenter(ConversationPresenter presenter) {
385 super.initPresenter(presenter);
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500386 String contactRingID = getArguments().getString(KEY_CONTACT_RING_ID);
387 String accountId = getArguments().getString(KEY_ACCOUNT_ID);
388 presenter.init(contactRingID, accountId);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400389 }
390
391 @Override
392 public void updateView(final String address, final String name, final int state) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500393 getActivity().runOnUiThread(() -> {
394 if (state != 0 || mNumberAdapter == null || mNumberAdapter.isEmpty()) {
395 return;
396 }
Aline Bonneteb5f7ff2017-01-17 11:09:17 -0500397
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500398 for (int i = 0; i < mNumberAdapter.getCount(); i++) {
399 Phone phone = (Phone) mNumberAdapter.getItem(i);
400 if (phone.getNumber() != null) {
401 String ringID = phone.getNumber().getRawUriString();
402 if (address.equals(ringID)) {
403 phone.getNumber().setUsername(name);
404 mNumberAdapter.notifyDataSetChanged();
Aline Bonneteb5f7ff2017-01-17 11:09:17 -0500405 }
406 }
407 }
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400408 });
409 }
410
411 @Override
Cyrille Béraud35b5a892017-07-22 17:20:13 -0400412 public void displayContactName(final CallContact contact) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500413 getActivity().runOnUiThread(() -> {
414 ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
415 if (actionBar == null) {
416 return;
417 }
418 String displayName = contact.getDisplayName();
419 actionBar.setTitle(displayName);
420 String identity = contact.getRingUsername();
421 if (identity != null && !identity.equals(displayName)) {
422 actionBar.setSubtitle(identity);
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500423 }
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400424 });
425 }
426
427 @Override
428 public void displayOnGoingCallPane(final boolean display) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500429 getActivity().runOnUiThread(() -> mTopPane.setVisibility(display ? View.VISIBLE : View.GONE));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400430 }
431
432 @Override
Alexandre Lision62c69782017-04-04 17:26:44 -0400433 public void displayContactPhoto(final byte[] photo) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500434 getActivity().runOnUiThread(() -> mAdapter.setPhoto(photo));
Alexandre Lision62c69782017-04-04 17:26:44 -0400435 }
436
437 @Override
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400438 public void displayNumberSpinner(final Conversation conversation, final Uri number) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500439 getActivity().runOnUiThread(() -> {
440 mNumberSpinner.setVisibility(View.VISIBLE);
441 mNumberAdapter = new NumberAdapter(getActivity(),
442 conversation.getContact(),
443 false);
444 mNumberSpinner.setAdapter(mNumberAdapter);
445 mNumberSpinner.setSelection(getIndex(mNumberSpinner, number));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400446 });
447 }
448
449 @Override
450 public void displayAddContact(final boolean display) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500451 getActivity().runOnUiThread(() -> {
452 if (mAddContactBtn != null) {
453 mAddContactBtn.setVisible(display);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400454 }
455 });
456 }
457
458 @Override
459 public void displayDeleteDialog(final Conversation conversation) {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500460 getActivity().runOnUiThread(() -> mDeleteDialog = ActionHelper.launchDeleteAction(getActivity(),
461 conversation.getContact(),
462 ConversationFragment.this));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400463 }
464
465 @Override
466 public void displayCopyToClipboard(CallContact callContact) {
467 ActionHelper.launchCopyNumberToClipboardFromContact(getActivity(),
468 callContact,
469 this);
470 }
471
472 @Override
473 public void hideNumberSpinner() {
Pierre Duchemin45707ca2018-01-15 15:05:23 -0500474 getActivity().runOnUiThread(() -> mNumberSpinner.setVisibility(View.GONE));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400475 }
476
477 @Override
478 public void clearMsgEdit() {
479 mMsgEditTxt.setText("");
480 }
481
482 @Override
483 public void goToHome() {
484 if (getActivity() instanceof ConversationActivity) {
485 getActivity().finish();
Aline Bonneteb5f7ff2017-01-17 11:09:17 -0500486 }
487 }
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400488
489 @Override
490 public void goToAddContact(CallContact callContact) {
491 startActivityForResult(ActionHelper.getAddNumberIntentForContact(callContact), REQ_ADD_CONTACT);
492 }
493
494 @Override
495 public void goToCallActivity(String conferenceId) {
496 startActivity(new Intent(Intent.ACTION_VIEW)
497 .setClass(getActivity().getApplicationContext(), CallActivity.class)
Hadrien De Sousaccc947d2017-04-12 14:26:52 -0400498 .putExtra(NotificationService.KEY_CALL_ID, conferenceId));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400499 }
500
501 @Override
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500502 public void goToCallActivityWithResult(String accountId, String contactRingId, boolean audioOnly) {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400503 Intent intent = new Intent(CallActivity.ACTION_CALL)
504 .setClass(getActivity().getApplicationContext(), CallActivity.class)
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500505 .putExtra(KEY_ACCOUNT_ID, accountId)
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500506 .putExtra(CallFragment.KEY_AUDIO_ONLY, audioOnly)
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500507 .putExtra(KEY_CONTACT_RING_ID, contactRingId);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400508 startActivityForResult(intent, HomeActivity.REQUEST_CODE_CALL);
509 }
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500510
511 @Override
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500512 @OnClick(R.id.btnBlock)
513 public void blockContactRequest() {
514 presenter.onBlockIncomingContactRequest();
515 }
516
517 @Override
518 @OnClick(R.id.btnRefuse)
519 public void refuseContactRequest() {
520 presenter.onRefuseIncomingContactRequest();
521 }
522
523 @Override
524 @OnClick(R.id.btnAccept)
525 public void acceptContactRequest() {
526 presenter.onAcceptIncomingContactRequest();
527 }
528
529 @Override
530 public void switchToIncomingTrustRequestView(String contactDisplayName) {
531 mMessageInput.setVisibility(View.GONE);
532 mTvTrustRequestMessage.setText(String.format(getString(R.string.message_contact_not_trusted_yet), contactDisplayName));
533 mTrustRequestPrompt.setVisibility(View.VISIBLE);
534 mLlTrustRequestMessage.setVisibility(View.VISIBLE);
535 }
536
537 @Override
538 public void switchToConversationView() {
539 mMessageInput.setVisibility(View.VISIBLE);
540 mTrustRequestPrompt.setVisibility(View.GONE);
541 mLlTrustRequestMessage.setVisibility(View.GONE);
542 }
543
544 @Override
545 public void positiveMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500546 presenter.clickOnGoingPane();
547 }
548
549 @Override
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500550 public void negativeMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500551 presenter.clickOnGoingPane();
552 }
553
554 @Override
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500555 public void toggleMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500556 presenter.clickOnGoingPane();
557 }
Pierre Duchemin17542a72018-02-14 16:38:36 -0500558
559 private void setLoading(boolean isLoading) {
560 if (isLoading) {
561 sendData.setVisibility(View.GONE);
562 pbDataTransfer.setVisibility(View.VISIBLE);
563 } else {
564 sendData.setVisibility(View.VISIBLE);
565 pbDataTransfer.setVisibility(View.GONE);
566 }
567 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500568}