2018-04-23 14:57:48 +01:00
|
|
|
/*
|
|
|
|
* Nextcloud Talk application
|
|
|
|
*
|
|
|
|
* @author Mario Danic
|
|
|
|
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package com.nextcloud.talk.controllers;
|
|
|
|
|
|
|
|
|
2018-05-08 19:30:43 +01:00
|
|
|
import android.content.ClipData;
|
|
|
|
import android.content.ClipboardManager;
|
|
|
|
import android.content.Context;
|
2018-04-30 12:34:02 +01:00
|
|
|
import android.content.Intent;
|
2018-05-04 02:59:27 +01:00
|
|
|
import android.graphics.Color;
|
|
|
|
import android.graphics.drawable.ColorDrawable;
|
|
|
|
import android.graphics.drawable.Drawable;
|
2018-04-23 14:57:48 +01:00
|
|
|
import android.os.Bundle;
|
|
|
|
import android.support.annotation.NonNull;
|
2018-04-23 19:39:37 +01:00
|
|
|
import android.support.v7.widget.LinearLayoutManager;
|
2018-04-28 08:51:53 +01:00
|
|
|
import android.text.TextUtils;
|
2018-04-23 14:57:48 +01:00
|
|
|
import android.view.LayoutInflater;
|
2018-04-28 11:26:34 +01:00
|
|
|
import android.view.Menu;
|
2018-04-30 12:34:02 +01:00
|
|
|
import android.view.MenuInflater;
|
2018-04-23 14:57:48 +01:00
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
2018-05-04 02:59:27 +01:00
|
|
|
import android.view.inputmethod.EditorInfo;
|
2018-04-23 14:57:48 +01:00
|
|
|
import android.widget.ImageView;
|
|
|
|
|
2018-04-28 08:51:53 +01:00
|
|
|
import com.bluelinelabs.conductor.RouterTransaction;
|
|
|
|
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
|
|
|
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
|
|
|
import com.bumptech.glide.request.RequestOptions;
|
|
|
|
import com.nextcloud.talk.R;
|
2018-04-30 12:34:02 +01:00
|
|
|
import com.nextcloud.talk.activities.CallActivity;
|
2018-04-24 12:57:31 +01:00
|
|
|
import com.nextcloud.talk.adapters.messages.MagicIncomingTextMessageViewHolder;
|
2018-05-04 14:35:03 +01:00
|
|
|
import com.nextcloud.talk.adapters.messages.MagicOutcomingTextMessageViewHolder;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.nextcloud.talk.api.NcApi;
|
|
|
|
import com.nextcloud.talk.application.NextcloudTalkApplication;
|
2018-05-04 02:59:27 +01:00
|
|
|
import com.nextcloud.talk.callbacks.MentionAutocompleteCallback;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.nextcloud.talk.controllers.base.BaseController;
|
|
|
|
import com.nextcloud.talk.models.database.UserEntity;
|
2018-04-28 08:51:53 +01:00
|
|
|
import com.nextcloud.talk.models.json.call.Call;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.nextcloud.talk.models.json.call.CallOverall;
|
|
|
|
import com.nextcloud.talk.models.json.chat.ChatMessage;
|
|
|
|
import com.nextcloud.talk.models.json.chat.ChatOverall;
|
2018-04-23 19:39:37 +01:00
|
|
|
import com.nextcloud.talk.models.json.generic.GenericOverall;
|
2018-05-04 02:59:27 +01:00
|
|
|
import com.nextcloud.talk.models.json.mention.Mention;
|
|
|
|
import com.nextcloud.talk.presenters.MentionAutocompletePresenter;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.nextcloud.talk.utils.ApiUtils;
|
|
|
|
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
|
|
|
import com.nextcloud.talk.utils.database.user.UserUtils;
|
|
|
|
import com.nextcloud.talk.utils.glide.GlideApp;
|
2018-05-04 02:59:27 +01:00
|
|
|
import com.otaliastudios.autocomplete.Autocomplete;
|
|
|
|
import com.otaliastudios.autocomplete.AutocompleteCallback;
|
|
|
|
import com.otaliastudios.autocomplete.AutocompletePresenter;
|
|
|
|
import com.otaliastudios.autocomplete.CharPolicy;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.stfalcon.chatkit.commons.ImageLoader;
|
2018-05-08 19:30:43 +01:00
|
|
|
import com.stfalcon.chatkit.commons.models.IMessage;
|
2018-04-23 14:57:48 +01:00
|
|
|
import com.stfalcon.chatkit.messages.MessageInput;
|
|
|
|
import com.stfalcon.chatkit.messages.MessagesList;
|
|
|
|
import com.stfalcon.chatkit.messages.MessagesListAdapter;
|
2018-04-23 19:39:37 +01:00
|
|
|
import com.stfalcon.chatkit.utils.DateFormatter;
|
2018-04-23 14:57:48 +01:00
|
|
|
|
|
|
|
import org.parceler.Parcels;
|
|
|
|
|
2018-04-28 12:48:26 +01:00
|
|
|
import java.util.ArrayList;
|
2018-04-23 19:39:37 +01:00
|
|
|
import java.util.Date;
|
2018-04-23 14:57:48 +01:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
|
|
|
|
|
import autodagger.AutoInjector;
|
|
|
|
import butterknife.BindView;
|
|
|
|
import io.reactivex.Observer;
|
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
|
|
import io.reactivex.disposables.Disposable;
|
|
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
import retrofit2.Response;
|
|
|
|
|
|
|
|
@AutoInjector(NextcloudTalkApplication.class)
|
2018-04-23 19:39:37 +01:00
|
|
|
public class ChatController extends BaseController implements MessagesListAdapter.OnLoadMoreListener,
|
2018-05-08 19:30:43 +01:00
|
|
|
MessagesListAdapter.Formatter<Date>, MessagesListAdapter.OnMessageLongClickListener {
|
2018-04-28 12:48:26 +01:00
|
|
|
private static final String TAG = "ChatController";
|
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
@Inject
|
|
|
|
NcApi ncApi;
|
|
|
|
@Inject
|
|
|
|
UserUtils userUtils;
|
2018-04-28 12:48:26 +01:00
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
@BindView(R.id.input)
|
|
|
|
MessageInput messageInput;
|
|
|
|
@BindView(R.id.messagesList)
|
|
|
|
MessagesList messagesList;
|
2018-04-30 13:30:33 +01:00
|
|
|
private List<Disposable> disposableList = new ArrayList<>();
|
2018-04-23 14:57:48 +01:00
|
|
|
private String conversationName;
|
|
|
|
private String roomToken;
|
|
|
|
private UserEntity currentUser;
|
2018-04-28 08:51:53 +01:00
|
|
|
private String roomPassword;
|
|
|
|
private Call currentCall;
|
2018-04-23 14:57:48 +01:00
|
|
|
private boolean inChat = false;
|
|
|
|
private boolean historyRead = false;
|
|
|
|
private int globalLastKnownFutureMessageId = -1;
|
|
|
|
private int globalLastKnownPastMessageId = -1;
|
|
|
|
private MessagesListAdapter<ChatMessage> adapter;
|
2018-04-28 11:26:34 +01:00
|
|
|
private Menu globalMenu;
|
|
|
|
|
2018-05-04 02:59:27 +01:00
|
|
|
private Autocomplete mentionAutocomplete;
|
2018-05-04 10:59:16 +01:00
|
|
|
|
2018-05-04 02:59:27 +01:00
|
|
|
/*
|
|
|
|
TODO:
|
|
|
|
- check push notifications
|
|
|
|
- new conversation handling
|
|
|
|
*/
|
2018-04-23 14:57:48 +01:00
|
|
|
public ChatController(Bundle args) {
|
|
|
|
super(args);
|
|
|
|
setHasOptionsMenu(true);
|
|
|
|
this.conversationName = args.getString(BundleKeys.KEY_CONVERSATION_NAME);
|
|
|
|
this.currentUser = Parcels.unwrap(args.getParcelable(BundleKeys.KEY_USER_ENTITY));
|
|
|
|
this.roomToken = args.getString(BundleKeys.KEY_ROOM_TOKEN);
|
2018-04-28 08:51:53 +01:00
|
|
|
this.roomPassword = args.getString(BundleKeys.KEY_ROOM_PASSWORD, "");
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) {
|
|
|
|
return inflater.inflate(R.layout.controller_chat, container, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onViewBound(@NonNull View view) {
|
|
|
|
super.onViewBound(view);
|
|
|
|
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
|
|
|
|
|
2018-04-23 19:39:37 +01:00
|
|
|
boolean adapterWasNull = false;
|
|
|
|
|
|
|
|
if (adapter == null) {
|
2018-04-28 12:48:26 +01:00
|
|
|
|
2018-04-23 19:39:37 +01:00
|
|
|
adapterWasNull = true;
|
2018-04-24 12:57:31 +01:00
|
|
|
|
|
|
|
MessagesListAdapter.HoldersConfig holdersConfig = new MessagesListAdapter.HoldersConfig();
|
|
|
|
holdersConfig.setIncoming(MagicIncomingTextMessageViewHolder.class,
|
|
|
|
R.layout.item_custom_incoming_text_message);
|
2018-05-08 19:54:43 +01:00
|
|
|
holdersConfig.setOutcoming(MagicOutcomingTextMessageViewHolder.class,
|
|
|
|
R.layout.item_custom_outcoming_text_message);
|
2018-04-24 12:57:31 +01:00
|
|
|
|
|
|
|
adapter = new MessagesListAdapter<>(currentUser.getUserId(), holdersConfig, new ImageLoader() {
|
2018-04-23 19:39:37 +01:00
|
|
|
@Override
|
|
|
|
public void loadImage(ImageView imageView, String url) {
|
|
|
|
GlideApp.with(NextcloudTalkApplication.getSharedApplication().getApplicationContext())
|
|
|
|
.asBitmap()
|
|
|
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
|
|
.load(url)
|
|
|
|
.centerInside()
|
|
|
|
.override(imageView.getMeasuredWidth(), imageView.getMeasuredHeight())
|
|
|
|
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
|
|
|
|
.into(imageView);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-04-23 14:57:48 +01:00
|
|
|
|
|
|
|
messagesList.setAdapter(adapter);
|
|
|
|
adapter.setLoadMoreListener(this);
|
2018-04-23 19:39:37 +01:00
|
|
|
adapter.setDateHeadersFormatter(this::format);
|
|
|
|
|
2018-05-08 19:30:43 +01:00
|
|
|
adapter.setOnMessageLongClickListener(this);
|
|
|
|
|
2018-05-04 02:59:27 +01:00
|
|
|
setupMentionAutocomplete();
|
|
|
|
|
|
|
|
messageInput.getInputEditText().setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
2018-04-23 19:39:37 +01:00
|
|
|
messageInput.setInputListener(input -> {
|
|
|
|
sendMessage(input.toString());
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (adapterWasNull) {
|
2018-04-28 08:51:53 +01:00
|
|
|
joinRoomWithPassword();
|
2018-04-23 19:39:37 +01:00
|
|
|
}
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
2018-05-04 02:59:27 +01:00
|
|
|
private void setupMentionAutocomplete() {
|
|
|
|
float elevation = 6f;
|
|
|
|
Drawable backgroundDrawable = new ColorDrawable(Color.WHITE);
|
|
|
|
AutocompletePresenter<Mention> presenter = new MentionAutocompletePresenter(getApplicationContext(), roomToken);
|
|
|
|
AutocompleteCallback<Mention> callback = new MentionAutocompleteCallback();
|
|
|
|
|
|
|
|
mentionAutocomplete = Autocomplete.<Mention>on(messageInput.getInputEditText())
|
|
|
|
.with(elevation)
|
|
|
|
.with(backgroundDrawable)
|
|
|
|
.with(new CharPolicy('@'))
|
|
|
|
.with(presenter)
|
|
|
|
.with(callback)
|
|
|
|
.build();
|
|
|
|
}
|
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
@Override
|
|
|
|
protected void onAttach(@NonNull View view) {
|
|
|
|
super.onAttach(view);
|
|
|
|
if (getActionBar() != null) {
|
|
|
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
|
|
|
}
|
2018-05-04 10:04:19 +01:00
|
|
|
|
|
|
|
if (mentionAutocomplete != null && mentionAutocomplete.isPopupShowing()) {
|
|
|
|
mentionAutocomplete.dismissPopup();
|
|
|
|
}
|
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected String getTitle() {
|
|
|
|
return conversationName;
|
|
|
|
}
|
|
|
|
|
2018-04-28 08:51:53 +01:00
|
|
|
@Override
|
|
|
|
public boolean handleBack() {
|
|
|
|
if (getRouter().hasRootController()) {
|
|
|
|
getRouter().popToRoot(new HorizontalChangeHandler());
|
|
|
|
} else {
|
|
|
|
getRouter().setRoot(RouterTransaction.with(new MagicBottomNavigationController())
|
|
|
|
.pushChangeHandler(new HorizontalChangeHandler())
|
|
|
|
.popChangeHandler(new HorizontalChangeHandler()));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
inChat = false;
|
2018-04-28 12:48:26 +01:00
|
|
|
dispose();
|
2018-04-23 14:57:48 +01:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
2018-04-28 12:48:26 +01:00
|
|
|
private void dispose() {
|
|
|
|
Disposable disposable;
|
|
|
|
for (int i = 0; i < disposableList.size(); i++) {
|
|
|
|
if ((disposable = disposableList.get(i)).isDisposed()) {
|
|
|
|
disposable.dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-28 08:51:53 +01:00
|
|
|
private void joinRoomWithPassword() {
|
|
|
|
String password = "";
|
|
|
|
|
|
|
|
if (TextUtils.isEmpty(roomPassword)) {
|
|
|
|
password = roomPassword;
|
|
|
|
}
|
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
ncApi.joinRoom(ApiUtils.getCredentials(currentUser.getUserId(), currentUser.getToken()), ApiUtils
|
|
|
|
.getUrlForRoomParticipants(currentUser.getBaseUrl(), roomToken), password)
|
|
|
|
.subscribeOn(Schedulers.newThread())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.retry(3)
|
|
|
|
.subscribe(new Observer<CallOverall>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Disposable d) {
|
2018-04-28 12:48:26 +01:00
|
|
|
disposableList.add(d);
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(CallOverall callOverall) {
|
|
|
|
inChat = true;
|
|
|
|
pullChatMessages(0);
|
2018-04-28 08:51:53 +01:00
|
|
|
currentCall = callOverall.getOcs().getData();
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-04-23 19:39:37 +01:00
|
|
|
private void sendMessage(String message) {
|
|
|
|
Map<String, String> fieldMap = new HashMap<>();
|
|
|
|
fieldMap.put("message", message);
|
|
|
|
fieldMap.put("actorDisplayName", currentUser.getDisplayName());
|
|
|
|
|
|
|
|
|
|
|
|
ncApi.sendChatMessage(ApiUtils.getCredentials(currentUser.getUserId(), currentUser.getToken()),
|
|
|
|
ApiUtils.getUrlForChat(currentUser.getBaseUrl(), roomToken), fieldMap)
|
|
|
|
.subscribeOn(Schedulers.newThread())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.retry(3, observable -> inChat)
|
|
|
|
.subscribe(new Observer<GenericOverall>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Disposable d) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(GenericOverall genericOverall) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-04-28 12:48:26 +01:00
|
|
|
|
2018-04-23 14:57:48 +01:00
|
|
|
private void pullChatMessages(int lookIntoFuture) {
|
|
|
|
Map<String, Integer> fieldMap = new HashMap<>();
|
|
|
|
fieldMap.put("lookIntoFuture", lookIntoFuture);
|
2018-04-23 19:39:37 +01:00
|
|
|
fieldMap.put("limit", 25);
|
2018-04-23 14:57:48 +01:00
|
|
|
|
|
|
|
int lastKnown;
|
|
|
|
if (lookIntoFuture == 1) {
|
|
|
|
lastKnown = globalLastKnownFutureMessageId;
|
|
|
|
} else {
|
|
|
|
lastKnown = globalLastKnownPastMessageId;
|
|
|
|
}
|
|
|
|
|
2018-04-28 12:48:26 +01:00
|
|
|
if (lastKnown != -1) {
|
|
|
|
fieldMap.put("lastKnownMessageId", lastKnown);
|
|
|
|
}
|
2018-04-23 14:57:48 +01:00
|
|
|
|
|
|
|
if (lookIntoFuture == 1) {
|
|
|
|
ncApi.pullChatMessages(ApiUtils.getCredentials(currentUser.getUserId(), currentUser.getToken()),
|
|
|
|
ApiUtils.getUrlForChat(currentUser.getBaseUrl(), roomToken), fieldMap)
|
|
|
|
.subscribeOn(Schedulers.newThread())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.takeWhile(observable -> inChat)
|
|
|
|
.retry(3, observable -> inChat)
|
|
|
|
.subscribe(new Observer<Response>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Disposable d) {
|
2018-04-28 12:48:26 +01:00
|
|
|
disposableList.add(d);
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(Response response) {
|
|
|
|
processMessages(response, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
2018-04-28 12:48:26 +01:00
|
|
|
pullChatMessages(1);
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ncApi.pullChatMessages(ApiUtils.getCredentials(currentUser.getUserId(), currentUser.getToken()),
|
|
|
|
ApiUtils.getUrlForChat(currentUser.getBaseUrl(), roomToken), fieldMap)
|
|
|
|
.subscribeOn(Schedulers.newThread())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.retry(3, observable -> inChat)
|
|
|
|
.subscribe(new Observer<Response>() {
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Disposable d) {
|
2018-04-28 12:48:26 +01:00
|
|
|
disposableList.add(d);
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNext(Response response) {
|
|
|
|
processMessages(response, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onError(Throwable e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onComplete() {
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void processMessages(Response response, boolean isFromTheFuture) {
|
|
|
|
if (response.code() == 200) {
|
|
|
|
boolean shouldForceFuture = false;
|
|
|
|
if (globalLastKnownFutureMessageId == -1) {
|
|
|
|
shouldForceFuture = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ChatOverall chatOverall = (ChatOverall) response.body();
|
|
|
|
List<ChatMessage> chatMessageList = chatOverall.getOcs().getData();
|
|
|
|
|
|
|
|
if (!isFromTheFuture) {
|
|
|
|
for (int i = 0; i < chatMessageList.size(); i++) {
|
|
|
|
chatMessageList.get(i).setBaseUrl(currentUser.getBaseUrl());
|
|
|
|
if (globalLastKnownPastMessageId == -1 || chatMessageList.get(i).getJsonMessageId() <
|
|
|
|
globalLastKnownPastMessageId) {
|
|
|
|
globalLastKnownPastMessageId = chatMessageList.get(i).getJsonMessageId();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldForceFuture) {
|
|
|
|
if (chatMessageList.get(i).getJsonMessageId() > globalLastKnownFutureMessageId) {
|
|
|
|
globalLastKnownFutureMessageId = chatMessageList.get(i).getJsonMessageId();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
adapter.addToEnd(chatMessageList, false);
|
|
|
|
|
|
|
|
} else {
|
2018-04-23 19:39:37 +01:00
|
|
|
LinearLayoutManager layoutManager = (LinearLayoutManager) messagesList.getLayoutManager();
|
2018-04-23 14:57:48 +01:00
|
|
|
for (int i = 0; i < chatMessageList.size(); i++) {
|
|
|
|
chatMessageList.get(i).setBaseUrl(currentUser.getBaseUrl());
|
2018-04-23 19:39:37 +01:00
|
|
|
adapter.addToStart(chatMessageList.get(i),
|
2018-04-28 12:48:26 +01:00
|
|
|
layoutManager.findLastVisibleItemPosition() <= adapter.getItemCount() - 10);
|
2018-04-23 14:57:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
globalLastKnownFutureMessageId = Integer.parseInt(response.headers().get("X-Chat-Last-Given"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldForceFuture) {
|
|
|
|
pullChatMessages(1);
|
|
|
|
}
|
|
|
|
} else if (response.code() == 304 && !isFromTheFuture) {
|
|
|
|
historyRead = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLoadMore(int page, int totalItemsCount) {
|
|
|
|
if (!historyRead) {
|
|
|
|
pullChatMessages(0);
|
|
|
|
}
|
|
|
|
}
|
2018-04-23 19:39:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String format(Date date) {
|
|
|
|
if (DateFormatter.isToday(date)) {
|
|
|
|
return getResources().getString(R.string.nc_date_header_today);
|
|
|
|
} else if (DateFormatter.isYesterday(date)) {
|
|
|
|
return getResources().getString(R.string.nc_date_header_yesterday);
|
|
|
|
} else {
|
|
|
|
return DateFormatter.format(date, DateFormatter.Template.STRING_DAY_MONTH_YEAR);
|
|
|
|
}
|
2018-04-28 11:26:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-04-30 12:34:02 +01:00
|
|
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
|
|
super.onCreateOptionsMenu(menu, inflater);
|
|
|
|
inflater.inflate(R.menu.menu_conversation, menu);
|
2018-04-28 11:26:34 +01:00
|
|
|
globalMenu = menu;
|
|
|
|
}
|
|
|
|
|
2018-04-30 12:34:02 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
case android.R.id.home:
|
|
|
|
inChat = false;
|
|
|
|
if (getRouter().hasRootController()) {
|
|
|
|
getRouter().popToRoot(new HorizontalChangeHandler());
|
|
|
|
} else {
|
|
|
|
getRouter().setRoot(RouterTransaction.with(new MagicBottomNavigationController())
|
|
|
|
.pushChangeHandler(new HorizontalChangeHandler())
|
|
|
|
.popChangeHandler(new HorizontalChangeHandler()));
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.conversation_video_call:
|
2018-04-30 13:01:36 +01:00
|
|
|
startActivity(getIntentForCall(false));
|
2018-04-30 12:34:02 +01:00
|
|
|
return true;
|
|
|
|
case R.id.conversation_voice_call:
|
2018-04-30 13:01:36 +01:00
|
|
|
startActivity(getIntentForCall(true));
|
2018-04-30 12:34:02 +01:00
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-30 13:01:36 +01:00
|
|
|
private Intent getIntentForCall(boolean isVoiceOnlyCall) {
|
|
|
|
Bundle bundle = new Bundle();
|
|
|
|
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken);
|
|
|
|
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(currentUser));
|
|
|
|
bundle.putString(BundleKeys.KEY_CALL_SESSION, currentCall.getSessionId());
|
|
|
|
|
|
|
|
if (isVoiceOnlyCall) {
|
|
|
|
bundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Intent callIntent = new Intent(getActivity(), CallActivity.class);
|
|
|
|
callIntent.putExtras(bundle);
|
|
|
|
|
|
|
|
return callIntent;
|
|
|
|
}
|
2018-05-08 19:30:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onMessageLongClick(IMessage message) {
|
|
|
|
if (getActivity() != null) {
|
|
|
|
ClipboardManager clipboardManager = (android.content.ClipboardManager)
|
|
|
|
getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
|
|
|
ClipData clipData = android.content.ClipData.newPlainText(
|
|
|
|
getResources().getString(R.string.nc_app_name), message.getText());
|
|
|
|
if (clipboardManager != null) {
|
|
|
|
clipboardManager.setPrimaryClip(clipData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 11:26:34 +01:00
|
|
|
}
|