UI improvements

This commit is contained in:
sowjanyakch 2024-02-05 22:43:00 +01:00
parent 426c8823c5
commit d27c7a6212
8 changed files with 296 additions and 107 deletions

View File

@ -79,7 +79,6 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
sharedApplication!!.componentApplication.inject(this) sharedApplication!!.componentApplication.inject(this)
setAvatarAndAuthorOnMessageItem(message) setAvatarAndAuthorOnMessageItem(message)
colorizeMessageBubble(message) colorizeMessageBubble(message)
itemView.isSelected = false itemView.isSelected = false
@ -114,14 +113,6 @@ class IncomingTextMessageViewHolder(itemView: View, payload: Any) :
binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
binding.messageText.text = processedMessageText binding.messageText.text = processedMessageText
if (message.parentMessage?.id != null && message.systemMessageType == ChatMessage.SystemMessageType
.MESSAGE_EDITED
) {
binding.messageType.visibility = View.VISIBLE
} else {
binding.messageType.visibility = View.GONE
}
binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp) binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp)
// parent message handling // parent message handling

View File

@ -100,13 +100,6 @@ class OutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewH
setBubbleOnChatMessage(message) setBubbleOnChatMessage(message)
binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
if (message.parentMessage?.id != null && message.systemMessageType == ChatMessage.SystemMessageType
.MESSAGE_EDITED
) {
binding.messageType.visibility = View.VISIBLE
} else {
binding.messageType.visibility = View.GONE
}
binding.messageTime.layoutParams = layoutParams binding.messageTime.layoutParams = layoutParams
viewThemeUtils.platform.colorTextView(binding.messageText, ColorRole.ON_SURFACE_VARIANT) viewThemeUtils.platform.colorTextView(binding.messageText, ColorRole.ON_SURFACE_VARIANT)
binding.messageText.text = processedMessageText binding.messageText.text = processedMessageText

View File

@ -24,7 +24,6 @@
package com.nextcloud.talk.api; package com.nextcloud.talk.api;
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall; import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
import com.nextcloud.talk.models.json.chat.ChatOCSSingleMessage;
import com.nextcloud.talk.models.json.chat.ChatOverall; import com.nextcloud.talk.models.json.chat.ChatOverall;
import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage; import com.nextcloud.talk.models.json.chat.ChatOverallSingleMessage;
import com.nextcloud.talk.models.json.chat.ChatShareOverall; import com.nextcloud.talk.models.json.chat.ChatShareOverall;
@ -97,14 +96,19 @@ public interface NcApi {
*/ */
@GET @GET
Observable<ResponseBody> getContactsWithSearchParam(@Header("Authorization") String authorization, @Url String url, @Nullable @Query("shareTypes[]") List<String> listOfShareTypes, @QueryMap Map<String, Object> options); Observable<ResponseBody> getContactsWithSearchParam(@Header("Authorization") String authorization,
@Url String url,
@Nullable @Query("shareTypes[]") List<String> listOfShareTypes,
@QueryMap Map<String, Object> options);
/* /*
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room
*/ */
@GET @GET
Observable<RoomsOverall> getRooms(@Header("Authorization") String authorization, @Url String url, @Nullable @Query("includeStatus") Boolean includeStatus); Observable<RoomsOverall> getRooms(@Header("Authorization") String authorization,
@Url String url,
@Nullable @Query("includeStatus") Boolean includeStatus);
/* /*
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken
@ -121,7 +125,9 @@ public interface NcApi {
*/ */
@POST @POST
Observable<RoomOverall> createRoom(@Header("Authorization") String authorization, @Url String url, @QueryMap Map<String, String> options); Observable<RoomOverall> createRoom(@Header("Authorization") String authorization,
@Url String url,
@QueryMap Map<String, String> options);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
@ -132,12 +138,16 @@ public interface NcApi {
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> renameRoom(@Header("Authorization") String authorization, @Url String url, @Field("roomName") String roomName); Observable<GenericOverall> renameRoom(@Header("Authorization") String authorization,
@Url String url,
@Field("roomName") String roomName);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setConversationDescription(@Header("Authorization") String authorization, @Url String url, @Field("description") String description); Observable<GenericOverall> setConversationDescription(@Header("Authorization") String authorization,
@Url String url,
@Field("description") String description);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
@ -146,32 +156,48 @@ public interface NcApi {
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken/participants Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken/participants
*/ */
@POST @POST
Observable<AddParticipantOverall> addParticipant(@Header("Authorization") String authorization, @Url String url, @QueryMap Map<String, String> options); Observable<AddParticipantOverall> addParticipant(@Header("Authorization") String authorization,
@Url String url,
@QueryMap Map<String,
String> options);
@POST @POST
Observable<GenericOverall> resendParticipantInvitations(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> resendParticipantInvitations(@Header("Authorization") String authorization,
@Url String url);
// also used for removing a guest from a conversation // also used for removing a guest from a conversation
@Deprecated @Deprecated
@DELETE @DELETE
Observable<GenericOverall> removeParticipantFromConversation(@Header("Authorization") String authorization, @Url String url, @Query("participant") String participantId); Observable<GenericOverall> removeParticipantFromConversation(@Header("Authorization") String authorization,
@Url String url,
@Query("participant") String participantId);
@DELETE @DELETE
Observable<GenericOverall> removeAttendeeFromConversation(@Header("Authorization") String authorization, @Url String url, @Query("attendeeId") Long attendeeId); Observable<GenericOverall> removeAttendeeFromConversation(@Header("Authorization") String authorization,
@Url String url,
@Query("attendeeId") Long attendeeId);
@Deprecated @Deprecated
@POST @POST
Observable<GenericOverall> promoteUserToModerator(@Header("Authorization") String authorization, @Url String url, @Query("participant") String participantId); Observable<GenericOverall> promoteUserToModerator(@Header("Authorization") String authorization,
@Url String url,
@Query("participant") String participantId);
@Deprecated @Deprecated
@DELETE @DELETE
Observable<GenericOverall> demoteModeratorToUser(@Header("Authorization") String authorization, @Url String url, @Query("participant") String participantId); Observable<GenericOverall> demoteModeratorToUser(@Header("Authorization") String authorization,
@Url String url,
@Query("participant") String participantId);
@POST @POST
Observable<GenericOverall> promoteAttendeeToModerator(@Header("Authorization") String authorization, @Url String url, @Query("attendeeId") Long attendeeId); Observable<GenericOverall> promoteAttendeeToModerator(@Header("Authorization") String authorization,
@Url String url,
@Query("attendeeId") Long attendeeId);
@DELETE @DELETE
Observable<GenericOverall> demoteAttendeeFromModerator(@Header("Authorization") String authorization, @Url String url, @Query("attendeeId") Long attendeeId); Observable<GenericOverall> demoteAttendeeFromModerator(@Header("Authorization") String authorization,
@Url String url,
@Query("attendeeId") Long attendeeId);
/* /*
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken/participants/self Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken/participants/self
@ -202,11 +228,15 @@ public interface NcApi {
Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization, @Url String url); Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization, @Url String url);
@GET @GET
Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization, @Url String url, @QueryMap Map<String, Boolean> fields); Observable<ParticipantsOverall> getPeersForCall(@Header("Authorization") String authorization,
@Url String url,
@QueryMap Map<String, Boolean> fields);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<RoomOverall> joinRoom(@Nullable @Header("Authorization") String authorization, @Url String url, @Nullable @Field("password") String password); Observable<RoomOverall> joinRoom(@Nullable @Header("Authorization") String authorization,
@Url String url,
@Nullable @Field("password") String password);
@DELETE @DELETE
Observable<GenericOverall> leaveRoom(@Nullable @Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> leaveRoom(@Nullable @Header("Authorization") String authorization, @Url String url);
@ -217,7 +247,11 @@ public interface NcApi {
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> joinCall(@Nullable @Header("Authorization") String authorization, @Url String url, @Field("flags") Integer inCall, @Field("silent") Boolean callWithoutNotification, @Nullable @Field("recordingConsent") Boolean recordingConsent); Observable<GenericOverall> joinCall(@Nullable @Header("Authorization") String authorization,
@Url String url,
@Field("flags") Integer inCall,
@Field("silent") Boolean callWithoutNotification,
@Nullable @Field("recordingConsent") Boolean recordingConsent);
/* /*
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /call/callToken Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /call/callToken
@ -226,7 +260,8 @@ public interface NcApi {
Observable<GenericOverall> leaveCall(@Nullable @Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> leaveCall(@Nullable @Header("Authorization") String authorization, @Url String url);
@GET @GET
Observable<SignalingSettingsOverall> getSignalingSettings(@Nullable @Header("Authorization") String authorization, @Url String url); Observable<SignalingSettingsOverall> getSignalingSettings(@Nullable @Header("Authorization") String authorization,
@Url String url);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
@ -236,13 +271,16 @@ public interface NcApi {
*/ */
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<SignalingOverall> sendSignalingMessages(@Nullable @Header("Authorization") String authorization, @Url String url, @Field("messages") String messages); Observable<SignalingOverall> sendSignalingMessages(@Nullable @Header("Authorization") String authorization,
@Url String url,
@Field("messages") String messages);
/* /*
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /signaling Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /signaling
*/ */
@GET @GET
Observable<SignalingOverall> pullSignalingMessages(@Nullable @Header("Authorization") String authorization, @Url String url); Observable<SignalingOverall> pullSignalingMessages(@Nullable @Header("Authorization") String authorization,
@Url String url);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
@ -260,7 +298,11 @@ public interface NcApi {
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setUserData(@Header("Authorization") String authorization, @Url String url, @Field("key") String key, @Field("value") String value); Observable<GenericOverall> setUserData(@Header("Authorization") String authorization,
@Url String url,
@Field("key") String key,
@Field("value") String value);
/* /*
Server URL is: baseUrl + /status.php Server URL is: baseUrl + /status.php
@ -280,14 +322,21 @@ public interface NcApi {
*/ */
@POST @POST
Observable<PushRegistrationOverall> registerDeviceForNotificationsWithNextcloud(@Header("Authorization") String authorization, @Url String url, @QueryMap Map<String, String> options); Observable<PushRegistrationOverall> registerDeviceForNotificationsWithNextcloud(
@Header("Authorization") String authorization,
@Url String url,
@QueryMap Map<String, String> options);
@DELETE @DELETE
Observable<GenericOverall> unregisterDeviceForNotificationsWithNextcloud(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> unregisterDeviceForNotificationsWithNextcloud(
@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<Unit> registerDeviceForNotificationsWithPushProxy(@Url String url, @FieldMap Map<String, String> fields); Observable<Unit> registerDeviceForNotificationsWithPushProxy(@Url String url,
@FieldMap Map<String, String> fields);
/* /*
QueryMap items are as follows: QueryMap items are as follows:
@ -296,15 +345,20 @@ public interface NcApi {
- "userPublicKey": "{{userPublicKey}}" - "userPublicKey": "{{userPublicKey}}"
*/ */
@DELETE @DELETE
Observable<Void> unregisterDeviceForNotificationsWithProxy(@Url String url, @QueryMap Map<String, String> fields); Observable<Void> unregisterDeviceForNotificationsWithProxy(@Url String url,
@QueryMap Map<String,String> fields);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setPassword(@Header("Authorization") String authorization, @Url String url, @Field("password") String password); Observable<GenericOverall> setPassword(@Header("Authorization") String authorization,
@Url String url,
@Field("password") String password);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<Response<GenericOverall>> setPassword2(@Header("Authorization") String authorization, @Url String url, @Field("password") String password); Observable<Response<GenericOverall>> setPassword2(@Header("Authorization") String authorization,
@Url String url,
@Field("password") String password);
@GET @GET
Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url); Observable<CapabilitiesOverall> getCapabilities(@Header("Authorization") String authorization, @Url String url);
@ -320,7 +374,9 @@ public interface NcApi {
- "lastKnownMessageId", int, use one from X-Chat-Last-Given - "lastKnownMessageId", int, use one from X-Chat-Last-Given
*/ */
@GET @GET
Observable<Response<ChatOverall>> pullChatMessages(@Header("Authorization") String authorization, @Url String url, @QueryMap Map<String, Integer> fields); Observable<Response<ChatOverall>> pullChatMessages(@Header("Authorization") String authorization,
@Url String url,
@QueryMap Map<String, Integer> fields);
/* /*
Fieldmap items are as follows: Fieldmap items are as follows:
@ -330,70 +386,113 @@ public interface NcApi {
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> sendChatMessage(@Header("Authorization") String authorization, @Url String url, @Field("message") CharSequence message, @Field("actorDisplayName") String actorDisplayName, @Field("replyTo") Integer replyTo, @Field("silent") Boolean sendWithoutNotification); Observable<GenericOverall> sendChatMessage(@Header("Authorization") String authorization,
@Url String url,
@Field("message") CharSequence message,
@Field("actorDisplayName") String actorDisplayName,
@Field("replyTo") Integer replyTo,
@Field("silent") Boolean sendWithoutNotification);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<ChatOverallSingleMessage> editChatMessage(@Header("Authorization") String authorization, @Url String url, @Field( Observable<ChatOverallSingleMessage> editChatMessage(@Header("Authorization") String authorization,
"message") String message); @Url String url,
@Field("message") String message);
@GET @GET
Observable<Response<ChatShareOverall>> getSharedItems(@Header("Authorization") String authorization, @Url String url, @Query("objectType") String objectType, @Nullable @Query("lastKnownMessageId") Integer lastKnownMessageId, @Nullable @Query("limit") Integer limit); Observable<Response<ChatShareOverall>> getSharedItems(
@Header("Authorization") String authorization,
@Url String url,
@Query("objectType") String objectType,
@Nullable @Query("lastKnownMessageId") Integer lastKnownMessageId,
@Nullable @Query("limit") Integer limit);
@GET @GET
Observable<Response<ChatShareOverviewOverall>> getSharedItemsOverview(@Header("Authorization") String authorization, @Url String url, @Nullable @Query("limit") Integer limit); Observable<Response<ChatShareOverviewOverall>> getSharedItemsOverview(@Header("Authorization") String authorization,
@Url String url,
@Nullable @Query("limit") Integer limit);
@GET @GET
Observable<MentionOverall> getMentionAutocompleteSuggestions(@Header("Authorization") String authorization, @Url String url, @Query("search") String query, @Nullable @Query("limit") Integer limit, @QueryMap Map<String, String> fields); Observable<MentionOverall> getMentionAutocompleteSuggestions(@Header("Authorization") String authorization,
@Url String url,
@Query("search") String query,
@Nullable @Query("limit") Integer limit,
@QueryMap Map<String, String> fields);
// Url is: /api/{apiVersion}/room/{token}/pin // Url is: /api/{apiVersion}/room/{token}/pin
@POST @POST
Observable<GenericOverall> addConversationToFavorites(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> addConversationToFavorites(@Header("Authorization") String authorization,
@Url String url);
// Url is: /api/{apiVersion}/room/{token}/favorites // Url is: /api/{apiVersion}/room/{token}/favorites
@DELETE @DELETE
Observable<GenericOverall> removeConversationFromFavorites(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> removeConversationFromFavorites(@Header("Authorization") String authorization,
@Url String url);
@GET @GET
Observable<NotificationOverall> getNcNotification(@Header("Authorization") String authorization, @Url String url); Observable<NotificationOverall> getNcNotification(@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> setNotificationLevel(@Header("Authorization") String authorization, @Url String url, @Field("level") int level); Observable<GenericOverall> setNotificationLevel(@Header("Authorization") String authorization,
@Url String url,
@Field("level") int level);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setReadOnlyState(@Header("Authorization") String authorization, @Url String url, @Field("state") int state); Observable<GenericOverall> setReadOnlyState(@Header("Authorization") String authorization,
@Url String url,
@Field("state") int state);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> createRemoteShare(@Nullable @Header("Authorization") String authorization, @Url String url, @Field("path") String remotePath, @Field("shareWith") String roomToken, @Field("shareType") String shareType, @Field("talkMetaData") String talkMetaData); Observable<GenericOverall> createRemoteShare(@Nullable @Header("Authorization") String authorization,
@Url String url,
@Field("path") String remotePath,
@Field("shareWith") String roomToken,
@Field("shareType") String shareType,
@Field("talkMetaData") String talkMetaData);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setLobbyForConversation(@Header("Authorization") String authorization, @Url String url, @Field("state") Integer state, @Field("timer") Long timer); Observable<GenericOverall> setLobbyForConversation(@Header("Authorization") String authorization,
@Url String url,
@Field("state") Integer state,
@Field("timer") Long timer);
@POST @POST
Observable<GenericOverall> setReadStatusPrivacy(@Header("Authorization") String authorization, @Url String url, @Body RequestBody body); Observable<GenericOverall> setReadStatusPrivacy(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody body);
@POST @POST
Observable<GenericOverall> setTypingStatusPrivacy(@Header("Authorization") String authorization, @Url String url, @Body RequestBody body); Observable<GenericOverall> setTypingStatusPrivacy(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody body);
@POST @POST
Observable<ContactsByNumberOverall> searchContactsByPhoneNumber(@Header("Authorization") String authorization, @Url String url, @Body RequestBody search); Observable<ContactsByNumberOverall> searchContactsByPhoneNumber(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody search);
@PUT @PUT
Observable<Response<GenericOverall>> uploadFile(@Header("Authorization") String authorization, @Url String url, @Body RequestBody body); Observable<Response<GenericOverall>> uploadFile(@Header("Authorization") String authorization,
@Url String url,
@Body RequestBody body);
@HEAD @HEAD
Observable<Response<Void>> checkIfFileExists(@Header("Authorization") String authorization, @Url String url); Observable<Response<Void>> checkIfFileExists(@Header("Authorization") String authorization,
@Url String url);
@GET @GET
Call<ResponseBody> downloadFile(@Header("Authorization") String authorization, @Url String url); Call<ResponseBody> downloadFile(@Header("Authorization") String authorization,
@Url String url);
@DELETE @DELETE
Observable<ChatOverallSingleMessage> deleteChatMessage(@Header("Authorization") String authorization, @Url String url); Observable<ChatOverallSingleMessage> deleteChatMessage(@Header("Authorization") String authorization,
@Url String url);
@DELETE @DELETE
Observable<GenericOverall> deleteAvatar(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> deleteAvatar(@Header("Authorization") String authorization, @Url String url);
@ -404,28 +503,40 @@ public interface NcApi {
@Multipart @Multipart
@POST @POST
Observable<GenericOverall> uploadAvatar(@Header("Authorization") String authorization, @Url String url, @Part MultipartBody.Part attachment); Observable<GenericOverall> uploadAvatar(@Header("Authorization") String authorization,
@Url String url,
@Part MultipartBody.Part attachment);
@Multipart @Multipart
@POST @POST
Observable<RoomOverall> uploadConversationAvatar(@Header("Authorization") String authorization, @Url String url, @Part MultipartBody.Part attachment); Observable<RoomOverall> uploadConversationAvatar(@Header("Authorization") String authorization,
@Url String url,
@Part MultipartBody.Part attachment);
@GET @GET
Observable<UserProfileFieldsOverall> getEditableUserProfileFields(@Header("Authorization") String authorization, @Url String url); Observable<UserProfileFieldsOverall> getEditableUserProfileFields(@Header("Authorization") String authorization,
@Url String url);
@GET @GET
Call<ResponseBody> downloadResizedImage(@Header("Authorization") String authorization, @Url String url); Call<ResponseBody> downloadResizedImage(@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> sendLocation(@Header("Authorization") String authorization, @Url String url, @Field("objectType") String objectType, @Field("objectId") String objectId, @Field("metaData") String metaData); Observable<GenericOverall> sendLocation(@Header("Authorization") String authorization,
@Url String url,
@Field("objectType") String objectType,
@Field("objectId") String objectId,
@Field("metaData") String metaData);
@DELETE @DELETE
Observable<GenericOverall> clearChatHistory(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> clearChatHistory(@Header("Authorization") String authorization, @Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> notificationCalls(@Header("Authorization") String authorization, @Url String url, @Field("level") Integer level); Observable<GenericOverall> notificationCalls(@Header("Authorization") String authorization,
@Url String url,
@Field("level") Integer level);
@GET @GET
Observable<HoverCardOverall> hoverCard(@Header("Authorization") String authorization, @Url String url); Observable<HoverCardOverall> hoverCard(@Header("Authorization") String authorization, @Url String url);
@ -433,7 +544,9 @@ public interface NcApi {
// Url is: /api/{apiVersion}/chat/{token}/read // Url is: /api/{apiVersion}/chat/{token}/read
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> setChatReadMarker(@Header("Authorization") String authorization, @Url String url, @Field("lastReadMessage") int lastReadMessage); Observable<GenericOverall> setChatReadMarker(@Header("Authorization") String authorization,
@Url String url,
@Field("lastReadMessage") int lastReadMessage);
// Url is: /api/{apiVersion}/chat/{token}/read // Url is: /api/{apiVersion}/chat/{token}/read
@DELETE @DELETE
@ -461,62 +574,100 @@ public interface NcApi {
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setPredefinedStatusMessage(@Header("Authorization") String authorization, @Url String url, @Field("messageId") String selectedPredefinedMessageId, @Field("clearAt") Long clearAt); Observable<GenericOverall> setPredefinedStatusMessage(@Header("Authorization") String authorization,
@Url String url,
@Field("messageId") String selectedPredefinedMessageId,
@Field("clearAt") Long clearAt);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setCustomStatusMessage(@Header("Authorization") String authorization, @Url String url, @Field("statusIcon") String statusIcon, @Field("message") String message, @Field("clearAt") Long clearAt); Observable<GenericOverall> setCustomStatusMessage(@Header("Authorization") String authorization,
@Url String url,
@Field("statusIcon") String statusIcon,
@Field("message") String message,
@Field("clearAt") Long clearAt);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setStatusType(@Header("Authorization") String authorization, @Url String url, @Field("statusType") String statusType); Observable<GenericOverall> setStatusType(@Header("Authorization") String authorization,
@Url String url,
@Field("statusType") String statusType);
@POST @POST
Observable<GenericOverall> sendReaction(@Header("Authorization") String authorization, @Url String url, @Query("reaction") String reaction); Observable<GenericOverall> sendReaction(@Header("Authorization") String authorization,
@Url String url,
@Query("reaction") String reaction);
@DELETE @DELETE
Observable<GenericOverall> deleteReaction(@Header("Authorization") String authorization, @Url String url, @Query("reaction") String reaction); Observable<GenericOverall> deleteReaction(@Header("Authorization") String authorization,
@Url String url,
@Query("reaction") String reaction);
@GET @GET
Observable<ReactionsOverall> getReactions(@Header("Authorization") String authorization, @Url String url, @Query("reaction") String reaction); Observable<ReactionsOverall> getReactions(@Header("Authorization") String authorization,
@Url String url,
@Query("reaction") String reaction);
@GET @GET
Observable<UnifiedSearchOverall> performUnifiedSearch(@Header("Authorization") String authorization, @Url String url, @Query("term") String term, @Query("from") String fromUrl, @Query("limit") Integer limit, @Query("cursor") Integer cursor); Observable<UnifiedSearchOverall> performUnifiedSearch(@Header("Authorization") String authorization,
@Url String url,
@Query("term") String term,
@Query("from") String fromUrl,
@Query("limit") Integer limit,
@Query("cursor") Integer cursor);
@GET @GET
Observable<PollOverall> getPoll(@Header("Authorization") String authorization, @Url String url); Observable<PollOverall> getPoll(@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<PollOverall> createPoll(@Header("Authorization") String authorization, @Url String url, @Query("question") String question, @Field("options[]") List<String> options, @Query("resultMode") Integer resultMode, @Query("maxVotes") Integer maxVotes); Observable<PollOverall> createPoll(@Header("Authorization") String authorization,
@Url String url,
@Query("question") String question,
@Field("options[]") List<String> options,
@Query("resultMode") Integer resultMode,
@Query("maxVotes") Integer maxVotes);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<PollOverall> votePoll(@Header("Authorization") String authorization, @Url String url, @Field("optionIds[]") List<Integer> optionIds); Observable<PollOverall> votePoll(@Header("Authorization") String authorization,
@Url String url,
@Field("optionIds[]") List<Integer> optionIds);
@DELETE @DELETE
Observable<PollOverall> closePoll(@Header("Authorization") String authorization, @Url String url); Observable<PollOverall> closePoll(@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> setMessageExpiration(@Header("Authorization") String authorization, @Url String url, @Field("seconds") Integer seconds); Observable<GenericOverall> setMessageExpiration(@Header("Authorization") String authorization,
@Url String url,
@Field("seconds") Integer seconds);
@GET @GET
Observable<OpenGraphOverall> getOpenGraph(@Header("Authorization") String authorization, @Url String url, @Query("reference") String urlToFindPreviewFor); Observable<OpenGraphOverall> getOpenGraph(@Header("Authorization") String authorization,
@Url String url,
@Query("reference") String urlToFindPreviewFor);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<GenericOverall> startRecording(@Header("Authorization") String authorization, @Url String url, @Field("status") Integer status); Observable<GenericOverall> startRecording(@Header("Authorization") String authorization,
@Url String url,
@Field("status") Integer status);
@DELETE @DELETE
Observable<GenericOverall> stopRecording(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> stopRecording(@Header("Authorization") String authorization,
@Url String url);
@POST @POST
Observable<GenericOverall> requestAssistance(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> requestAssistance(@Header("Authorization") String authorization,
@Url String url);
@DELETE @DELETE
Observable<GenericOverall> withdrawRequestAssistance(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> withdrawRequestAssistance(@Header("Authorization") String authorization,
@Url String url);
@POST @POST
Observable<GenericOverall> sendCommonPostRequest(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> sendCommonPostRequest(@Header("Authorization") String authorization, @Url String url);
@ -526,22 +677,33 @@ public interface NcApi {
@POST @POST
Observable<TranslationsOverall> translateMessage(@Header("Authorization") String authorization, @Url String url, @Query("text") String text, @Query("toLanguage") String toLanguage, @Nullable @Query("fromLanguage") String fromLanguage); Observable<TranslationsOverall> translateMessage(@Header("Authorization") String authorization,
@Url String url,
@Query("text") String text,
@Query("toLanguage") String toLanguage,
@Nullable @Query("fromLanguage") String fromLanguage);
@GET @GET
Observable<LanguagesOverall> getLanguages(@Header("Authorization") String authorization, @Url String url); Observable<LanguagesOverall> getLanguages(@Header("Authorization") String authorization,
@Url String url);
@GET @GET
Observable<ReminderOverall> getReminder(@Header("Authorization") String authorization, @Url String url); Observable<ReminderOverall> getReminder(@Header("Authorization") String authorization,
@Url String url);
@DELETE @DELETE
Observable<GenericOverall> deleteReminder(@Header("Authorization") String authorization, @Url String url); Observable<GenericOverall> deleteReminder(@Header("Authorization") String authorization,
@Url String url);
@FormUrlEncoded @FormUrlEncoded
@POST @POST
Observable<ReminderOverall> setReminder(@Header("Authorization") String authorization, @Url String url, @Field("timestamp") int timestamp); Observable<ReminderOverall> setReminder(@Header("Authorization") String authorization,
@Url String url,
@Field("timestamp") int timestamp);
@FormUrlEncoded @FormUrlEncoded
@PUT @PUT
Observable<GenericOverall> setRecordingConsent(@Header("Authorization") String authorization, @Url String url, @Field("recordingConsent") int recordingConsent); Observable<GenericOverall> setRecordingConsent(@Header("Authorization") String authorization,
@Url String url,
@Field("recordingConsent") int recordingConsent);
} }

View File

@ -835,6 +835,7 @@ class ChatActivity :
binding.messageInputView.recordAudioButton.visibility = View.GONE binding.messageInputView.recordAudioButton.visibility = View.GONE
binding.messageInputView.editMessageButton.visibility = View.VISIBLE binding.messageInputView.editMessageButton.visibility = View.VISIBLE
binding.editView.editMessageView.visibility = View.VISIBLE binding.editView.editMessageView.visibility = View.VISIBLE
binding.messageInputView.attachmentButton.visibility = View.GONE
} }
if (sharedText.isNotEmpty()) { if (sharedText.isNotEmpty()) {
@ -885,7 +886,8 @@ class ChatActivity :
conversationUser?.baseUrl, conversationUser?.baseUrl,
roomToken, roomToken,
message?.id message?.id
), editedMessageText ),
editedMessageText
)?.subscribeOn(Schedulers.io()) )?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread()) ?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<ChatOverallSingleMessage> { ?.subscribe(object : Observer<ChatOverallSingleMessage> {
@ -894,6 +896,29 @@ class ChatActivity :
} }
override fun onNext(messageEdited: ChatOverallSingleMessage) { override fun onNext(messageEdited: ChatOverallSingleMessage) {
when (messageEdited.ocs?.meta?.statusCode) {
HTTP_BAD_REQUEST -> {
Snackbar.make(
binding.root,
getString(R.string.edit_error_24_hours_old_message),
Snackbar.LENGTH_LONG
).show()
}
HTTP_FORBIDDEN -> {
Snackbar.make(
binding.root,
getString(R.string.conversation_is_read_only),
Snackbar.LENGTH_LONG
).show()
}
HTTP_NOT_FOUND -> {
Snackbar.make(
binding.root,
"Conversation not found",
Snackbar.LENGTH_LONG
).show()
}
}
message.message = messageEdited.ocs?.data?.parentMessage?.text message.message = messageEdited.ocs?.data?.parentMessage?.text
adapter?.update(message) adapter?.update(message)
adapter?.notifyDataSetChanged() adapter?.notifyDataSetChanged()
@ -901,11 +926,9 @@ class ChatActivity :
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
} }
override fun onComplete() { override fun onComplete() {
} }
}) })
} }
@ -915,6 +938,7 @@ class ChatActivity :
editableBehaviorSubject.onNext(false) editableBehaviorSubject.onNext(false)
binding.messageInputView.inputEditText.setText("") binding.messageInputView.inputEditText.setText("")
binding.editView.editMessageView.visibility = GONE binding.editView.editMessageView.visibility = GONE
binding.messageInputView.attachmentButton.visibility = View.VISIBLE
} }
private fun themeMessageInputView() { private fun themeMessageInputView() {
@ -988,7 +1012,7 @@ class ChatActivity :
) )
adapter?.setLoadMoreListener(this) adapter?.setLoadMoreListener(this)
adapter?.setDateHeadersFormatter {format(it)} adapter?.setDateHeadersFormatter { format(it) }
adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) }
adapter?.registerViewClickListener( adapter?.registerViewClickListener(
R.id.playPauseBtn R.id.playPauseBtn
@ -1084,7 +1108,6 @@ class ChatActivity :
R.layout.item_system_message, R.layout.item_system_message,
this this
) )
messageHolders.registerContentType( messageHolders.registerContentType(
CONTENT_TYPE_UNREAD_NOTICE_MESSAGE, CONTENT_TYPE_UNREAD_NOTICE_MESSAGE,
UnreadNoticeMessageViewHolder::class.java, UnreadNoticeMessageViewHolder::class.java,
@ -4333,7 +4356,6 @@ class ChatActivity :
} }
private fun showMicrophoneButton(show: Boolean) { private fun showMicrophoneButton(show: Boolean) {
if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) { if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
Log.d(TAG, "Microphone shown") Log.d(TAG, "Microphone shown")
binding.messageInputView.messageSendButton.visibility = View.GONE binding.messageInputView.messageSendButton.visibility = View.GONE

View File

@ -43,7 +43,7 @@ class MessageInput : MessageInput {
lateinit var sendVoiceRecording: ImageView lateinit var sendVoiceRecording: ImageView
lateinit var micInputCloud: MicInputCloud lateinit var micInputCloud: MicInputCloud
lateinit var playPauseBtn: MaterialButton lateinit var playPauseBtn: MaterialButton
lateinit var editMessageButton:ImageButton lateinit var editMessageButton: ImageButton
lateinit var seekBar: SeekBar lateinit var seekBar: SeekBar
constructor(context: Context?) : super(context) { constructor(context: Context?) : super(context) {

View File

@ -108,7 +108,7 @@ class MessageActionsDialog(
hasUserActorId(message) && hasUserActorId(message) &&
currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL currentConversation?.type != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
) )
initMenuEditMessage(CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "edit-messages")) initMenuEditMessage(CapabilitiesUtilNew.hasSpreedFeatureCapability(user, "edit-messages") && !message.isDeleted)
initMenuDeleteMessage(showMessageDeletionButton) initMenuDeleteMessage(showMessageDeletionButton)
initMenuForwardMessage( initMenuForwardMessage(
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() && ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() &&

View File

@ -1,5 +1,24 @@
<vector android:height="24dp" android:tint="#FFFFFF" <!--
android:viewportHeight="24" android:viewportWidth="24" @author Google LLC
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> Copyright (C) 2021 Google LLC
<path android:fillColor="@android:color/white" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
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"
android:tint="?attr/colorControlNormal">
<path android:fillColor="@color/fontAppbar" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector> </vector>

View File

@ -794,4 +794,6 @@ How to translate with transifex:
<string name="conversation_is_read_only">Conversation is read Only</string> <string name="conversation_is_read_only">Conversation is read Only</string>
<string name="nc_edit_message_text">Edit Message Text</string> <string name="nc_edit_message_text">Edit Message Text</string>
<string name="hint_edited_message">(edited)</string> <string name="hint_edited_message">(edited)</string>
<string name="nc_conversation_not_found">Conversation not found</string>
</resources> </resources>