diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/build.gradle b/BeWoPlanerChat/bewoplaner-chat-android/app/build.gradle index 31e0fda..713dc76 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/build.gradle +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "de.beyondsoft.ownchat" minSdkVersion 19 targetSdkVersion 26 - versionCode 6 - versionName "1.6" + versionCode 7 + versionName "1.7" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -111,7 +111,7 @@ dependencies { compile 'com.github.bumptech.glide:glide:3.7.0' compile 'de.hdodenhof:circleimageview:2.1.0' compile 'com.scottyab:secure-preferences-lib:0.1.4' - compile 'com.google.firebase:firebase-messaging:11.4.2' + compile 'com.google.firebase:firebase-messaging:11.6.0' compile 'hani.momanii.supernova_emoji_library:supernova-emoji-library:0.0.2' compile 'com.github.lzyzsd:circleprogress:1.2.1' compile 'org.greenrobot:eventbus:3.0.0' @@ -136,4 +136,4 @@ task adp2upload(type: Exec, dependsOn: "build") { commandLine 'upload_build.sh', "-c", "$channel", "-v", "$versionCode", "-p", "android", "-a", "$slug", "-f", "$file", "-i", "$identifier", "-n", "$notes" } -apply plugin: 'com.google.gms.google-services' \ No newline at end of file +apply plugin: 'com.google.gms.google-services' diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/BaseChatActivity.java b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/BaseChatActivity.java index 689d13d..ea65122 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/BaseChatActivity.java +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/BaseChatActivity.java @@ -68,6 +68,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.inject.Named; @@ -347,7 +348,6 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha private int xDelta; private String mAudioFilePath; - private Rect mRecButtonRightLimit; private int mMaxMarginRight; private Rect mDialogContainer; private void selectFile(int requestCode) { @@ -368,6 +368,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha ImageView attachDocumentImageView = dialog.findViewById(R.id.attachDocumentBtn); TouchableImageView attachRecordAudioImageView = dialog.findViewById(R.id.attachRecordAudioBtn); TextView limitTextView = dialog.findViewById(R.id.audioRecordingLimitTextView); + ImageView abortRecordingImageView = dialog.findViewById(R.id.abortRecordingImageView); attachDocumentImageView.setOnClickListener(v -> { FilePickerBuilder.getInstance().setMaxCount(1) @@ -395,16 +396,20 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha }); dialog.setOnShowListener(dialog1 -> { - mRecButtonRightLimit = ViewUtils.getRectFromView(attachRecordAudioImageView); mMaxMarginRight = ((GridLayout.LayoutParams) attachRecordAudioImageView.getLayoutParams()).leftMargin; mDialogContainer = ViewUtils.getRectFromView(dialog.findViewById(R.id.dialogGridLayout)); }); - final long duration = (mUploadMaxSize.get() / 256000L) * 1000; + Log.d("ON_TOUCH", "Upload max size: " + mUploadMaxSize.get()); + + final long duration = ((mUploadMaxSize.get() / 10 * 9) * 8) / (Constants.RECORDING_BIT_RATE_IN_MS / 1000); // 10% Overhead CountDownTimer countDownTimer = new CountDownTimer(duration, 10) { @Override public void onTick(long millisecondsUntilFinished) { - limitTextView.setText(String.format(Locale.getDefault(), "%.2fs", (double) (millisecondsUntilFinished / 1000.0))); + long minutes = TimeUnit.MILLISECONDS.toMinutes(millisecondsUntilFinished); + long seconds = TimeUnit.MILLISECONDS.toSeconds(millisecondsUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisecondsUntilFinished)); + + limitTextView.setText(String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds)); } @Override @@ -416,19 +421,19 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha attachFromGalleryImageView.setVisibility(View.VISIBLE); try { - mMediaRecorder.stop(); + mMediaRecorder.stop(); // TODO: delete } catch (IllegalStateException e) { e.printStackTrace(); } } }; - // TODO: prevent the image view from moving outside the dialog box attachRecordAudioImageView.setOnTouchListener((v, event) -> { try { attachRecordAudioImageView.performClick(); final int x = (int) event.getRawX(); + int test = 0; switch(event.getAction()) { case MotionEvent.ACTION_DOWN: @@ -439,6 +444,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha limitTextView.setVisibility(View.VISIBLE); attachDocumentImageView.setVisibility(View.INVISIBLE); attachFromGalleryImageView.setVisibility(View.INVISIBLE); + abortRecordingImageView.setVisibility(View.VISIBLE); mAudioFilePath = FileUtils.generateAudioRecordingFileName(this); setupMediaRecorder(mAudioFilePath); @@ -461,11 +467,34 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha mMediaRecorder.stop(); + Rect recordButtonRect = ViewUtils.getRectFromView(attachRecordAudioImageView); + Rect abortButtonRect = ViewUtils.getRectFromView(abortRecordingImageView); + + if(recordButtonRect.intersect(abortButtonRect)) { + if(!TextUtils.isEmpty(mAudioFilePath)) { + File audioFile = new File(mAudioFilePath); + if(audioFile.exists()) { + audioFile.delete(); + } + } + + dialog.dismiss(); + return true; + } + if (!mChatPresenter.isAttached()) { mChatPresenter.attachView(this); } - //mCallback.sendFile(Uri.fromFile(new File(mAudioFilePath)), null); + Bundle bundle = new Bundle(); + bundle.putString(Constants.FILENAME, mAudioFilePath); + + Intent intent = new Intent(this, FileConfirmationActivity.class); + intent.putExtras(bundle); + + intent.putExtra(Constants.EXTRA_GROUP, mGroup); + + startActivityForResult(intent, 666); dialog.dismiss(); return true; @@ -475,9 +504,11 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha int newLeft = x - xDelta; - Log.d("ON_TOUCH", "dialog container left: " + mDialogContainer.left + "; x: " + x + "; limit to the right: " + mMaxMarginRight + "; old margin left: " + layoutParams2.leftMargin); + Log.d("ON_TOUCH", "new left margin: " + newLeft); - if(x > mDialogContainer.left && newLeft < mMaxMarginRight) { + int buttonLeft = ViewUtils.getRectFromView(attachRecordAudioImageView).left; + + if(buttonLeft > mDialogContainer.left && newLeft < mMaxMarginRight) { layoutParams2.leftMargin = newLeft; layoutParams2.rightMargin = 0; v.setLayoutParams(layoutParams2); @@ -501,7 +532,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha mMediaRecorder = new MediaRecorder(); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - mMediaRecorder.setAudioEncodingBitRate(32000); + mMediaRecorder.setAudioEncodingBitRate(Constants.RECORDING_BIT_RATE_IN_MS); mMediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB); mMediaRecorder.setOutputFile(audioFilePath); } diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/ChatPresenter.java b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/ChatPresenter.java index 1cf8098..0c3c1ea 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/ChatPresenter.java +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/page/chat/ChatPresenter.java @@ -4,7 +4,6 @@ import de.beyondsoft.ownchat.R; import de.beyondsoft.ownchat.data.AppPrefsConstants; import de.beyondsoft.ownchat.data.api.common.ErrorHandlingResponseConverter; import de.beyondsoft.ownchat.data.api.responses.MessageResponse; -import de.beyondsoft.ownchat.data.api.responses.MessagesResponse; import de.beyondsoft.ownchat.data.api.services.ChatService; import de.beyondsoft.ownchat.data.events.GroupUpdatedEvent; import de.beyondsoft.ownchat.data.prefs.LongPreference; @@ -27,15 +26,12 @@ import de.beyondsoft.ownchat.utils.rx.RxUtils; import org.greenrobot.eventbus.EventBus; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; import android.support.annotation.NonNull; import android.support.v4.util.Pair; import android.text.TextUtils; import android.util.Log; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -43,6 +39,7 @@ import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; @@ -59,7 +56,6 @@ import rx.Observable; import rx.Subscriber; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; import rx.schedulers.Schedulers; import static de.beyondsoft.ownchat.data.AppPrefsConstants.USER_ID; @@ -165,51 +161,48 @@ public class ChatPresenter extends MVPAbstractPresenter implements Cha Subscription subscription = mChatService.getMessages(mGroupId, 0) .compose(RxUtils.provideDefaultTransformer()) .flatMap(new ErrorHandlingResponseConverter<>()) - .flatMap(new Func1>>() { - @Override - public Observable> call(MessagesResponse messageResponse) { - if (messageResponse.response.messages == null || messageResponse.response.messages.isEmpty()) { - return Observable.just(null); - } - - Message lastMessage = messageResponse.response.messages.get(messageResponse.response.messages.size() - 1); - lastMessage.status = Message.Status.DELIVERED; - lastMessage.isRead = true; - - if (!mMessages.contains(lastMessage)) { - long groupId = mGroupId; - resetMessages(); - loadMessagesFromServerByGroupId(groupId); - - return Observable.just(null); - } - - for (int i = 0; i < mMessageToUpdate.size(); i++) { - Pair messageToUpdate = mMessageToUpdate.get(i); - - if (isAttached()) { - getView().lastMessageUpdated(messageToUpdate.first, messageToUpdate.second); - } - } - - mMessageToUpdate.clear(); - ArrayList messages = new ArrayList<>(); - - for (int i = messageResponse.response.messages.size() - 1; i >= 0; i--) { - Message message = messageResponse.response.messages.get(i); - message.status = Message.Status.DELIVERED; - message.isRead = true; - message.userId = mUserIdPreference.get(); - - if (mMessages.contains(message)) { - continue; - } - - messages.add(message); - } - - return mMessageRealmRepository.updateMessages(messages, new MessageByIdSpecification(mUserIdPreference.get())); + .flatMap(messageResponse -> { + if (messageResponse.response.messages == null || messageResponse.response.messages.isEmpty()) { + return Observable.just(null); } + + Message lastMessage = messageResponse.response.messages.get(messageResponse.response.messages.size() - 1); + lastMessage.status = Message.Status.DELIVERED; + lastMessage.isRead = true; + + if (!mMessages.contains(lastMessage)) { + long groupId1 = mGroupId; + resetMessages(); + loadMessagesFromServerByGroupId(groupId1); + + return Observable.just(null); + } + + for (int i = 0; i < mMessageToUpdate.size(); i++) { + Pair messageToUpdate = mMessageToUpdate.get(i); + + if (isAttached()) { + getView().lastMessageUpdated(messageToUpdate.first, messageToUpdate.second); + } + } + + mMessageToUpdate.clear(); + ArrayList messages = new ArrayList<>(); + + for (int i = messageResponse.response.messages.size() - 1; i >= 0; i--) { + Message message = messageResponse.response.messages.get(i); + message.status = Message.Status.DELIVERED; + message.isRead = true; + message.userId = mUserIdPreference.get(); + + if (mMessages.contains(message)) { + continue; + } + + messages.add(message); + } + + return mMessageRealmRepository.updateMessages(messages, new MessageByIdSpecification(mUserIdPreference.get())); }) .subscribe(this::fetchNewMessagesSuccess, this::fetchNewMessagesError); addSubscription(subscription); @@ -418,7 +411,7 @@ public class ChatPresenter extends MVPAbstractPresenter implements Cha * Send the file to the server. */ @Override - public void sendFile(Uri fileUri, String messageText) { + public void sendFile(final Uri fileUri, String messageText) { File file = getView().getFile(fileUri); final String mimeType = FileUtils.getMimeType(file); @@ -506,11 +499,11 @@ public class ChatPresenter extends MVPAbstractPresenter implements Cha storeMessageLocally(newMessage, message.id, false); storeGroupLocally(mGroupId, message); - if (!isAttached()) { + if(!isAttached()) { return; } - if (mSystemUtils.isNetworkUnavailable()) { + if(mSystemUtils.isNetworkUnavailable()) { getView().showError(R.string.error_no_internet_connection); return; } @@ -526,6 +519,15 @@ public class ChatPresenter extends MVPAbstractPresenter implements Cha baseResponse.response.message.isRead = true; storeMessageLocally(baseResponse.response.message, message.id, false); storeGroupLocally(mGroupId, baseResponse.response.message); + + List splitUriAsList = Arrays.asList(fileUri.toString().split("/")); + + if(splitUriAsList.contains(Constants.AUDIO_RECORDINGS_DIR)) { + File f = getView().getFile(fileUri); + if(f != null && f.exists()) { + f.delete(); + } + } } }); } diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/Constants.java b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/Constants.java index fcd90e2..25ed660 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/Constants.java +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/Constants.java @@ -36,4 +36,6 @@ public interface Constants { String HAS_OPEN_CHAT = "has_open_chat"; String AUDIO_RECORDINGS_DIR = "audio_recordings"; + + int RECORDING_BIT_RATE_IN_MS = 32000; } \ No newline at end of file diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/ui/ViewUtils.java b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/ui/ViewUtils.java index 75338d3..1af8a0b 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/ui/ViewUtils.java +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/java/de/beyondsoft/ownchat/utils/ui/ViewUtils.java @@ -56,17 +56,6 @@ public abstract class ViewUtils { imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } - public static boolean isInViewInBounds(View view, int x, int y) { - Rect outRect = new Rect(); - int[] location = new int[2]; - - view.getDrawingRect(outRect); - view.getLocationOnScreen(location); - outRect.offset(location[0], location[1]); - - return outRect.contains(x, y); - } - public static Rect getRectFromView(View view) { Rect outRect = new Rect(); int[] location = new int[2]; @@ -78,4 +67,16 @@ public abstract class ViewUtils { return outRect; } + + public static Rect getHitRectFromView(View view) { + Rect outRect = new Rect(); + int[] location = new int[2]; + + view.getHitRect(outRect); + view.getLocationOnScreen(location); + + outRect.offset(location[0], location[1]); + + return outRect; + } } diff --git a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/res/layout/dialog_file_chooser.xml b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/res/layout/dialog_file_chooser.xml index 70da05b..f5cb74b 100644 --- a/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/res/layout/dialog_file_chooser.xml +++ b/BeWoPlanerChat/bewoplaner-chat-android/app/src/main/res/layout/dialog_file_chooser.xml @@ -2,7 +2,7 @@ + +