瀏覽代碼

mark message as unread / conversation as read

Resolves #1464

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Andy Scherzinger 3 年之前
父節點
當前提交
1521e13e21

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

@@ -429,4 +429,11 @@ public interface NcApi {
 
     @GET
     Observable<HoverCardOverall> hoverCard(@Header("Authorization") String authorization, @Url String url);
+
+    // Url is: /api/{apiVersion}/chat/{token}/read
+    @FormUrlEncoded
+    @POST
+    Observable<GenericOverall> setChatReadMarker(@Header("Authorization") String authorization,
+                                                 @Url String url,
+                                                 @Field("lastReadMessage") int lastReadMessage);
 }

+ 32 - 0
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -2319,6 +2319,38 @@ class ChatController(args: Bundle) :
                         clipboardManager.setPrimaryClip(clipData)
                         true
                     }
+                    R.id.action_mark_as_unread -> {
+                        val chatMessage = message as ChatMessage?
+                        ncApi!!.setChatReadMarker(
+                            credentials,
+                            ApiUtils.getUrlForSetChatReadMarker(
+                                1,
+                                conversationUser?.baseUrl,
+                                roomToken
+                            ),
+                            chatMessage!!.jsonMessageId.minus(1)
+                        )
+                            .subscribeOn(Schedulers.io())
+                            .observeOn(AndroidSchedulers.mainThread())
+                            .subscribe(object : Observer<GenericOverall> {
+                                override fun onSubscribe(d: Disposable) {
+                                    // unused atm
+                                }
+
+                                override fun onNext(t: GenericOverall) {
+                                    // unused atm
+                                }
+
+                                override fun onError(e: Throwable) {
+                                    Log.e(TAG, e.message, e)
+                                }
+
+                                override fun onComplete() {
+                                    // unused atm
+                                }
+                            })
+                        true
+                    }
                     R.id.action_forward_message -> {
                         val bundle = Bundle()
                         bundle.putBoolean(BundleKeys.KEY_FORWARD_MSG_FLAG, true)

+ 7 - 1
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/CallMenuController.java

@@ -74,6 +74,7 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
 
 @AutoInjector(NextcloudTalkApplication.class)
 public class CallMenuController extends BaseController implements FlexibleAdapter.OnItemClickListener {
+    public static final int ALL_MESSAGES_READ = 0;
     @BindView(R.id.recycler_view)
     RecyclerView recyclerView;
 
@@ -170,6 +171,12 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
                                                                           R.color.grey_600)));
             }
 
+            if(conversation.unreadMessages > ALL_MESSAGES_READ && CapabilitiesUtil.canSetChatReadMarker(currentUser)) {
+                menuItems.add(new MenuItem(getResources().getString(R.string.nc_mark_as_read),
+                                           96,
+                                           ContextCompat.getDrawable(context, R.drawable.ic_eye)));
+            }
+
             if (conversation.isNameEditable(currentUser)) {
                 menuItems.add(new MenuItem(getResources().getString(R.string.nc_rename),
                                            2,
@@ -340,7 +347,6 @@ public class CallMenuController extends BaseController implements FlexibleAdapte
         }
 
         return null;
-
     }
 
     @Parcel

+ 13 - 0
app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java

@@ -33,6 +33,7 @@ import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
@@ -74,6 +75,7 @@ import io.reactivex.Observer;
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.Disposable;
 import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
 import retrofit2.HttpException;
 import retrofit2.Response;
 
@@ -480,6 +482,17 @@ public class OperationsMenuController extends BaseController {
                         });
 
                 break;
+            case 96:
+                // TODO: why does it break with v4?
+                ncApi.setChatReadMarker(credentials,
+                                        ApiUtils.getUrlForSetChatReadMarker(1,
+                                                                            currentUser.getBaseUrl(),
+                                                                            conversation.getToken()),
+                                        conversation.lastMessage.jsonMessageId)
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .retry(1)
+                    .subscribe(genericOperationsObserver);
             case 97:
             case 98:
                 if (operationCode == 97) {

+ 4 - 0
app/src/main/java/com/nextcloud/talk/models/database/CapabilitiesUtil.java

@@ -75,6 +75,10 @@ public abstract class CapabilitiesUtil {
         return !hasSpreedFeatureCapability(user, "chat-replies");
     }
 
+    public static boolean canSetChatReadMarker(@Nullable UserEntity user) {
+        return hasSpreedFeatureCapability(user, "chat-read-marker");
+    }
+
     public static boolean hasSpreedFeatureCapability(@Nullable UserEntity user, String capabilityName) {
         if (user != null && user.getCapabilities() != null) {
             try {

+ 4 - 0
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java

@@ -406,4 +406,8 @@ public class ApiUtils {
 
     public static String getUrlForHoverCard(String baseUrl, String userId) { return baseUrl + ocsApiVersion +
         "/hovercard/v1/" + userId; }
+
+    public static String getUrlForSetChatReadMarker(int version, String baseUrl, String roomToken) {
+        return getUrlForChat(version, baseUrl, roomToken) + "/read";
+    }
 }

+ 25 - 0
app/src/main/res/drawable/ic_eye.xml

@@ -0,0 +1,25 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2021 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#757575"
+        android:pathData="M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" />
+</vector>

+ 26 - 0
app/src/main/res/drawable/ic_eye_off.xml

@@ -0,0 +1,26 @@
+<!--
+    @author Google LLC
+    Copyright (C) 2021 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="@color/medium_emphasis_text"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#000"
+        android:pathData="M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z" />
+</vector>

+ 6 - 0
app/src/main/res/menu/chat_message_menu.xml

@@ -8,6 +8,12 @@
         android:title="@string/nc_copy_message"
         app:showAsAction="always" />
 
+    <item
+        android:id="@+id/action_mark_as_unread"
+        android:icon="@drawable/ic_eye_off"
+        android:title="@string/nc_mark_as_unread"
+        app:showAsAction="always" />
+
     <item
         android:id="@+id/action_forward_message"
         android:icon="@drawable/ic_share_action"

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -187,6 +187,8 @@
     <string name="nc_new_conversation">New conversation</string>
     <string name="nc_join_via_link">Join with a link</string>
     <string name="nc_join_via_web">Join via web</string>
+    <string name="nc_mark_as_read">Mark as read</string>
+    <string name="nc_mark_as_unread">Mark as unread</string>
     <string name="nc_add_to_favorites">Add to favorites</string>
     <string name="nc_remove_from_favorites">Remove from favorites</string>