blob: aed7060a6b3206e58de987ce2e818b1f509c11d0 [file] [log] [blame]
Loïc Siret0202fbf2017-09-28 16:34:28 -04001/*
Sébastien Blinab53ada2019-01-02 17:23:00 -05002 * Copyright (C) 2004-2019 Savoir-faire Linux Inc.
Loïc Siret0202fbf2017-09-28 16:34:28 -04003 *
Adrien Béraud64538722018-03-15 17:34:00 -04004 * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
5 *
Loïc Siret0202fbf2017-09-28 16:34:28 -04006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
Aline Bonnet9c6defe2016-12-21 13:21:02 -050020package cx.ring.fragments;
21
Pierre Duchemin4af6b392018-02-02 11:23:56 -050022import android.Manifest;
Adrien Béraud772e2162019-02-12 16:00:21 -050023import android.animation.ValueAnimator;
Adrien Béraud1b8ac9f2018-05-31 14:34:23 -040024import android.app.DownloadManager;
Rayan Osseirane4450272019-06-03 14:17:19 -040025import android.content.ActivityNotFoundException;
Adrien Béraudae45ffa2018-07-06 16:21:29 -040026import android.content.ClipData;
Adrien Béraud1b8ac9f2018-05-31 14:34:23 -040027import android.content.Context;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050028import android.content.Intent;
Adrien Béraud3a875a02018-07-18 17:54:17 -040029import android.content.SharedPreferences;
Adrien Béraud4f542f92019-01-03 12:17:53 -050030import android.content.pm.PackageManager;
Adrien Béraud78ae7b92018-08-25 19:04:17 -040031import android.graphics.drawable.BitmapDrawable;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050032import android.os.Bundle;
Adrien Béraud64538722018-03-15 17:34:00 -040033import android.provider.MediaStore;
Adrien Béraud3c483ce2019-01-02 17:33:49 -050034
35import androidx.annotation.NonNull;
Adrien Béraudb28c4912018-12-02 22:58:52 -050036import androidx.annotation.Nullable;
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -050037
Adrien Béraud8bc95102018-08-25 22:34:51 -040038import androidx.core.content.FileProvider;
39import androidx.appcompat.app.ActionBar;
Adrien Béraud8bc95102018-08-25 22:34:51 -040040import androidx.appcompat.app.AppCompatActivity;
41import androidx.recyclerview.widget.DefaultItemAnimator;
Adrien Béraud8bc95102018-08-25 22:34:51 -040042
Adrien Béraud3a875a02018-07-18 17:54:17 -040043import android.text.Editable;
Adrien Béraud58bd92b2018-08-23 10:54:25 -040044import android.text.TextUtils;
Adrien Béraud3a875a02018-07-18 17:54:17 -040045import android.text.TextWatcher;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050046import android.util.Log;
Adrien Béraudb28c4912018-12-02 22:58:52 -050047import android.view.LayoutInflater;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050048import android.view.Menu;
49import android.view.MenuInflater;
50import android.view.MenuItem;
51import android.view.View;
52import android.view.ViewGroup;
53import android.view.inputmethod.EditorInfo;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050054import android.widget.Spinner;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050055import android.widget.Toast;
56
Rayan Osseirane4450272019-06-03 14:17:19 -040057import com.google.android.material.snackbar.Snackbar;
58
Pierre Duchemine0c3a492018-02-01 16:22:45 -050059import java.io.File;
60import java.io.IOException;
Adrien Béraudace37a22018-06-22 14:58:36 -040061import java.util.List;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050062
Aline Bonnet9c6defe2016-12-21 13:21:02 -050063import butterknife.OnEditorAction;
Adrien Béraud5b47cb52018-07-06 16:24:14 -040064import cx.ring.BuildConfig;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050065import cx.ring.R;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050066import cx.ring.adapters.ConversationAdapter;
67import cx.ring.adapters.NumberAdapter;
Adrien Béraudb28c4912018-12-02 22:58:52 -050068import cx.ring.application.RingApplication;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050069import cx.ring.client.CallActivity;
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -050070import cx.ring.client.ContactDetailsActivity;
Aline Bonnet830c4c62016-12-27 14:02:02 -050071import cx.ring.client.ConversationActivity;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050072import cx.ring.client.HomeActivity;
Adrien Béraud78ae7b92018-08-25 19:04:17 -040073import cx.ring.contacts.AvatarFactory;
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -040074import cx.ring.conversation.ConversationPresenter;
75import cx.ring.conversation.ConversationView;
Adrien Béraudb28c4912018-12-02 22:58:52 -050076import cx.ring.databinding.FragConversationBinding;
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -040077import cx.ring.dependencyinjection.RingInjectionComponent;
Adrien Béraud171ba362018-12-14 21:35:40 -050078import cx.ring.interfaces.Colorable;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050079import cx.ring.model.CallContact;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050080import cx.ring.model.Conversation;
Adrien Béraudace37a22018-06-22 14:58:36 -040081import cx.ring.model.ConversationElement;
Adrien Béraud21533292018-03-22 14:11:35 -040082import cx.ring.model.DataTransfer;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050083import cx.ring.model.Phone;
Pierre Duchemine0c3a492018-02-01 16:22:45 -050084import cx.ring.model.RingError;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050085import cx.ring.model.Uri;
Adrien Bérauda373e3b2018-12-12 11:14:50 -050086import cx.ring.mvp.BaseSupportFragment;
Hadrien De Sousaccc947d2017-04-12 14:26:52 -040087import cx.ring.services.NotificationService;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050088import cx.ring.utils.ActionHelper;
Adrien Béraud64538722018-03-15 17:34:00 -040089import cx.ring.utils.AndroidFileUtils;
Adrien Béraud64538722018-03-15 17:34:00 -040090import cx.ring.utils.ContentUriHandler;
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -050091import cx.ring.utils.MediaButtonsHelper;
Adrien Béraud44939482019-02-13 21:42:08 -050092import io.reactivex.Completable;
93import io.reactivex.Single;
Adrien Béraud78ae7b92018-08-25 19:04:17 -040094import io.reactivex.android.schedulers.AndroidSchedulers;
95import io.reactivex.disposables.Disposable;
Adrien Béraud44939482019-02-13 21:42:08 -050096import io.reactivex.schedulers.Schedulers;
Aline Bonnet9c6defe2016-12-21 13:21:02 -050097
Pierre Duchemine0c3a492018-02-01 16:22:45 -050098import static android.app.Activity.RESULT_OK;
99
Adrien Bérauda373e3b2018-12-12 11:14:50 -0500100public class ConversationFragment extends BaseSupportFragment<ConversationPresenter> implements
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500101 MediaButtonsHelper.MediaButtonsHelperCallback,
Adrien Bérauda373e3b2018-12-12 11:14:50 -0500102 ConversationView, SharedPreferences.OnSharedPreferenceChangeListener
103{
Adrien Béraud64538722018-03-15 17:34:00 -0400104 protected static final String TAG = ConversationFragment.class.getSimpleName();
105
Hadrien De Sousaccc947d2017-04-12 14:26:52 -0400106 public static final int REQ_ADD_CONTACT = 42;
Hadrien De Sousaccc947d2017-04-12 14:26:52 -0400107
Adrien Béraud6ac63632018-12-09 00:11:21 -0500108 public static final String KEY_CONTACT_RING_ID = BuildConfig.APPLICATION_ID + ".CONTACT_RING_ID";
109 public static final String KEY_ACCOUNT_ID = BuildConfig.APPLICATION_ID + ".ACCOUNT_ID";
Adrien Béraud3a875a02018-07-18 17:54:17 -0400110 public static final String KEY_PREFERENCE_PENDING_MESSAGE = "pendingMessage";
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500111 public static final String KEY_PREFERENCE_CONVERSATION_COLOR = "color";
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500112
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500113 private static final int REQUEST_CODE_FILE_PICKER = 1000;
Pierre Duchemin4af6b392018-02-02 11:23:56 -0500114 private static final int REQUEST_PERMISSION_CAMERA = 1001;
Adrien Béraud64538722018-03-15 17:34:00 -0400115 private static final int REQUEST_CODE_TAKE_PICTURE = 1002;
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500116
Adrien Béraudb28c4912018-12-02 22:58:52 -0500117 private FragConversationBinding binding;
Adrien Béraud5b47cb52018-07-06 16:24:14 -0400118 private MenuItem mAudioCallBtn = null;
119 private MenuItem mVideoCallBtn = null;
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500120
121 private ConversationAdapter mAdapter = null;
122 private NumberAdapter mNumberAdapter = null;
Adrien Béraud772e2162019-02-12 16:00:21 -0500123 private int marginPx;
124 private final ValueAnimator animation = new ValueAnimator();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500125
Adrien Béraud3a875a02018-07-18 17:54:17 -0400126 private SharedPreferences mPreferences;
127
Adrien Béraud64538722018-03-15 17:34:00 -0400128 private File mCurrentPhoto = null;
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400129 private Disposable actionbarTarget = null;
Adrien Béraud64538722018-03-15 17:34:00 -0400130
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500131 private static int getIndex(Spinner spinner, Uri myString) {
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500132 for (int i = 0, n = spinner.getCount(); i < n; i++)
133 if (((Phone) spinner.getItemAtPosition(i)).getNumber().equals(myString)) {
134 return i;
135 }
136 return 0;
137 }
138
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400139 @Override
Adrien Béraudace37a22018-06-22 14:58:36 -0400140 public void refreshView(final List<ConversationElement> conversation) {
Adrien Béraud20d42212018-03-02 14:40:38 -0500141 if (conversation == null) {
142 return;
143 }
Adrien Béraudb28c4912018-12-02 22:58:52 -0500144 if (binding != null)
145 binding.pbLoading.setVisibility(View.GONE);
Adrien Béraudace37a22018-06-22 14:58:36 -0400146 if (mAdapter != null) {
147 mAdapter.updateDataset(conversation);
148 }
149 getActivity().invalidateOptionsMenu();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500150 }
151
Aline Bonnete8e87f62016-12-26 10:54:37 -0500152 @Override
Adrien Béraud64538722018-03-15 17:34:00 -0400153 public void scrollToEnd() {
Adrien Béraudace37a22018-06-22 14:58:36 -0400154 if (mAdapter.getItemCount() > 0) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500155 binding.histList.scrollToPosition(mAdapter.getItemCount() - 1);
Adrien Béraudace37a22018-06-22 14:58:36 -0400156 }
Adrien Béraud64538722018-03-15 17:34:00 -0400157 }
158
159 @Override
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400160 public int getLayout() {
161 return R.layout.frag_conversation;
162 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500163
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400164 @Override
165 public void injectFragment(RingInjectionComponent component) {
166 component.inject(this);
167 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500168
Adrien Béraudb28c4912018-12-02 22:58:52 -0500169 @Nullable
170 @Override
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500171 public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500172 injectFragment(((RingApplication) getActivity().getApplication()).getRingInjectionComponent());
Adrien Béraud772e2162019-02-12 16:00:21 -0500173 marginPx = getResources().getDimensionPixelSize(R.dimen.margin_message_input);
174 animation.setDuration(150);
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500175 binding = FragConversationBinding.inflate(inflater, container, false);
Adrien Béraudb28c4912018-12-02 22:58:52 -0500176 binding.setPresenter(this);
177 return binding.getRoot();
178 }
179
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400180 @Override
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500181 public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
Hadrien De Sousa73d6dd72017-09-07 10:54:51 -0400182 super.onViewCreated(view, savedInstanceState);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500183
Adrien Béraud1af6c012019-05-25 23:20:29 -0400184 binding.msgInputTxt.setMediaListener(contentInfo -> startFileSend(AndroidFileUtils
185 .getCacheFile(requireContext(), contentInfo.getContentUri())
186 .flatMapCompletable(this::sendFile)
187 .doFinally(contentInfo::releasePermission)));
188
Adrien Béraud3a875a02018-07-18 17:54:17 -0400189 if (mPreferences != null) {
190 String pendingMessage = mPreferences.getString(KEY_PREFERENCE_PENDING_MESSAGE, null);
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400191 if (!TextUtils.isEmpty(pendingMessage)) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500192 binding.msgInputTxt.setText(pendingMessage);
193 binding.msgSend.setVisibility(View.VISIBLE);
194 binding.emojiSend.setVisibility(View.GONE);
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400195 }
Adrien Béraud3a875a02018-07-18 17:54:17 -0400196 }
Adrien Béraudb28c4912018-12-02 22:58:52 -0500197 binding.msgInputTxt.setOnEditorActionListener((v, actionId, event) -> actionSendMsgText(actionId));
198 binding.msgInputTxt.addTextChangedListener(new TextWatcher() {
Adrien Béraud3a875a02018-07-18 17:54:17 -0400199 @Override
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500200 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
201 }
Adrien Béraud3a875a02018-07-18 17:54:17 -0400202
203 @Override
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500204 public void onTextChanged(CharSequence s, int start, int before, int count) {
205 }
Adrien Béraud3a875a02018-07-18 17:54:17 -0400206
207 @Override
208 public void afterTextChanged(Editable s) {
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400209 String message = s.toString();
210 if (TextUtils.isEmpty(message)) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500211 binding.msgSend.setVisibility(View.GONE);
212 binding.emojiSend.setVisibility(View.VISIBLE);
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400213 } else {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500214 binding.msgSend.setVisibility(View.VISIBLE);
215 binding.emojiSend.setVisibility(View.GONE);
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400216 }
Adrien Béraud3a875a02018-07-18 17:54:17 -0400217 if (mPreferences != null) {
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400218 mPreferences.edit().putString(KEY_PREFERENCE_PENDING_MESSAGE, message).apply();
Adrien Béraud3a875a02018-07-18 17:54:17 -0400219 }
220 }
221 });
Adrien Béraud9d4a81f2018-07-09 01:19:52 -0400222
Adrien Béraud772e2162019-02-12 16:00:21 -0500223 animation.addUpdateListener(valueAnimator -> binding.histList.setPadding(
224 binding.histList.getPaddingLeft(),
225 binding.histList.getPaddingTop(),
226 binding.histList.getPaddingRight(),
227 Integer.parseInt(valueAnimator.getAnimatedValue().toString())));
228
229 binding.msgInputTxt.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
230 if (animation.isStarted())
231 animation.cancel();
232 animation.setIntValues(binding.histList.getPaddingBottom(), binding.msgInputTxt.getHeight() + marginPx);
233 animation.start();
234 });
235
Adrien Béraudb28c4912018-12-02 22:58:52 -0500236 if (binding != null) {
237 binding.ongoingcallPane.setVisibility(View.GONE);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500238 }
239
Adrien Béraudb28c4912018-12-02 22:58:52 -0500240 DefaultItemAnimator animator = (DefaultItemAnimator) binding.histList.getItemAnimator();
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500241 if (animator != null)
242 animator.setSupportsChangeAnimations(false);
Adrien Béraudb28c4912018-12-02 22:58:52 -0500243 binding.histList.setAdapter(mAdapter);
Adrien Béraude5ec8952018-07-11 15:14:44 -0400244 setHasOptionsMenu(true);
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500245 }
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500246
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500247 @Override
248 public void setConversationColor(int color) {
Adrien Béraud171ba362018-12-14 21:35:40 -0500249 Colorable activity = (Colorable) getActivity();
250 if (activity != null)
251 activity.setColor(color);
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500252 mAdapter.setPrimaryColor(color);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500253 }
254
Adrien Béraud7c505112018-03-20 16:03:28 -0400255 @Override
Adrien Béraud4030d2e2018-12-02 23:08:03 -0500256 public void onDestroyView() {
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500257 if (mPreferences != null)
258 mPreferences.unregisterOnSharedPreferenceChangeListener(this);
Adrien Béraud772e2162019-02-12 16:00:21 -0500259 animation.removeAllUpdateListeners();
Adrien Béraudb28c4912018-12-02 22:58:52 -0500260 binding.histList.setAdapter(null);
Adrien Béraud4030d2e2018-12-02 23:08:03 -0500261 super.onDestroyView();
262 }
263
264 @Override
Adrien Béraud7c505112018-03-20 16:03:28 -0400265 public boolean onContextItemSelected(MenuItem item) {
266 if (mAdapter.onContextItemSelected(item))
267 return true;
268 return super.onContextItemSelected(item);
269 }
270
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500271 public void sendMessageText() {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500272 String message = binding.msgInputTxt.getText().toString();
Adrien Béraudace37a22018-06-22 14:58:36 -0400273 clearMsgEdit();
274 presenter.sendTextMessage(message);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500275 }
276
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400277 public void sendEmoji() {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500278 presenter.sendTextMessage(binding.emojiSend.getText().toString());
Adrien Béraud58bd92b2018-08-23 10:54:25 -0400279 }
280
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500281 public void selectFile() {
282 presenter.selectFile();
283 }
284
Adrien Béraud64538722018-03-15 17:34:00 -0400285 public void takePicture() {
Adrien Béraud4f542f92019-01-03 12:17:53 -0500286 if (!presenter.getDeviceRuntimeService().hasVideoPermission()) {
287 requestPermissions(new String[]{Manifest.permission.CAMERA}, RingApplication.PERMISSIONS_REQUEST);
288 } else {
Adrien Béraudf5c32f92019-01-03 23:40:00 -0500289 Context c = getContext();
290 if (c == null)
291 return;
Adrien Béraud4f542f92019-01-03 12:17:53 -0500292 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Adrien Béraudf5c32f92019-01-03 23:40:00 -0500293 if (takePictureIntent.resolveActivity(c.getPackageManager()) != null) {
Adrien Béraud4f542f92019-01-03 12:17:53 -0500294 // Create the File where the photo should go
Adrien Béraud44939482019-02-13 21:42:08 -0500295 File photoFile;
Adrien Béraud4f542f92019-01-03 12:17:53 -0500296 try {
Adrien Béraudf5c32f92019-01-03 23:40:00 -0500297 photoFile = AndroidFileUtils.createImageFile(c);
Adrien Béraud4f542f92019-01-03 12:17:53 -0500298 } catch (IOException ex) {
299 Log.e(TAG, "takePicture: error creating temporary file", ex);
300 return;
301 }
302 Log.i(TAG, "takePicture: trying to save to " + photoFile);
303 mCurrentPhoto = photoFile;
Adrien Béraudf5c32f92019-01-03 23:40:00 -0500304 android.net.Uri photoURI = FileProvider.getUriForFile(c, ContentUriHandler.AUTHORITY_FILES, photoFile);
Adrien Béraud4f542f92019-01-03 12:17:53 -0500305 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
306 startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_PICTURE);
Adrien Béraud64538722018-03-15 17:34:00 -0400307 }
Adrien Béraud64538722018-03-15 17:34:00 -0400308 }
309 }
310
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500311 @Override
Pierre Duchemin4af6b392018-02-02 11:23:56 -0500312 public void askWriteExternalStoragePermission() {
Adrien Béraud4f542f92019-01-03 12:17:53 -0500313 requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RingApplication.PERMISSIONS_REQUEST);
Pierre Duchemin4af6b392018-02-02 11:23:56 -0500314 }
315
316 @Override
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500317 public void openFilePicker() {
318 Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
319 intent.addCategory(Intent.CATEGORY_OPENABLE);
320 intent.setType("*/*");
321
322 startActivityForResult(intent, REQUEST_CODE_FILE_PICKER);
323 }
324
Adrien Béraud44939482019-02-13 21:42:08 -0500325 private Completable sendFile(File file) {
326 return Completable.fromAction(() -> presenter.sendFile(file));
327 }
328
Adrien Béraud44939482019-02-13 21:42:08 -0500329 private void startFileSend(Completable op) {
330 setLoading(true);
Adrien Béraud1af6c012019-05-25 23:20:29 -0400331 op.observeOn(AndroidSchedulers.mainThread())
Adrien Béraud44939482019-02-13 21:42:08 -0500332 .doFinally(() -> setLoading(false))
333 .subscribe(() -> {}, e -> {
334 Log.e(TAG, "startFileSend: not able to create cache file", e);
335 displayErrorToast(RingError.INVALID_FILE);
336 });
337 }
338
Pierre Duchemine0c3a492018-02-01 16:22:45 -0500339 @Override
Pierre Duchemin17542a72018-02-14 16:38:36 -0500340 public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
Adrien Béraud64538722018-03-15 17:34:00 -0400341 Log.w(TAG, "onActivityResult: " + requestCode + " " + resultCode + " " + resultData);
Pierre Duchemin17542a72018-02-14 16:38:36 -0500342 super.onActivityResult(requestCode, resultCode, resultData);
343
344 if (requestCode == REQUEST_CODE_FILE_PICKER && resultCode == RESULT_OK) {
Adrien Béraud64538722018-03-15 17:34:00 -0400345 if (resultData == null) {
346 return;
Pierre Duchemin17542a72018-02-14 16:38:36 -0500347 }
Adrien Béraud64538722018-03-15 17:34:00 -0400348 android.net.Uri uri = resultData.getData();
349 if (uri == null) {
350 return;
351 }
Adrien Béraud1af6c012019-05-25 23:20:29 -0400352 startFileSend(AndroidFileUtils.getCacheFile(requireContext(), uri)
353 .observeOn(AndroidSchedulers.mainThread())
354 .flatMapCompletable(this::sendFile));
Adrien Béraud64538722018-03-15 17:34:00 -0400355 } else if (requestCode == REQUEST_CODE_TAKE_PICTURE) {
356 if (resultCode != RESULT_OK) {
357 mCurrentPhoto = null;
358 return;
359 }
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500360 Log.w(TAG, "onActivityResult: mCurrentPhoto " + mCurrentPhoto.getAbsolutePath() + " " + mCurrentPhoto.exists() + " " + mCurrentPhoto.length());
Adrien Béraud64538722018-03-15 17:34:00 -0400361 if (mCurrentPhoto == null || !mCurrentPhoto.exists() || mCurrentPhoto.length() == 0) {
362 Toast.makeText(getActivity(), "Can't find picture", Toast.LENGTH_SHORT).show();
363 }
Adrien Béraud44939482019-02-13 21:42:08 -0500364 File file = mCurrentPhoto;
365 mCurrentPhoto = null;
366 startFileSend(sendFile(file));
Pierre Duchemin17542a72018-02-14 16:38:36 -0500367 }
368 }
369
370 @Override
Adrien Béraud4f542f92019-01-03 12:17:53 -0500371 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
372 super.onRequestPermissionsResult(requestCode, permissions, grantResults);
373 for (int i = 0, n = permissions.length; i < n; i++) {
374 switch (permissions[i]) {
375 case Manifest.permission.CAMERA:
376 boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
Rayan Osseiran38206c62019-05-15 14:49:03 -0400377 presenter.cameraPermissionChanged(granted);
Adrien Béraud4f542f92019-01-03 12:17:53 -0500378 if (granted) {
379 takePicture();
380 }
381 return;
382 default:
383 break;
384 }
385 }
386 }
387
388 @Override
Adrien Béraudace37a22018-06-22 14:58:36 -0400389 public void addElement(ConversationElement element) {
390 mAdapter.add(element);
391 scrollToEnd();
392 }
Adrien Béraud3cbc7fa2018-07-18 18:36:21 -0400393
Adrien Béraudace37a22018-06-22 14:58:36 -0400394 @Override
395 public void updateElement(ConversationElement element) {
396 mAdapter.update(element);
397 }
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500398
Adrien Béraudace37a22018-06-22 14:58:36 -0400399 @Override
400 public void removeElement(ConversationElement element) {
401 mAdapter.remove(element);
Adrien Béraud21533292018-03-22 14:11:35 -0400402 }
403
Adrien Béraudfcf457f2018-04-03 17:46:34 -0400404 @Override
405 public void shareFile(File path) {
Adrien Béraud50549532019-01-03 12:22:16 -0500406 Context c = getContext();
407 if (c == null)
408 return;
Adrien Béraudfcf457f2018-04-03 17:46:34 -0400409 android.net.Uri fileUri = null;
410 try {
Adrien Béraud50549532019-01-03 12:22:16 -0500411 fileUri = FileProvider.getUriForFile(c, ContentUriHandler.AUTHORITY_FILES, path);
Adrien Béraudfcf457f2018-04-03 17:46:34 -0400412 } catch (IllegalArgumentException e) {
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500413 Log.e("File Selector", "The selected file can't be shared: " + path.getName());
Adrien Béraudfcf457f2018-04-03 17:46:34 -0400414 }
415 if (fileUri != null) {
416 Intent sendIntent = new Intent();
417 sendIntent.setAction(Intent.ACTION_SEND);
418 sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Adrien Béraud50549532019-01-03 12:22:16 -0500419 String type = c.getContentResolver().getType(fileUri);
Adrien Béraudfcf457f2018-04-03 17:46:34 -0400420 sendIntent.setDataAndType(fileUri, type);
421 sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
422 startActivity(Intent.createChooser(sendIntent, null));
423 }
424 }
425
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500426 @Override
427 public void openFile(File path) {
Adrien Béraud50549532019-01-03 12:22:16 -0500428 Context c = getContext();
429 if (c == null)
430 return;
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500431 android.net.Uri fileUri = null;
432 try {
Adrien Béraud50549532019-01-03 12:22:16 -0500433 fileUri = FileProvider.getUriForFile(c, ContentUriHandler.AUTHORITY_FILES, path);
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500434 } catch (IllegalArgumentException e) {
435 Log.e("File Selector", "The selected file can't be shared: " + path.getName());
436 }
437 if (fileUri != null) {
438 Intent sendIntent = new Intent();
439 sendIntent.setAction(Intent.ACTION_VIEW);
440 sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Adrien Béraud50549532019-01-03 12:22:16 -0500441 String type = c.getContentResolver().getType(fileUri);
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500442 sendIntent.setDataAndType(fileUri, type);
443 sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
444 //startActivity(Intent.createChooser(sendIntent, null));
Rayan Osseirane4450272019-06-03 14:17:19 -0400445 try {
446 startActivity(sendIntent);
447 } catch (ActivityNotFoundException e) {
448 Snackbar.make(getView(), R.string.conversation_open_file_error, Snackbar.LENGTH_LONG).show();
449 Log.e("File Loader", "File of unknown type, could not open: " + path.getName());
450 }
Adrien Béraudb2b3f442018-12-01 17:42:38 -0500451 }
452 }
453
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500454 @OnEditorAction(R.id.msg_input_txt)
Adrien Béraud44939482019-02-13 21:42:08 -0500455 boolean actionSendMsgText(int actionId) {
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500456 switch (actionId) {
457 case EditorInfo.IME_ACTION_SEND:
Adrien Béraudace37a22018-06-22 14:58:36 -0400458 sendMessageText();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500459 return true;
460 }
461 return false;
462 }
463
Alexandre Lision66a9f9a2017-02-26 20:28:27 -0500464 public void onClick() {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400465 presenter.clickOnGoingPane();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500466 }
467
468 @Override
469 public void onPause() {
470 super.onPause();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400471 presenter.pause();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500472 }
473
474 @Override
475 public void onResume() {
476 super.onResume();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400477 presenter.resume();
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500478 }
479
480 @Override
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400481 public void onDetach() {
482 if (actionbarTarget != null) {
483 actionbarTarget.dispose();
484 actionbarTarget = null;
485 }
486 super.onDetach();
487 }
488
489 @Override
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500490 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400491 inflater.inflate(R.menu.conversation_actions, menu);
Adrien Béraud5b47cb52018-07-06 16:24:14 -0400492 mAudioCallBtn = menu.findItem(R.id.conv_action_audiocall);
493 mVideoCallBtn = menu.findItem(R.id.conv_action_videocall);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500494 }
495
496 @Override
497 public boolean onOptionsItemSelected(MenuItem item) {
498 switch (item.getItemId()) {
499 case android.R.id.home:
500 startActivity(new Intent(getActivity(), HomeActivity.class));
501 return true;
502 case R.id.conv_action_audiocall:
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500503 presenter.callWithAudioOnly(true);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500504 return true;
505 case R.id.conv_action_videocall:
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500506 presenter.callWithAudioOnly(false);
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500507 return true;
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500508 case R.id.conv_contact_details:
509 presenter.openContact();
Aline Bonnet54cf69b2017-03-28 12:03:45 -0400510 return true;
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500511 default:
512 return super.onOptionsItemSelected(item);
513 }
514 }
515
Aline Bonnet9c6defe2016-12-21 13:21:02 -0500516 @Override
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400517 protected void initPresenter(ConversationPresenter presenter) {
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500518 Bundle args = getArguments();
519 if (args == null)
520 return;
521 Uri contactUri = new Uri(args.getString(KEY_CONTACT_RING_ID));
522 String accountId = args.getString(KEY_ACCOUNT_ID);
523 mAdapter = new ConversationAdapter(this, presenter);
524 presenter.init(contactUri, accountId);
Adrien Béraud56c34132018-11-29 13:32:00 -0500525 try {
Adrien Béraud44939482019-02-13 21:42:08 -0500526 mPreferences = requireActivity().getSharedPreferences(accountId + "_" + contactUri.getRawRingId(), Context.MODE_PRIVATE);
Adrien Béraud3c483ce2019-01-02 17:33:49 -0500527 mPreferences.registerOnSharedPreferenceChangeListener(this);
528 presenter.setConversationColor(mPreferences.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light)));
Adrien Béraud56c34132018-11-29 13:32:00 -0500529 } catch (Exception e) {
530 Log.e(TAG, "Can't load conversation preferences");
531 }
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500532 }
533
534 @Override
535 public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
536 switch (key) {
537 case KEY_PREFERENCE_CONVERSATION_COLOR:
538 presenter.setConversationColor(prefs.getInt(KEY_PREFERENCE_CONVERSATION_COLOR, getResources().getColor(R.color.color_primary_light)));
539 break;
540 }
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400541 }
542
543 @Override
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400544 public void displayContact(final CallContact contact) {
Adrien Béraud44939482019-02-13 21:42:08 -0500545 ActionBar actionBar = ((AppCompatActivity) requireActivity()).getSupportActionBar();
Adrien Béraudace37a22018-06-22 14:58:36 -0400546 if (actionBar == null) {
547 return;
548 }
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400549 Context context = actionBar.getThemedContext();
Adrien Béraudace37a22018-06-22 14:58:36 -0400550 String displayName = contact.getDisplayName();
551 actionBar.setTitle(displayName);
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400552
553 if (actionbarTarget != null) {
554 actionbarTarget.dispose();
555 actionbarTarget = null;
556 }
557 int targetSize = (int) (AvatarFactory.SIZE_AB * context.getResources().getDisplayMetrics().density);
558 actionbarTarget = AvatarFactory.getBitmapAvatar(context, contact, targetSize)
559 .observeOn(AndroidSchedulers.mainThread())
560 .subscribe(b -> actionBar.setLogo(new BitmapDrawable(context.getResources(), b)));
561
Adrien Béraudace37a22018-06-22 14:58:36 -0400562 String identity = contact.getRingUsername();
563 if (identity != null && !identity.equals(displayName)) {
564 actionBar.setSubtitle(identity);
565 }
Adrien Béraud78ae7b92018-08-25 19:04:17 -0400566
567 mAdapter.setPhoto();
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400568 }
569
570 @Override
571 public void displayOnGoingCallPane(final boolean display) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500572 binding.ongoingcallPane.setVisibility(display ? View.VISIBLE : View.GONE);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400573 }
574
575 @Override
576 public void displayNumberSpinner(final Conversation conversation, final Uri number) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500577 binding.numberSelector.setVisibility(View.VISIBLE);
Adrien Béraudace37a22018-06-22 14:58:36 -0400578 mNumberAdapter = new NumberAdapter(getActivity(),
579 conversation.getContact(),
580 false);
Adrien Béraudb28c4912018-12-02 22:58:52 -0500581 binding.numberSelector.setAdapter(mNumberAdapter);
582 binding.numberSelector.setSelection(getIndex(binding.numberSelector, number));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400583 }
584
585 @Override
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400586 public void hideNumberSpinner() {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500587 binding.numberSelector.setVisibility(View.GONE);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400588 }
589
590 @Override
591 public void clearMsgEdit() {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500592 binding.msgInputTxt.setText("");
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400593 }
594
595 @Override
596 public void goToHome() {
597 if (getActivity() instanceof ConversationActivity) {
598 getActivity().finish();
Aline Bonneteb5f7ff2017-01-17 11:09:17 -0500599 }
600 }
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400601
602 @Override
603 public void goToAddContact(CallContact callContact) {
604 startActivityForResult(ActionHelper.getAddNumberIntentForContact(callContact), REQ_ADD_CONTACT);
605 }
606
607 @Override
608 public void goToCallActivity(String conferenceId) {
609 startActivity(new Intent(Intent.ACTION_VIEW)
Adrien Béraud44939482019-02-13 21:42:08 -0500610 .setClass(requireActivity().getApplicationContext(), CallActivity.class)
Hadrien De Sousaccc947d2017-04-12 14:26:52 -0400611 .putExtra(NotificationService.KEY_CALL_ID, conferenceId));
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400612 }
613
614 @Override
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500615 public void goToContactActivity(String accountId, String contactRingId) {
616 startActivity(new Intent(Intent.ACTION_VIEW, android.net.Uri.withAppendedPath(android.net.Uri.withAppendedPath(ContentUriHandler.CONTACT_CONTENT_URI, accountId), contactRingId))
Adrien Béraud44939482019-02-13 21:42:08 -0500617 .setClass(requireActivity().getApplicationContext(), ContactDetailsActivity.class));
Adrien Béraud0f3ee3d2018-12-08 22:03:54 -0500618 }
619
620 @Override
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500621 public void goToCallActivityWithResult(String accountId, String contactRingId, boolean audioOnly) {
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400622 Intent intent = new Intent(CallActivity.ACTION_CALL)
Adrien Béraud44939482019-02-13 21:42:08 -0500623 .setClass(requireActivity().getApplicationContext(), CallActivity.class)
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500624 .putExtra(KEY_ACCOUNT_ID, accountId)
Hadrien De Sousa203164c2017-12-05 17:41:42 -0500625 .putExtra(CallFragment.KEY_AUDIO_ONLY, audioOnly)
Hadrien De Sousa0dc83162017-11-10 16:15:18 -0500626 .putExtra(KEY_CONTACT_RING_ID, contactRingId);
Hadrien De Sousaec95e5e2017-03-21 15:28:23 -0400627 startActivityForResult(intent, HomeActivity.REQUEST_CODE_CALL);
628 }
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500629
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500630 public void blockContactRequest() {
631 presenter.onBlockIncomingContactRequest();
632 }
633
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500634 public void refuseContactRequest() {
635 presenter.onRefuseIncomingContactRequest();
636 }
637
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500638 public void acceptContactRequest() {
639 presenter.onAcceptIncomingContactRequest();
640 }
641
Adrien Béraudace37a22018-06-22 14:58:36 -0400642 public void addContact() {
643 presenter.onAddContact();
644 }
645
646 @Override
Adrien Béraud5b47cb52018-07-06 16:24:14 -0400647 public void onPrepareOptionsMenu(Menu menu) {
648 super.onPrepareOptionsMenu(menu);
Adrien Béraudb28c4912018-12-02 22:58:52 -0500649 boolean visible = binding.cvMessageInput.getVisibility() == View.VISIBLE;
Adrien Béraud5b47cb52018-07-06 16:24:14 -0400650 if (mAudioCallBtn != null)
651 mAudioCallBtn.setVisible(visible);
652 if (mVideoCallBtn != null)
653 mVideoCallBtn.setVisible(visible);
654 }
655
656 @Override
Adrien Béraudace37a22018-06-22 14:58:36 -0400657 public void switchToUnknownView(String contactDisplayName) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500658 binding.cvMessageInput.setVisibility(View.GONE);
659 binding.unknownContactPrompt.setVisibility(View.VISIBLE);
660 binding.trustRequestPrompt.setVisibility(View.GONE);
661 binding.tvTrustRequestMessage.setText(String.format(getString(R.string.message_contact_not_trusted), contactDisplayName));
662 binding.trustRequestMessageLayout.setVisibility(View.VISIBLE);
Adrien Béraud44939482019-02-13 21:42:08 -0500663 requireActivity().invalidateOptionsMenu();
Adrien Béraudace37a22018-06-22 14:58:36 -0400664 }
665
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500666 @Override
667 public void switchToIncomingTrustRequestView(String contactDisplayName) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500668 binding.cvMessageInput.setVisibility(View.GONE);
669 binding.unknownContactPrompt.setVisibility(View.GONE);
670 binding.trustRequestPrompt.setVisibility(View.VISIBLE);
671 binding.tvTrustRequestMessage.setText(String.format(getString(R.string.message_contact_not_trusted_yet), contactDisplayName));
672 binding.trustRequestMessageLayout.setVisibility(View.VISIBLE);
Adrien Béraud44939482019-02-13 21:42:08 -0500673 requireActivity().invalidateOptionsMenu();
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500674 }
675
676 @Override
677 public void switchToConversationView() {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500678 binding.cvMessageInput.setVisibility(View.VISIBLE);
679 binding.unknownContactPrompt.setVisibility(View.GONE);
680 binding.trustRequestPrompt.setVisibility(View.GONE);
681 binding.trustRequestMessageLayout.setVisibility(View.GONE);
Adrien Béraud44939482019-02-13 21:42:08 -0500682 requireActivity().invalidateOptionsMenu();
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500683 }
684
685 @Override
686 public void positiveMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500687 presenter.clickOnGoingPane();
688 }
689
690 @Override
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500691 public void negativeMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500692 presenter.clickOnGoingPane();
693 }
694
695 @Override
Pierre Duchemin1fa61922018-01-18 10:09:02 -0500696 public void toggleMediaButtonClicked() {
Pierre Duchemin8b2c1b52017-12-29 17:17:13 -0500697 presenter.clickOnGoingPane();
698 }
Pierre Duchemin17542a72018-02-14 16:38:36 -0500699
700 private void setLoading(boolean isLoading) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500701 if (binding == null)
Adrien Béraud5b47cb52018-07-06 16:24:14 -0400702 return;
Pierre Duchemin17542a72018-02-14 16:38:36 -0500703 if (isLoading) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500704 binding.btnTakePicture.setVisibility(View.GONE);
705 binding.sendData.setVisibility(View.GONE);
706 binding.pbDataTransfer.setVisibility(View.VISIBLE);
Pierre Duchemin17542a72018-02-14 16:38:36 -0500707 } else {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500708 binding.btnTakePicture.setVisibility(View.VISIBLE);
709 binding.sendData.setVisibility(View.VISIBLE);
710 binding.pbDataTransfer.setVisibility(View.GONE);
Pierre Duchemin17542a72018-02-14 16:38:36 -0500711 }
712 }
Adrien Béraud1b8ac9f2018-05-31 14:34:23 -0400713
714 @Override
715 public void displayCompletedDownload(DataTransfer transfer, File destination) {
Adrien Béraud44939482019-02-13 21:42:08 -0500716 DownloadManager downloadManager = (DownloadManager) requireContext().getSystemService(Context.DOWNLOAD_SERVICE);
Adrien Béraud1b8ac9f2018-05-31 14:34:23 -0400717 if (downloadManager != null) {
718 downloadManager.addCompletedDownload(transfer.getDisplayName(),
719 transfer.getDisplayName(),
720 true,
Adrien Béraud99aaade2018-07-09 13:34:30 -0400721 AndroidFileUtils.getMimeType(destination.getAbsolutePath()),
Adrien Béraud1b8ac9f2018-05-31 14:34:23 -0400722 destination.getAbsolutePath(),
723 destination.length(),
724 true);
725 }
726 }
Adrien Béraudae45ffa2018-07-06 16:21:29 -0400727
728 public void handleShareIntent(Intent intent) {
729 String type = intent.getType();
730 if (type == null) {
731 Log.w(TAG, "Can't share with no type");
732 return;
733 }
Rayan Osseirane4450272019-06-03 14:17:19 -0400734 if (type.startsWith("text/plain")) {
Adrien Béraudb28c4912018-12-02 22:58:52 -0500735 binding.msgInputTxt.setText(intent.getStringExtra(Intent.EXTRA_TEXT));
Rayan Osseirane4450272019-06-03 14:17:19 -0400736 } else {
Adrien Béraudae45ffa2018-07-06 16:21:29 -0400737 android.net.Uri uri = intent.getData();
738 ClipData clip = intent.getClipData();
739 if (uri == null && clip != null && clip.getItemCount() > 0)
740 uri = clip.getItemAt(0).getUri();
741 if (uri == null)
742 return;
Adrien Béraud1af6c012019-05-25 23:20:29 -0400743 startFileSend(AndroidFileUtils.getCacheFile(requireContext(), uri).flatMapCompletable(this::sendFile));
Adrien Béraudae45ffa2018-07-06 16:21:29 -0400744 }
745 }
Adrien Béraude32ab742018-08-25 21:15:08 -0400746}