Browse Source

Sending support and bunch of improvements

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 7 years ago
parent
commit
bd5b37aa5e

+ 1 - 1
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -277,7 +277,7 @@ public interface NcApi {
     */
 
     @FormUrlEncoded
-    @PUT
+    @POST
     Observable<GenericOverall> sendChatMessage(@Header("Authorization") String authorization, @Url String url,
                                                @FieldMap Map<String, String> fields);
 

+ 85 - 23
app/src/main/java/com/nextcloud/talk/controllers/ChatController.java

@@ -24,6 +24,8 @@ package com.nextcloud.talk.controllers;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
@@ -41,6 +43,7 @@ import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.call.CallOverall;
 import com.nextcloud.talk.models.json.chat.ChatMessage;
 import com.nextcloud.talk.models.json.chat.ChatOverall;
+import com.nextcloud.talk.models.json.generic.GenericOverall;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.user.UserUtils;
@@ -49,9 +52,11 @@ import com.stfalcon.chatkit.commons.ImageLoader;
 import com.stfalcon.chatkit.messages.MessageInput;
 import com.stfalcon.chatkit.messages.MessagesList;
 import com.stfalcon.chatkit.messages.MessagesListAdapter;
+import com.stfalcon.chatkit.utils.DateFormatter;
 
 import org.parceler.Parcels;
 
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -67,7 +72,8 @@ import io.reactivex.schedulers.Schedulers;
 import retrofit2.Response;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public class ChatController extends BaseController implements MessagesListAdapter.OnLoadMoreListener {
+public class ChatController extends BaseController implements MessagesListAdapter.OnLoadMoreListener,
+        MessagesListAdapter.Formatter<Date> {
     @Inject
     NcApi ncApi;
     @Inject
@@ -87,6 +93,7 @@ public class ChatController extends BaseController implements MessagesListAdapte
     private int globalLastKnownPastMessageId = -1;
 
     private MessagesListAdapter<ChatMessage> adapter;
+    private RecyclerView.LayoutManager layoutManager;
 
     public ChatController(Bundle args) {
         super(args);
@@ -106,23 +113,37 @@ public class ChatController extends BaseController implements MessagesListAdapte
         super.onViewBound(view);
         NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
 
-        adapter = new MessagesListAdapter<>(currentUser.getUserId(), new ImageLoader() {
-            @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);
-            }
-        });
+        boolean adapterWasNull = false;
+
+        if (adapter == null) {
+            adapterWasNull = true;
+            adapter = new MessagesListAdapter<>(currentUser.getUserId(), new ImageLoader() {
+                @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);
+                }
+            });
+        }
 
         messagesList.setAdapter(adapter);
         adapter.setLoadMoreListener(this);
-        joinRoomWithPassword(null);
+        adapter.setDateHeadersFormatter(this::format);
+
+        messageInput.setInputListener(input -> {
+            sendMessage(input.toString());
+            return true;
+        });
+
+        if (adapterWasNull) {
+            joinRoomWithPassword(null);
+        }
     }
 
     @Override
@@ -186,10 +207,43 @@ public class ChatController extends BaseController implements MessagesListAdapte
                 });
     }
 
+    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() {
+
+                    }
+                });
+    }
     private void pullChatMessages(int lookIntoFuture) {
         Map<String, Integer> fieldMap = new HashMap<>();
         fieldMap.put("lookIntoFuture", lookIntoFuture);
-        fieldMap.put("limit", 2);
+        fieldMap.put("limit", 25);
 
         int lastKnown;
         if (lookIntoFuture == 1) {
@@ -285,17 +339,14 @@ public class ChatController extends BaseController implements MessagesListAdapte
                     }
                 }
 
-
                 adapter.addToEnd(chatMessageList, false);
 
             } else {
+                LinearLayoutManager layoutManager = (LinearLayoutManager) messagesList.getLayoutManager();
                 for (int i = 0; i < chatMessageList.size(); i++) {
                     chatMessageList.get(i).setBaseUrl(currentUser.getBaseUrl());
-                    if (i == chatMessageList.size() - 1) {
-                        adapter.addToStart(chatMessageList.get(i), true);
-                    } else {
-                        adapter.addToStart(chatMessageList.get(i), false);
-                    }
+                    adapter.addToStart(chatMessageList.get(i),
+                            layoutManager.findLastVisibleItemPosition() <= adapter.getItemCount() - 3);
                 }
 
                 globalLastKnownFutureMessageId = Integer.parseInt(response.headers().get("X-Chat-Last-Given"));
@@ -315,4 +366,15 @@ public class ChatController extends BaseController implements MessagesListAdapte
             pullChatMessages(0);
         }
     }
-}
+
+
+    @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);
+        }
+    }}

+ 27 - 18
app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java

@@ -137,7 +137,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
     @BindView(R.id.clear_button)
     Button clearButton;
 
-    private UserEntity userEntity;
+    private UserEntity currentUser;
     private Disposable contactsQueryDisposable;
     private Disposable cacheQueryDisposable;
     private FlexibleAdapter adapter;
@@ -196,9 +196,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
         FlipView.resetLayoutAnimationDelay(true, 1000L);
         FlipView.stopLayoutAnimation();
 
-        userEntity = userUtils.getCurrentUser();
+        currentUser = userUtils.getCurrentUser();
 
-        if (userEntity == null &&
+        if (currentUser == null &&
                 getParentController() != null && getParentController().getRouter() != null) {
             getParentController().getRouter().setRoot((RouterTransaction.with(new ServerSelectionController())
                     .pushChangeHandler(new HorizontalChangeHandler())
@@ -210,7 +210,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
             adapter.setNotifyChangeOfUnfilteredItems(true)
                     .setMode(SelectableAdapter.Mode.MULTI);
 
-            if (userEntity != null) {
+            if (currentUser != null) {
                 fetchData();
             }
         }
@@ -248,9 +248,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
     public void onDoneButtonClick() {
 
         if (!isPublicCall && adapter.getSelectedPositions().size() == 1) {
-            RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(userEntity.getBaseUrl(), "1",
+            RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), "1",
                     ((UserItem) adapter.getItem(adapter.getSelectedPositions().get(0))).getModel().getUserId(), null);
-            ncApi.createRoom(ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()),
+            ncApi.createRoom(ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
                     retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
                     .subscribeOn(Schedulers.newThread())
                     .observeOn(AndroidSchedulers.mainThread())
@@ -266,7 +266,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
                                 Intent callIntent = new Intent(getActivity(), CallActivity.class);
                                 Bundle bundle = new Bundle();
                                 bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken());
-                                bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(userEntity));
+                                bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(currentUser));
                                 callIntent.putExtras(bundle);
                                 startActivity(callIntent);
                                 new Handler().postDelayed(() -> getRouter().popCurrentController(), 100);
@@ -402,10 +402,10 @@ public class ContactsController extends BaseController implements SearchView.OnQ
         contactItems = new ArrayList<>();
         userHeaderItems = new HashMap<>();
 
-        RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForContactsSearch(userEntity.getBaseUrl(),
+        RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForContactsSearch(currentUser.getBaseUrl(),
                 "");
         contactsQueryDisposable = ncApi.getContactsWithSearchParam(
-                ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()),
+                ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
                 retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
                 .subscribeOn(Schedulers.newThread())
                 .observeOn(AndroidSchedulers.mainThread())
@@ -424,7 +424,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
 
                                 Participant participant;
                                 for (Sharee sharee : shareeHashSet) {
-                                    if (!sharee.getValue().getShareWith().equals(userEntity.getUsername())) {
+                                    if (!sharee.getValue().getShareWith().equals(currentUser.getUsername())) {
                                         participant = new Participant();
                                         participant.setName(sharee.getLabel());
                                         String headerTitle;
@@ -438,7 +438,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
                                         }
 
                                         participant.setUserId(sharee.getValue().getShareWith());
-                                        contactItems.add(new UserItem(participant, userEntity,
+                                        contactItems.add(new UserItem(participant, currentUser,
                                                 userHeaderItems.get(headerTitle)));
                                     }
 
@@ -492,7 +492,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ
                                         if (getParentController() != null &&
                                                 getParentController().getRouter() != null) {
                                             getParentController().getRouter().pushController((RouterTransaction.with
-                                                    (new WebViewLoginController(userEntity.getBaseUrl(),
+                                                    (new WebViewLoginController(currentUser.getBaseUrl(),
                                                             true))
                                                     .pushChangeHandler(new VerticalChangeHandler())
                                                     .popChangeHandler(new VerticalChangeHandler())));
@@ -700,9 +700,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
         if (adapter.getItem(position) instanceof UserItem) {
             if (!isNewConversationView) {
                 UserItem userItem = (UserItem) adapter.getItem(position);
-                RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(userEntity.getBaseUrl(), "1",
+                RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), "1",
                         userItem.getModel().getUserId(), null);
-                ncApi.createRoom(ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()),
+                ncApi.createRoom(ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
                         retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
                         .subscribeOn(Schedulers.newThread())
                         .observeOn(AndroidSchedulers.mainThread())
@@ -715,12 +715,21 @@ public class ContactsController extends BaseController implements SearchView.OnQ
                             @Override
                             public void onNext(RoomOverall roomOverall) {
                                 if (getActivity() != null) {
-                                    Intent callIntent = new Intent(getActivity(), CallActivity.class);
+                                    Intent conversationIntent = new Intent(getActivity(), CallActivity.class);
                                     Bundle bundle = new Bundle();
                                     bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken());
-                                    bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(userEntity));
-                                    callIntent.putExtras(bundle);
-                                    startActivity(callIntent);
+                                    bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(currentUser));
+                                    conversationIntent.putExtras(bundle);
+
+                                    if (currentUser.hasSpreedCapabilityWithName("chat-v2")) {
+                                        bundle.putString(BundleKeys.KEY_CONVERSATION_NAME,
+                                                roomOverall.getOcs().getData().getDisplayName());
+                                        getParentController().getRouter().pushController((RouterTransaction.with(new ChatController(bundle))
+                                                .pushChangeHandler(new HorizontalChangeHandler())
+                                                .popChangeHandler(new HorizontalChangeHandler())));
+                                    } else {
+                                        startActivity(conversationIntent);
+                                    }
                                 }
                             }
 

+ 2 - 7
app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java

@@ -22,7 +22,6 @@ package com.nextcloud.talk.models.json.chat;
 import com.bluelinelabs.logansquare.annotation.JsonField;
 import com.bluelinelabs.logansquare.annotation.JsonObject;
 import com.nextcloud.talk.utils.ApiUtils;
-import com.nextcloud.talk.utils.TimeUtils;
 import com.stfalcon.chatkit.commons.models.IMessage;
 import com.stfalcon.chatkit.commons.models.IUser;
 
@@ -95,17 +94,13 @@ public class ChatMessage implements IMessage {
 
             @Override
             public String getAvatar() {
-                if ("guests".equals(actorType)) {
-                    return null;
-                } else {
-                    return ApiUtils.getUrlForAvatarWithName(getBaseUrl(), actorId, false);
-                }
+                return ApiUtils.getUrlForAvatarWithName(getBaseUrl(), actorId, false);
             }
         };
     }
 
     @Override
     public Date getCreatedAt() {
-        return TimeUtils.getDateCurrentTimeZone(timestamp);
+        return new Date(timestamp * 1000L);
     }
 }

+ 0 - 52
app/src/main/java/com/nextcloud/talk/utils/TimeUtils.java

@@ -1,52 +0,0 @@
-/*
- * 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.utils;
-
-import android.util.Log;
-
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-public class TimeUtils {
-    private static final String TAG = "TimeUtils";
-
-    public static Date getDateCurrentTimeZone(long timestamp) {
-        try{
-            Calendar calendar = Calendar.getInstance();
-            TimeZone tz = Calendar.getInstance().getTimeZone();
-            calendar.setTimeInMillis(timestamp * 1000);
-            calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis()));
-            Date currentTimeZone = calendar.getTime();
-            return currentTimeZone;
-        } catch (Exception e) {
-            Log.d(TAG, "Failed to convert time to local timezone");
-        }
-        return new Date();
-    }
-
-    public static String getDateStringCurrentTimeZone(long timestamp) {
-        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
-        return simpleDateFormat.format(getDateCurrentTimeZone(timestamp));
-    }
-}

+ 6 - 2
app/src/main/res/layout/controller_chat.xml

@@ -29,6 +29,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_above="@+id/input"
+        app:outcomingDefaultBubbleColor="@color/colorPrimary"
+        app:outcomingDefaultBubbleSelectedColor="@color/colorPrimaryDark"
         app:textAutoLink="all"/>
 
     <View
@@ -45,11 +47,13 @@
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:maxLength="1000"
+        app:inputButtonDefaultBgColor="@color/colorPrimary"
+        app:inputButtonDefaultBgPressedColor="@color/colorPrimaryDark"
         app:inputButtonHeight="30dp"
         app:inputButtonMargin="16dp"
         app:inputButtonWidth="30dp"
-        app:inputHint="@string/hint_enter_a_message"
+        app:inputHint="@string/nc_hint_enter_a_message"
         app:inputTextColor="@color/black"
         app:inputTextSize="18sp"/>
 
-</RelativeLayout>
+</RelativeLayout>

+ 6 - 1
app/src/main/res/values/strings.xml

@@ -164,5 +164,10 @@ Millions of users use Nextcloud daily at businesses and homes around the world.
 Learn more on https://nextcloud.com/talk
 
 Find Nextcloud on https://nextcloud.com</string>
-    <string name="hint_enter_a_message">Enter a message…</string>
+
+    <!-- Chat -->
+    <string name="nc_hint_enter_a_message">Enter a message…</string>
+    <string name="nc_date_header_yesterday">Yesterday</string>
+    <string name="nc_date_header_today">Today</string>
+
 </resources>