Migrate ChatMesage, Conversation and directly linked data classes to kotlin

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
This commit is contained in:
Andy Scherzinger 2022-05-17 01:37:49 +02:00
parent 968e8d2bab
commit 8ed5432045
No known key found for this signature in database
GPG key ID: 6CADC7E3523C308B
38 changed files with 950 additions and 1691 deletions

View file

@ -288,7 +288,7 @@ public class CallNotificationActivity extends CallBaseActivity {
CapabilitiesUtil.hasSpreedFeatureCapability(userBeingCalled,
"conversation-call-flags");
if (hasCallFlags) {
if (isInCallWithVideo(currentConversation.callFlag)) {
if (isInCallWithVideo(currentConversation.getCallFlag())) {
binding.incomingCallVoiceOrVideoTextView.setText(
String.format(getResources().getString(R.string.nc_call_video),
getResources().getString(R.string.nc_app_product_name)));

View file

@ -281,7 +281,7 @@ class MainActivity : BaseActivity(), ActionBarProvider {
)
remapChatController(
router!!, currentUser.id,
roomOverall.ocs.data.token, bundle, true
roomOverall.ocs.data.token!!, bundle, true
)
}

View file

@ -165,10 +165,10 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
ContextCompat.getColor(context,
R.color.colorPrimary));
if (conversation.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
if (conversation.getType() == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
holder.binding.dialogUnreadBubble.setTextColor(Color.WHITE);
} else if (conversation.isUnreadMention()) {
} else if (conversation.getUnreadMention()) {
if (CapabilitiesUtil.hasSpreedFeatureCapability(userEntity, "direct-mention-flag")) {
if (conversation.getUnreadMentionDirect()) {
holder.binding.dialogUnreadBubble.setChipBackgroundColorResource(R.color.colorPrimary);
@ -196,7 +196,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
holder.binding.dialogUnreadBubble.setVisibility(View.GONE);
}
if (conversation.isFavorite()) {
if (conversation.getFavorite()) {
holder.binding.favoriteConversationImageView.setVisibility(View.VISIBLE);
} else {
holder.binding.favoriteConversationImageView.setVisibility(View.GONE);
@ -227,7 +227,7 @@ public class ConversationItem extends AbstractFlexibleItem<ConversationItem.Conv
String authorDisplayName = "";
conversation.getLastMessage().setActiveUser(userEntity);
String text;
if (conversation.getLastMessage().getMessageType() == ChatMessage.MessageType.REGULAR_TEXT_MESSAGE) {
if (conversation.getLastMessage().getCalculateMessageType() == ChatMessage.MessageType.REGULAR_TEXT_MESSAGE) {
if (conversation.getLastMessage().getActorId().equals(userEntity.getUserId())) {
text = String.format(appContext.getString(R.string.nc_formatted_message_you),
conversation.getLastMessage().getLastMessageDisplayText());

View file

@ -113,11 +113,11 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
}
private fun setAvatarAndAuthorOnMessageItem(message: ChatMessage) {
val author: String = message.actorDisplayName
val author: String = message.actorDisplayName!!
if (!TextUtils.isEmpty(author)) {
binding.messageAuthor.text = author
binding.messageUserAvatar.setOnClickListener {
(payload as? ProfileBottomSheet)?.showFor(message.actorId, itemView.context)
(payload as? ProfileBottomSheet)?.showFor(message.actorId!!, itemView.context)
}
} else {
binding.messageAuthor.setText(R.string.nc_nick_guest)
@ -180,13 +180,13 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
if (!message.isDeleted && message.parentMessage != null) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage!!.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {
@ -199,7 +199,7 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
binding.messageQuote.quotedMessageAuthor
.setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
@ -213,9 +213,9 @@ class IncomingLocationMessageViewHolder(incomingView: View, payload: Any) : Mess
@SuppressLint("SetJavaScriptEnabled", "ClickableViewAccessibility")
private fun setLocationDataOnMessageItem(message: ChatMessage) {
if (message.messageParameters != null && message.messageParameters.size > 0) {
for (key in message.messageParameters.keys) {
val individualHashMap: Map<String, String> = message.messageParameters[key]!!
if (message.messageParameters != null && message.messageParameters!!.size > 0) {
for (key in message.messageParameters!!.keys) {
val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!!
if (individualHashMap["type"] == "geo-location") {
locationLon = individualHashMap["longitude"]
locationLat = individualHashMap["latitude"]

View file

@ -154,7 +154,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
private fun updateDownloadState(message: ChatMessage) {
// check if download worker is already running
val fileId = message.getSelectedIndividualHashMap()["id"]
val fileId = message.selectedIndividualHashMap!!["id"]
val workers = WorkManager.getInstance(context!!).getWorkInfosByTag(fileId!!)
try {
@ -206,11 +206,11 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
}
private fun setAvatarAndAuthorOnMessageItem(message: ChatMessage) {
val author: String = message.actorDisplayName
val author: String = message.actorDisplayName!!
if (!TextUtils.isEmpty(author)) {
binding.messageAuthor.text = author
binding.messageUserAvatar.setOnClickListener {
(payload as? ProfileBottomSheet)?.showFor(message.actorId, itemView.context)
(payload as? ProfileBottomSheet)?.showFor(message.actorId!!, itemView.context)
}
} else {
binding.messageAuthor.setText(R.string.nc_nick_guest)
@ -281,13 +281,13 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
if (!message.isDeleted && message.parentMessage != null) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage!!.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {
@ -300,7 +300,7 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : Message
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context!!, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)

View file

@ -120,7 +120,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
binding.messageQuote.quotedChatMessageView.visibility = View.GONE
}
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.replyable)
Reaction().showReactions(message, binding.reactions, binding.messageText.context, false)
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
@ -136,7 +136,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
if (!TextUtils.isEmpty(message.actorDisplayName)) {
binding.messageAuthor.text = message.actorDisplayName
binding.messageUserAvatar.setOnClickListener {
(payload as? ProfileBottomSheet)?.showFor(message.actorId, itemView.context)
(payload as? ProfileBottomSheet)?.showFor(message.actorId!!, itemView.context)
}
} else {
binding.messageAuthor.setText(R.string.nc_nick_guest)
@ -169,13 +169,13 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
private fun processParentMessage(message: ChatMessage) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {
@ -188,7 +188,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context!!, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
@ -226,13 +226,13 @@ class MagicIncomingTextMessageViewHolder(itemView: View, payload: Any) : Message
}
private fun processMessageParameters(
messageParameters: HashMap<String, HashMap<String, String>>,
messageParameters: HashMap<String?, HashMap<String?, String?>>,
message: ChatMessage,
messageString: Spannable
): Spannable {
var messageStringInternal = messageString
for (key in messageParameters.keys) {
val individualHashMap = message.messageParameters[key]
val individualHashMap = message.messageParameters!![key]
if (individualHashMap != null) {
if (
individualHashMap["type"] == "user" ||

View file

@ -66,7 +66,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
override fun onBind(message: ChatMessage) {
super.onBind(message)
sharedApplication!!.componentApplication.inject(this)
val messageParameters: HashMap<String, HashMap<String, String>>? = message.messageParameters
val messageParameters: HashMap<String?, HashMap<String?, String?>>? = message.messageParameters
var messageString: Spannable = SpannableString(message.text)
realView.isSelected = false
binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60))
@ -119,7 +119,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
binding.checkMark.setContentDescription(readStatusContentDescriptionString)
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.replyable)
Reaction().showReactions(message, binding.reactions, context!!, true)
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
@ -133,13 +133,13 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
private fun processParentMessage(message: ChatMessage) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {
@ -183,13 +183,13 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
}
private fun processMessageParameters(
messageParameters: HashMap<String, HashMap<String, String>>,
messageParameters: HashMap<String?, HashMap<String?, String?>>,
message: ChatMessage,
messageString: Spannable
): Spannable {
var messageString1 = messageString
for (key in messageParameters.keys) {
val individualHashMap: HashMap<String, String>? = message.messageParameters[key]
val individualHashMap: HashMap<String?, String?>? = message.messageParameters!![key]
if (individualHashMap != null) {
if (individualHashMap["type"] == "user" ||
individualHashMap["type"] == "guest" ||

View file

@ -116,8 +116,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
public void onBind(ChatMessage message) {
super.onBind(message);
if (userAvatar != null) {
if (message.isGrouped || message.isOneToOneConversation) {
if (message.isOneToOneConversation) {
if (message.isGrouped() || message.isOneToOneConversation()) {
if (message.isOneToOneConversation()) {
userAvatar.setVisibility(View.GONE);
} else {
userAvatar.setVisibility(View.INVISIBLE);
@ -126,11 +126,11 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
userAvatar.setVisibility(View.VISIBLE);
userAvatar.setOnClickListener(v -> {
if (payload instanceof ProfileBottomSheet) {
((ProfileBottomSheet) payload).showFor(message.actorId, v.getContext());
((ProfileBottomSheet) payload).showFor(message.getActorId(), v.getContext());
}
});
if (ACTOR_TYPE_BOTS.equals(message.actorType) && ACTOR_ID_CHANGELOG.equals(message.actorId)) {
if (ACTOR_TYPE_BOTS.equals(message.getActorType()) && ACTOR_ID_CHANGELOG.equals(message.getActorId())) {
if (context != null) {
Drawable[] layers = new Drawable[2];
layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background);
@ -148,9 +148,9 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
clickView = getImage();
getMessageText().setVisibility(View.VISIBLE);
if (message.getMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
if (message.getCalculateMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
fileViewerUtils = new FileViewerUtils(context, message.activeUser);
fileViewerUtils = new FileViewerUtils(context, message.getActiveUser());
String fileName = message.getSelectedIndividualHashMap().get(KEY_NAME);
getMessageText().setText(fileName);
@ -177,10 +177,13 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
Drawable drawable = ContextCompat.getDrawable(context, drawableResourceId);
image.getHierarchy().setPlaceholderImage(drawable);
} else {
fetchFileInformation("/" + message.getSelectedIndividualHashMap().get(KEY_PATH), message.activeUser);
fetchFileInformation("/" + message.getSelectedIndividualHashMap().get(KEY_PATH),
message.getActiveUser());
}
if (message.activeUser != null && message.activeUser.getUsername() != null && message.activeUser.getBaseUrl() != null) {
if (message.getActiveUser() != null &&
message.getActiveUser().getUsername() != null &&
message.getActiveUser().getBaseUrl() != null) {
clickView.setOnClickListener(v ->
fileViewerUtils.openFile(
message,
@ -202,10 +205,10 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
message.getSelectedIndividualHashMap().get(MagicPreviewMessageViewHolder.KEY_MIMETYPE),
new FileViewerUtils.ProgressUi(progressBar, getMessageText(), image));
} else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {
} else if (message.getCalculateMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {
getMessageText().setText("GIPHY");
DisplayUtils.setClickableString("GIPHY", "https://giphy.com", getMessageText());
} else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_TENOR_MESSAGE) {
} else if (message.getCalculateMessageType() == ChatMessage.MessageType.SINGLE_LINK_TENOR_MESSAGE) {
getMessageText().setText("Tenor");
DisplayUtils.setClickableString("Tenor", "https://tenor.com", getMessageText());
} else {
@ -221,7 +224,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
getMessageText().setText("");
}
itemView.setTag(REPLYABLE_VIEW_TAG, message.isReplyable());
itemView.setTag(REPLYABLE_VIEW_TAG, message.getReplyable());
reactionsBinding = getReactionsBinding();
new Reaction().showReactions(message, reactionsBinding, getMessageText().getContext(), true);

View file

@ -76,9 +76,9 @@ public class MagicSystemMessageViewHolder extends MessageHolders.IncomingTextMes
Spannable messageString = new SpannableString(message.getText());
if (message.messageParameters != null && message.messageParameters.size() > 0) {
for (String key : message.messageParameters.keySet()) {
Map<String, String> individualMap = message.messageParameters.get(key);
if (message.getMessageParameters() != null && message.getMessageParameters().size() > 0) {
for (String key : message.getMessageParameters().keySet()) {
Map<String, String> individualMap = message.getMessageParameters().get(key);
if (individualMap != null && individualMap.containsKey("name")) {
String searchText;
@ -97,6 +97,6 @@ public class MagicSystemMessageViewHolder extends MessageHolders.IncomingTextMes
text.setText(messageString);
itemView.setTag(REPLYABLE_VIEW_TAG, message.isReplyable());
itemView.setTag(REPLYABLE_VIEW_TAG, message.getReplyable());
}
}

View file

@ -126,9 +126,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
@SuppressLint("SetJavaScriptEnabled", "ClickableViewAccessibility")
private fun setLocationDataOnMessageItem(message: ChatMessage) {
if (message.messageParameters != null && message.messageParameters.size > 0) {
for (key in message.messageParameters.keys) {
val individualHashMap: Map<String, String> = message.messageParameters[key]!!
if (message.messageParameters != null && message.messageParameters!!.size > 0) {
for (key in message.messageParameters!!.keys) {
val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!!
if (individualHashMap["type"] == "geo-location") {
locationLon = individualHashMap["longitude"]
locationLat = individualHashMap["latitude"]
@ -185,13 +185,13 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
if (!message.isDeleted && message.parentMessage != null) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {

View file

@ -180,7 +180,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
private fun updateDownloadState(message: ChatMessage) {
// check if download worker is already running
val fileId = message.getSelectedIndividualHashMap()["id"]
val fileId = message.selectedIndividualHashMap!!["id"]
val workers = WorkManager.getInstance(context!!).getWorkInfosByTag(fileId!!)
try {
@ -235,13 +235,13 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) : MessageHolders
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
if (!message.isDeleted && message.parentMessage != null) {
val parentChatMessage = message.parentMessage
parentChatMessage.activeUser = message.activeUser
parentChatMessage!!.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)
)
}
} ?: run {

View file

@ -44,10 +44,10 @@ class Reaction {
isOutgoingMessage: Boolean
) {
binding.reactionsEmojiWrapper.removeAllViews()
if (message.reactions != null && message.reactions.isNotEmpty()) {
if (message.reactions != null && message.reactions!!.isNotEmpty()) {
var remainingEmojisToDisplay = MAX_EMOJIS_TO_DISPLAY
val showInfoAboutMoreEmojis = message.reactions.size > MAX_EMOJIS_TO_DISPLAY
val showInfoAboutMoreEmojis = message.reactions!!.size > MAX_EMOJIS_TO_DISPLAY
val textColor = getTextColor(context, isOutgoingMessage, binding)
val amountParams = getAmountLayoutParams(context)
@ -57,7 +57,7 @@ class Reaction {
val paddingTop = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_TOP, context).toInt()
val paddingBottom = DisplayUtils.convertDpToPixel(WRAPPER_PADDING_BOTTOM, context).toInt()
for ((emoji, amount) in message.reactions) {
for ((emoji, amount) in message.reactions!!) {
val emojiWithAmountWrapper = getEmojiWithAmountWrapperLayout(
context,
message,
@ -99,8 +99,8 @@ class Reaction {
emojiWithAmountWrapper.layoutParams = layoutInfo.wrapperParams
if (message.reactionsSelf != null &&
message.reactionsSelf.isNotEmpty() &&
message.reactionsSelf.contains(emoji)
message.reactionsSelf!!.isNotEmpty() &&
message.reactionsSelf!!.contains(emoji)
) {
emojiWithAmountWrapper.background =
AppCompatResources.getDrawable(context, R.drawable.reaction_self_background)

View file

@ -339,7 +339,7 @@ class ChatController(args: Bundle) :
currentConversation = roomOverall.ocs.data
Log.d(
TAG,
"getRoomInfo. token: " + currentConversation?.getToken() +
"getRoomInfo. token: " + currentConversation?.token +
" sessionId: " + currentConversation?.sessionId
)
loadAvatarForStatusBar()
@ -548,7 +548,7 @@ class ChatController(args: Bundle) :
if (!conversationUser?.userId.equals("?")) {
senderId = "users/" + conversationUser?.userId
} else {
senderId = currentConversation?.getActorType() + "/" + currentConversation?.getActorId()
senderId = currentConversation?.actorType + "/" + currentConversation?.actorId
}
Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: " + senderId)
@ -579,7 +579,7 @@ class ChatController(args: Bundle) :
adapter?.registerViewClickListener(
R.id.playPauseBtn
) { view, message ->
val filename = message.getSelectedIndividualHashMap()["name"]
val filename = message.selectedIndividualHashMap!!["name"]
val file = File(context!!.cacheDir, filename!!)
if (file.exists()) {
if (message.isPlayingVoiceMessage) {
@ -934,7 +934,7 @@ class ChatController(args: Bundle) :
}
if (mediaPlayer == null) {
val fileName = message.getSelectedIndividualHashMap()["name"]
val fileName = message.selectedIndividualHashMap!!["name"]
val absolutePath = context!!.cacheDir.absolutePath + "/" + fileName
mediaPlayer = MediaPlayer().apply {
setDataSource(absolutePath)
@ -978,17 +978,17 @@ class ChatController(args: Bundle) :
message.isDownloadingVoiceMessage = true
adapter?.update(message)
val baseUrl = message.activeUser.baseUrl
val userId = message.activeUser.userId
val baseUrl = message.activeUser!!.baseUrl
val userId = message.activeUser!!.userId
val attachmentFolder = CapabilitiesUtil.getAttachmentFolder(message.activeUser)
val fileName = message.getSelectedIndividualHashMap()["name"]
var size = message.getSelectedIndividualHashMap()["size"]
val fileName = message.selectedIndividualHashMap!!["name"]
var size = message.selectedIndividualHashMap!!["size"]
if (size == null) {
size = "-1"
}
val fileSize = size.toLong()
val fileId = message.getSelectedIndividualHashMap()["id"]
val path = message.getSelectedIndividualHashMap()["path"]
val fileId = message.selectedIndividualHashMap!!["id"]
val path = message.selectedIndividualHashMap!!["path"]
// check if download worker is already running
val workers = WorkManager.getInstance(
@ -1223,7 +1223,7 @@ class ChatController(args: Bundle) :
private fun shouldShowLobby(): Boolean {
if (currentConversation != null) {
return currentConversation?.shouldShowLobby(conversationUser) == true
return currentConversation?.shouldShowLobby(conversationUser!!) == true
}
return false
}
@ -1262,7 +1262,7 @@ class ChatController(args: Bundle) :
private fun checkLobbyState() {
if (currentConversation != null &&
currentConversation?.isLobbyViewApplicable(conversationUser) ?: false &&
currentConversation?.isLobbyViewApplicable(conversationUser!!) ?: false &&
isAlive()
) {
@ -1270,7 +1270,7 @@ class ChatController(args: Bundle) :
getRoomInfo()
}
if (currentConversation?.shouldShowLobby(conversationUser) ?: false) {
if (currentConversation?.shouldShowLobby(conversationUser!!) ?: false) {
binding.lobby.lobbyView.visibility = View.VISIBLE
binding.messagesListView.visibility = View.GONE
binding.messageInputView.visibility = View.GONE
@ -2026,7 +2026,7 @@ class ChatController(args: Bundle) :
}
pullChatMessagesPending = true
if (currentConversation != null && currentConversation!!.shouldShowLobby(conversationUser)) {
if (currentConversation != null && currentConversation!!.shouldShowLobby(conversationUser!!)) {
// return
}
@ -2181,7 +2181,7 @@ class ChatController(args: Bundle) :
if (response.code() == HTTP_CODE_OK) {
val chatOverall = response.body() as ChatOverall?
val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data)
val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data!!)
if (chatMessageList.isNotEmpty() &&
ChatMessage.SystemMessageType.CLEARED_CHAT == chatMessageList[0].systemMessageType
@ -2455,19 +2455,19 @@ class ChatController(args: Bundle) :
// setDeletionFlagsAndRemoveInfomessages
if (isInfoMessageAboutDeletion(currentMessage)) {
if (!chatMessageMap.containsKey(currentMessage.value.parentMessage.id)) {
if (!chatMessageMap.containsKey(currentMessage.value.parentMessage!!.id)) {
// if chatMessageMap doesn't contain message to delete (this happens when lookingIntoFuture),
// the message to delete has to be modified directly inside the adapter
setMessageAsDeleted(currentMessage.value.parentMessage)
} else {
chatMessageMap[currentMessage.value.parentMessage.id]!!.isDeleted = true
chatMessageMap[currentMessage.value.parentMessage!!.id]!!.isDeleted = true
}
chatMessageIterator.remove()
}
// delete reactions system messages
else if (isReactionsMessage(currentMessage)) {
if (!chatMessageMap.containsKey(currentMessage.value.parentMessage.id)) {
if (!chatMessageMap.containsKey(currentMessage.value.parentMessage!!.id)) {
updateAdapterForReaction(currentMessage.value.parentMessage)
}
@ -2569,7 +2569,7 @@ class ChatController(args: Bundle) :
}
private fun isSystemMessage(message: ChatMessage): Boolean {
return ChatMessage.MessageType.SYSTEM_MESSAGE == message.getMessageType()
return ChatMessage.MessageType.SYSTEM_MESSAGE == message.getCalculateMessageType()
}
fun deleteMessage(message: IMessage?) {
@ -2603,7 +2603,7 @@ class ChatController(args: Bundle) :
}
override fun onNext(t: ChatOverallSingleMessage) {
if (t.ocs.meta.statusCode == HttpURLConnection.HTTP_ACCEPTED) {
if (t.ocs.meta!!.statusCode == HttpURLConnection.HTTP_ACCEPTED) {
Toast.makeText(
context, R.string.nc_delete_message_leaked_to_matterbridge,
Toast.LENGTH_LONG
@ -2653,15 +2653,15 @@ class ChatController(args: Bundle) :
override fun onNext(roomOverall: RoomOverall) {
val bundle = Bundle()
bundle.putParcelable(KEY_USER_ENTITY, conversationUser)
bundle.putString(KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken())
bundle.putString(KEY_ROOM_ID, roomOverall.getOcs().getData().getRoomId())
bundle.putString(KEY_ROOM_TOKEN, roomOverall.getOcs().getData().token)
bundle.putString(KEY_ROOM_ID, roomOverall.getOcs().getData().roomId)
// FIXME once APIv2+ is used only, the createRoom already returns all the data
ncApi!!.getRoom(
credentials,
ApiUtils.getUrlForRoom(
apiVersion, conversationUser?.baseUrl,
roomOverall.getOcs().getData().getToken()
roomOverall.getOcs().getData().token
)
)
.subscribeOn(Schedulers.io())
@ -2678,7 +2678,7 @@ class ChatController(args: Bundle) :
)
remapChatController(
router, conversationUser!!.id,
roomOverall.getOcs().getData().getToken(), bundle, true
roomOverall.getOcs().getData().token!!, bundle, true
)
}
@ -2767,9 +2767,9 @@ class ChatController(args: Bundle) :
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
isShowMessageDeletionButton(message) || // delete
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType() || // forward
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() || // forward
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID && // mark as unread
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getCalculateMessageType() &&
BuildConfig.DEBUG
}
@ -2867,12 +2867,12 @@ class ChatController(args: Bundle) :
message.reactionsSelf = ArrayList<String>()
}
var amount = message.reactions[emoji]
var amount = message.reactions!![emoji]
if (amount == null) {
amount = 0
}
message.reactions[emoji] = amount + 1
message.reactionsSelf.add(emoji)
message.reactions!![emoji] = amount + 1
message.reactionsSelf!!.add(emoji)
adapter?.update(message)
}
@ -2905,7 +2905,7 @@ class ChatController(args: Bundle) :
override fun hasContentFor(message: ChatMessage, type: Byte): Boolean {
return when (type) {
CONTENT_TYPE_LOCATION -> message.hasGeoLocation()
CONTENT_TYPE_VOICE_MESSAGE -> message.isVoiceMessage()
CONTENT_TYPE_VOICE_MESSAGE -> message.isVoiceMessage
CONTENT_TYPE_SYSTEM_MESSAGE -> !TextUtils.isEmpty(message.systemMessage)
CONTENT_TYPE_UNREAD_NOTICE_MESSAGE -> message.id == "-1"
else -> false
@ -2980,7 +2980,7 @@ class ChatController(args: Bundle) :
ConductorRemapping.remapChatController(
router, conversationUser.id,
roomOverall.ocs.data.token, bundle, false
roomOverall.ocs.data.token!!, bundle, false
)
} else {
conversationIntent.putExtras(bundle)

View file

@ -263,15 +263,15 @@ class ContactsController(args: Bundle) :
override fun onNext(roomOverall: RoomOverall) {
val bundle = Bundle()
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken())
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().getRoomId())
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().token)
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().roomId)
// FIXME once APIv2 or later is used only, the createRoom already returns all the data
ncApi.getRoom(
credentials,
ApiUtils.getUrlForRoom(
apiVersion, currentUser!!.baseUrl,
roomOverall.getOcs().getData().getToken()
roomOverall.getOcs().getData().token
)
)
.subscribeOn(Schedulers.io())
@ -287,7 +287,7 @@ class ContactsController(args: Bundle) :
)
ConductorRemapping.remapChatController(
router, currentUser!!.id,
roomOverall.getOcs().getData().getToken(), bundle, true
roomOverall.getOcs().getData().token!!, bundle, true
)
}
@ -752,7 +752,7 @@ class ContactsController(args: Bundle) :
fun onMessageEvent(openConversationEvent: OpenConversationEvent) {
ConductorRemapping.remapChatController(
router, currentUser!!.id,
openConversationEvent.conversation!!.getToken(),
openConversationEvent.conversation!!.token!!,
openConversationEvent.bundle!!, true
)
contactsBottomDialog?.dismiss()
@ -827,8 +827,8 @@ class ContactsController(args: Bundle) :
if (activity != null) {
val bundle = Bundle()
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, currentUser)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken())
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().getRoomId())
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().token)
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().roomId)
bundle.putParcelable(
BundleKeys.KEY_ACTIVE_CONVERSATION,
Parcels.wrap(roomOverall.getOcs().getData())
@ -836,7 +836,7 @@ class ContactsController(args: Bundle) :
ConductorRemapping.remapChatController(
router,
currentUser!!.id,
roomOverall.getOcs().getData().getToken(),
roomOverall.getOcs().getData().token!!,
bundle,
true
)

View file

@ -208,7 +208,7 @@ class ConversationInfoController(args: Bundle) :
private fun setupWebinaryView() {
if (CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "webinary-lobby") &&
webinaryRoomType(conversation!!) &&
conversation!!.canModerate(conversationUser)
conversation!!.canModerate(conversationUser!!)
) {
binding.webinarInfoView.webinarSettings.visibility = View.VISIBLE
@ -223,7 +223,7 @@ class ConversationInfoController(args: Bundle) :
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
val currentTimeCalendar = Calendar.getInstance()
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer * DateConstants.SECOND_DIVIDER
currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER
}
dateTimePicker(
@ -278,7 +278,7 @@ class ConversationInfoController(args: Bundle) :
) {
binding.webinarInfoView.startTimePreferences.setSummary(
DateUtils.getLocalDateStringFromTimestampForLobby(
conversation!!.lobbyTimer
conversation!!.lobbyTimer!!
)
)
} else {
@ -639,7 +639,7 @@ class ConversationInfoController(args: Bundle) :
setupWebinaryView()
if (!conversation!!.canLeave(conversationUser)) {
if (!conversation!!.canLeave()) {
binding.leaveConversationAction.visibility = View.GONE
} else {
binding.leaveConversationAction.visibility = View.VISIBLE
@ -670,7 +670,7 @@ class ConversationInfoController(args: Bundle) :
binding.displayNameText.text = conversation!!.displayName
if (conversation!!.description != null && !conversation!!.description.isEmpty()) {
if (conversation!!.description != null && !conversation!!.description!!.isEmpty()) {
binding.descriptionText.text = conversation!!.description
binding.conversationDescription.visibility = View.VISIBLE
}
@ -979,7 +979,7 @@ class ConversationInfoController(args: Bundle) :
}
override fun onItemClick(view: View?, position: Int): Boolean {
if (!conversation!!.canModerate(conversationUser)) {
if (!conversation!!.canModerate(conversationUser!!)) {
return true
}

View file

@ -561,8 +561,10 @@ public class ConversationsListController extends BaseController implements Searc
}
for (Conversation conversation : roomsOverall.getOcs().getData()) {
if (bundle.containsKey(BundleKeys.INSTANCE.getKEY_FORWARD_HIDE_SOURCE_ROOM()) && conversation.roomId.equals(bundle.getString(
BundleKeys.INSTANCE.getKEY_FORWARD_HIDE_SOURCE_ROOM()))) {
if (bundle.containsKey(BundleKeys.INSTANCE.getKEY_FORWARD_HIDE_SOURCE_ROOM()) &&
conversation.getRoomId().equals(bundle.getString(
BundleKeys.INSTANCE.getKEY_FORWARD_HIDE_SOURCE_ROOM()))
) {
continue;
}
@ -581,7 +583,7 @@ public class ConversationsListController extends BaseController implements Searc
conversation,
currentUser,
getActivity(),
userStatuses.get(conversation.name));
userStatuses.get(conversation.getName()));
conversationItems.add(conversationItem);
ConversationItem conversationItemWithHeader = new ConversationItem(
@ -589,7 +591,7 @@ public class ConversationsListController extends BaseController implements Searc
currentUser,
getActivity(),
callHeaderItems.get(headerTitle),
userStatuses.get(conversation.name));
userStatuses.get(conversation.getName()));
conversationItemsWithHeader.add(conversationItemWithHeader);
}
}
@ -628,7 +630,7 @@ public class ConversationsListController extends BaseController implements Searc
Conversation conversation1 = ((ConversationItem) o1).getModel();
Conversation conversation2 = ((ConversationItem) o2).getModel();
return new CompareToBuilder()
.append(conversation2.isFavorite(), conversation1.isFavorite())
.append(conversation2.getFavorite(), conversation1.getFavorite())
.append(conversation2.getLastActivity(), conversation1.getLastActivity())
.toComparison();
});
@ -662,7 +664,7 @@ public class ConversationsListController extends BaseController implements Searc
currentUser,
getActivity(),
callHeaderItems.get(headerTitle),
userStatuses.get(conversation.name));
userStatuses.get(conversation.getName()));
openConversationItems.add(conversationItem);
}
@ -770,9 +772,9 @@ public class ConversationsListController extends BaseController implements Searc
for (AbstractFlexibleItem flexItem : conversationItems) {
Conversation conversationItem = ((ConversationItem) flexItem).getModel();
int position = adapter.getGlobalPositionOf(flexItem);
if ((conversationItem.unreadMention ||
(conversationItem.unreadMessages > 0 &&
conversationItem.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)) &&
if ((conversationItem.getUnreadMention() ||
(conversationItem.getUnreadMessages() > 0 &&
conversationItem.getType() == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)) &&
position > lastVisibleItem) {
nextUnreadConversationScrollPosition = position;
if (!newMentionPopupBubble.isShown()) {
@ -874,7 +876,7 @@ public class ConversationsListController extends BaseController implements Searc
if (selectedConversation != null && getActivity() != null) {
boolean hasChatPermission =
new AttendeePermissionsUtil(selectedConversation.permissions).hasChatPermission(currentUser);
new AttendeePermissionsUtil(selectedConversation.getPermissions()).hasChatPermission(currentUser);
if (showShareToScreen) {
if (hasChatPermission && !isReadOnlyConversation(selectedConversation)) {
@ -902,7 +904,7 @@ public class ConversationsListController extends BaseController implements Searc
}
private Boolean isReadOnlyConversation(Conversation conversation) {
return conversation.conversationReadOnlyState ==
return conversation.getConversationReadOnlyState() ==
Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY;
}

View file

@ -103,7 +103,7 @@ class EntryMenuController(args: Bundle) :
super.onViewBound(view)
if (conversation != null && operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
binding.textEdit.setText(conversation!!.getName())
binding.textEdit.setText(conversation!!.name)
}
binding.textEdit.setOnEditorActionListener { v, actionId, event ->
@ -127,7 +127,7 @@ class EntryMenuController(args: Bundle) :
override fun afterTextChanged(s: Editable) {
if (!TextUtils.isEmpty(s)) {
if (operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
if (conversation!!.getName() == null || !conversation!!.getName().equals(s.toString())) {
if (conversation!!.name == null || !conversation!!.name.equals(s.toString())) {
if (!binding.okButton.isEnabled) {
binding.okButton.isEnabled = true
binding.okButton.alpha = OPACITY_ENABLED
@ -260,9 +260,9 @@ class EntryMenuController(args: Bundle) :
if (operation === ConversationOperationEnum.OPS_CODE_CHANGE_PASSWORD ||
operation === ConversationOperationEnum.OPS_CODE_SET_PASSWORD
) {
conversation!!.setPassword(binding.textEdit.text.toString())
conversation!!.password = binding.textEdit.text.toString()
} else {
conversation!!.setName(binding.textEdit.text.toString())
conversation!!.name = binding.textEdit.text.toString()
}
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)

View file

@ -257,9 +257,9 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForSetChatReadMarker(
chatApiVersion(),
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
),
conversation!!.lastMessage.jsonMessageId
conversation!!.lastMessage!!.jsonMessageId
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -273,7 +273,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForRoomPublic(
apiVersion(),
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
)
)
.subscribeOn(Schedulers.io())
@ -284,15 +284,15 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
private fun operationChangePassword() {
var pass: String? = ""
if (conversation!!.getPassword() != null) {
pass = conversation!!.getPassword()
if (conversation!!.password != null) {
pass = conversation!!.password
}
ncApi.setPassword(
credentials,
ApiUtils.getUrlForRoomPassword(
apiVersion(),
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
),
pass
)
@ -308,7 +308,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForRoomPublic(
apiVersion(),
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
)
)
.subscribeOn(Schedulers.io())
@ -323,9 +323,9 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForRoom(
apiVersion(),
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
),
conversation!!.getName()
conversation!!.name
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -342,7 +342,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForRoomFavorite(
apiVersion,
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
)
)
.subscribeOn(Schedulers.io())
@ -355,7 +355,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
ApiUtils.getUrlForRoomFavorite(
apiVersion,
currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
)
)
.subscribeOn(Schedulers.io())
@ -406,7 +406,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
credentials,
ApiUtils.getUrlForRoom(
apiVersion, currentUser!!.baseUrl,
conversation!!.getToken()
conversation!!.token
)
)
.subscribeOn(Schedulers.io())
@ -461,7 +461,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
override fun onNext(roomOverall: RoomOverall) {
conversation = roomOverall.getOcs().getData()
if (conversation!!.isHasPassword && conversation!!.isGuest) {
if (conversation!!.hasPassword && conversation!!.isGuest) {
eventBus.post(ConversationsListFetchDataEvent())
val bundle = Bundle()
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))
@ -639,7 +639,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(
apiVersion,
currentUser!!.baseUrl,
conversation!!.getToken(),
conversation!!.token,
userId
)
ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
@ -683,7 +683,7 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipantWithSource(
apiVersion,
currentUser!!.baseUrl,
conversation!!.getToken(),
conversation!!.token,
"groups",
groupId
)
@ -718,9 +718,9 @@ class OperationsMenuController(args: Bundle) : NewBaseController(
private fun initiateConversation() {
eventBus.post(ConversationsListFetchDataEvent())
val bundle = Bundle()
bundle.putString(KEY_ROOM_TOKEN, conversation!!.getToken())
bundle.putString(KEY_ROOM_ID, conversation!!.getRoomId())
bundle.putString(KEY_CONVERSATION_NAME, conversation!!.getDisplayName())
bundle.putString(KEY_ROOM_TOKEN, conversation!!.token)
bundle.putString(KEY_ROOM_ID, conversation!!.roomId)
bundle.putString(KEY_CONVERSATION_NAME, conversation!!.displayName)
bundle.putParcelable(KEY_USER_ENTITY, currentUser)
bundle.putParcelable(KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation))
bundle.putString(KEY_CONVERSATION_PASSWORD, callPassword)

View file

@ -170,7 +170,7 @@ public class NotificationWorker extends Worker {
}
}
muteCall = !(conversation.notificationCalls == 1);
muteCall = !(conversation.getNotificationCalls() == 1);
}
@Override

View file

@ -1,694 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
* 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.models.json.chat;
import android.text.TextUtils;
import android.util.Log;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonIgnore;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.R;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.converters.EnumSystemMessageTypeConverter;
import com.nextcloud.talk.utils.ApiUtils;
import com.stfalcon.chatkit.commons.models.IUser;
import com.stfalcon.chatkit.commons.models.MessageContentType;
import org.parceler.Parcel;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import androidx.annotation.Nullable;
import kotlin.text.Charsets;
@Parcel
@JsonObject
public class ChatMessage implements MessageContentType, MessageContentType.Image {
private static String TAG = "ChatMessage";
@JsonIgnore
public boolean isGrouped;
@JsonIgnore
public boolean isOneToOneConversation;
@JsonIgnore
public UserEntity activeUser;
@JsonIgnore
public Map<String, String> selectedIndividualHashMap;
@JsonIgnore
public boolean isDeleted;
@JsonField(name = "id")
public int jsonMessageId;
@JsonIgnore
public int previousMessageId = -1;
@JsonField(name = "token")
public String token;
// guests or users
@JsonField(name = "actorType")
public String actorType;
@JsonField(name = "actorId")
public String actorId;
// send when crafting a message
@JsonField(name = "actorDisplayName")
public String actorDisplayName;
@JsonField(name = "timestamp")
public long timestamp;
// send when crafting a message, max 1000 lines
@JsonField(name = "message")
public String message;
@JsonField(name = "messageParameters")
public HashMap<String, HashMap<String, String>> messageParameters;
@JsonField(name = "systemMessage", typeConverter = EnumSystemMessageTypeConverter.class)
public SystemMessageType systemMessageType;
@JsonField(name = "isReplyable")
public boolean replyable;
@JsonField(name = "parent")
public ChatMessage parentMessage;
public Enum<ReadStatus> readStatus = ReadStatus.NONE;
@JsonField(name = "messageType")
public String messageType;
@JsonField(name = "reactions")
public LinkedHashMap<String, Integer> reactions;
@JsonField(name = "reactionsSelf")
public ArrayList<String> reactionsSelf;
public boolean isDownloadingVoiceMessage;
public boolean resetVoiceMessage;
public boolean isPlayingVoiceMessage;
public int voiceMessageDuration;
public int voiceMessagePlayedSeconds;
public int voiceMessageDownloadProgress;
@JsonIgnore
List<MessageType> messageTypesToIgnore = Arrays.asList(
MessageType.REGULAR_TEXT_MESSAGE,
MessageType.SYSTEM_MESSAGE,
MessageType.SINGLE_LINK_VIDEO_MESSAGE,
MessageType.SINGLE_LINK_AUDIO_MESSAGE,
MessageType.SINGLE_LINK_MESSAGE,
MessageType.SINGLE_NC_GEOLOCATION_MESSAGE,
MessageType.VOICE_MESSAGE);
public boolean hasFileAttachment() {
if (messageParameters != null && messageParameters.size() > 0) {
for (HashMap.Entry<String, HashMap<String, String>> entry : messageParameters.entrySet()) {
Map<String, String> individualHashMap = entry.getValue();
if (MessageDigest.isEqual(
Objects.requireNonNull(individualHashMap.get("type")).getBytes(Charsets.UTF_8),
("file").getBytes(Charsets.UTF_8))) {
return true;
}
}
}
return false;
}
public boolean hasGeoLocation() {
if (messageParameters != null && messageParameters.size() > 0) {
for (HashMap.Entry<String, HashMap<String, String>> entry : messageParameters.entrySet()) {
Map<String, String> individualHashMap = entry.getValue();
if (MessageDigest.isEqual(
Objects.requireNonNull(individualHashMap.get("type")).getBytes(Charsets.UTF_8),
("geo-location").getBytes(Charsets.UTF_8))) {
return true;
}
}
}
return false;
}
@Nullable
@Override
public String getImageUrl() {
if (messageParameters != null && messageParameters.size() > 0) {
for (HashMap.Entry<String, HashMap<String, String>> entry : messageParameters.entrySet()) {
Map<String, String> individualHashMap = entry.getValue();
if (MessageDigest.isEqual(
Objects.requireNonNull(individualHashMap.get("type")).getBytes(Charsets.UTF_8),
("file").getBytes(Charsets.UTF_8))) {
// TODO: this selectedIndividualHashMap stuff needs to be analyzed and most likely be refactored!
// it just feels wrong to fill this here inside getImageUrl()
selectedIndividualHashMap = individualHashMap;
if (!isVoiceMessage()) {
if (getActiveUser() != null && getActiveUser().getBaseUrl() != null) {
return (ApiUtils.getUrlForFilePreviewWithFileId(
getActiveUser().getBaseUrl(),
individualHashMap.get("id"),
NextcloudTalkApplication.Companion.getSharedApplication().getResources().getDimensionPixelSize(R.dimen.maximum_file_preview_size)));
} else {
Log.e(TAG, "getActiveUser() or getActiveUser().getBaseUrl() were null when trying to " +
"getImageUrl()");
}
}
}
}
}
if (!messageTypesToIgnore.contains(getMessageType())) {
return getMessage().trim();
}
return null;
}
public MessageType getMessageType() {
if (!TextUtils.isEmpty(getSystemMessage())) {
return MessageType.SYSTEM_MESSAGE;
}
if (isVoiceMessage()) {
return MessageType.VOICE_MESSAGE;
}
if (hasFileAttachment()) {
return MessageType.SINGLE_NC_ATTACHMENT_MESSAGE;
}
if (hasGeoLocation()) {
return MessageType.SINGLE_NC_GEOLOCATION_MESSAGE;
}
return MessageType.REGULAR_TEXT_MESSAGE;
}
public Map<String, String> getSelectedIndividualHashMap() {
return selectedIndividualHashMap;
}
public void setSelectedIndividualHashMap(Map<String, String> selectedIndividualHashMap) {
this.selectedIndividualHashMap = selectedIndividualHashMap;
}
@Override
public String getId() {
return Integer.toString(jsonMessageId);
}
@Override
public String getText() {
return ChatUtils.Companion.getParsedMessage(getMessage(), getMessageParameters());
}
public String getLastMessageDisplayText() {
if (getMessageType().equals(MessageType.REGULAR_TEXT_MESSAGE) || getMessageType().equals(MessageType.SYSTEM_MESSAGE) || getMessageType().equals(MessageType.SINGLE_LINK_MESSAGE)) {
return getText();
} else {
if (MessageType.SINGLE_LINK_GIPHY_MESSAGE == getMessageType()
|| MessageType.SINGLE_LINK_TENOR_MESSAGE == getMessageType()
|| MessageType.SINGLE_LINK_GIF_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_a_gif_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_a_gif),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
} else if (MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_an_attachment_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_an_attachment),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
} else if (MessageType.SINGLE_NC_GEOLOCATION_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_location_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_location),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
} else if (MessageType.VOICE_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_voice_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_voice),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
/*} else if (getMessageType().equals(MessageType.SINGLE_LINK_MESSAGE)) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_a_link_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_a_link),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}*/
} else if (MessageType.SINGLE_LINK_AUDIO_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_an_audio_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_an_audio),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
} else if (MessageType.SINGLE_LINK_VIDEO_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_a_video_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_a_video),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
} else if (MessageType.SINGLE_LINK_IMAGE_MESSAGE == getMessageType()) {
if (getActorId().equals(getActiveUser().getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_an_image_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_an_image),
!TextUtils.isEmpty(getActorDisplayName()) ? getActorDisplayName() : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}
}
}
return "";
}
@Override
public IUser getUser() {
return new IUser() {
@Override
public String getId() {
return actorType + "/" + actorId;
}
@Override
public String getName() {
if (!TextUtils.isEmpty(actorDisplayName)) {
return actorDisplayName;
}
return NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest);
}
@Override
public String getAvatar() {
if (getActiveUser() == null) {
return null;
} else if (getActorType().equals("users")) {
return ApiUtils.getUrlForAvatar(getActiveUser().getBaseUrl(), actorId, true);
} else if (getActorType().equals("bridged")) {
return ApiUtils.getUrlForAvatar(getActiveUser().getBaseUrl(), "bridge-bot",
true);
} else {
String apiId =
NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest);
if (!TextUtils.isEmpty(getActorDisplayName())) {
apiId = getActorDisplayName();
}
return ApiUtils.getUrlForGuestAvatar(getActiveUser().getBaseUrl(), apiId, true);
}
}
};
}
@Override
public Date getCreatedAt() {
return new Date(timestamp * 1000L);
}
@Override
public String getSystemMessage() {
return new EnumSystemMessageTypeConverter().convertToString(getSystemMessageType());
}
public boolean isGrouped() {
return this.isGrouped;
}
public boolean isOneToOneConversation() {
return this.isOneToOneConversation;
}
public UserEntity getActiveUser() {
return this.activeUser;
}
public boolean isDeleted() {
return this.isDeleted;
}
public int getJsonMessageId() {
return this.jsonMessageId;
}
public String getToken() {
return this.token;
}
public String getActorType() {
return this.actorType;
}
public String getActorId() {
return this.actorId;
}
public String getActorDisplayName() {
return this.actorDisplayName;
}
public long getTimestamp() {
return this.timestamp;
}
public String getMessage() {
return this.message;
}
public HashMap<String, HashMap<String, String>> getMessageParameters() {
return this.messageParameters;
}
public SystemMessageType getSystemMessageType() {
return this.systemMessageType;
}
public boolean isReplyable() {
return this.replyable;
}
public ChatMessage getParentMessage() {
return this.parentMessage;
}
public Enum<ReadStatus> getReadStatus() {
return this.readStatus;
}
public List<MessageType> getMessageTypesToIgnore() {
return this.messageTypesToIgnore;
}
public void setGrouped(boolean isGrouped) {
this.isGrouped = isGrouped;
}
public void setOneToOneConversation(boolean isOneToOneConversation) {
this.isOneToOneConversation = isOneToOneConversation;
}
public void setActiveUser(UserEntity activeUser) {
this.activeUser = activeUser;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
public void setJsonMessageId(int jsonMessageId) {
this.jsonMessageId = jsonMessageId;
}
public void setToken(String token) {
this.token = token;
}
public void setActorType(String actorType) {
this.actorType = actorType;
}
public void setActorId(String actorId) {
this.actorId = actorId;
}
public void setActorDisplayName(String actorDisplayName) {
this.actorDisplayName = actorDisplayName;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageParameters(HashMap<String, HashMap<String, String>> messageParameters) {
this.messageParameters = messageParameters;
}
public void setSystemMessageType(SystemMessageType systemMessageType) {
this.systemMessageType = systemMessageType;
}
public void setReplyable(boolean replyable) {
this.replyable = replyable;
}
public void setParentMessage(ChatMessage parentMessage) {
this.parentMessage = parentMessage;
}
public void setReadStatus(Enum<ReadStatus> readStatus) {
this.readStatus = readStatus;
}
public void setMessageTypesToIgnore(List<MessageType> messageTypesToIgnore) {
this.messageTypesToIgnore = messageTypesToIgnore;
}
public void setMessageType(String messageType) {
this.messageType = messageType;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ChatMessage)) {
return false;
}
final ChatMessage other = (ChatMessage) o;
if (!other.canEqual((Object) this)) {
return false;
}
if (this.isGrouped() != other.isGrouped()) {
return false;
}
if (this.isOneToOneConversation() != other.isOneToOneConversation()) {
return false;
}
final Object this$activeUser = this.getActiveUser();
final Object other$activeUser = other.getActiveUser();
if (this$activeUser == null ? other$activeUser != null : !this$activeUser.equals(other$activeUser)) {
return false;
}
final Object this$selectedIndividualHashMap = this.getSelectedIndividualHashMap();
final Object other$selectedIndividualHashMap = other.getSelectedIndividualHashMap();
if (this$selectedIndividualHashMap == null ? other$selectedIndividualHashMap != null : !this$selectedIndividualHashMap.equals(other$selectedIndividualHashMap)) {
return false;
}
if (this.isDeleted() != other.isDeleted()) {
return false;
}
if (this.getJsonMessageId() != other.getJsonMessageId()) {
return false;
}
final Object this$token = this.getToken();
final Object other$token = other.getToken();
if (this$token == null ? other$token != null : !this$token.equals(other$token)) {
return false;
}
final Object this$actorType = this.getActorType();
final Object other$actorType = other.getActorType();
if (this$actorType == null ? other$actorType != null : !this$actorType.equals(other$actorType)) {
return false;
}
final Object this$actorId = this.getActorId();
final Object other$actorId = other.getActorId();
if (this$actorId == null ? other$actorId != null : !this$actorId.equals(other$actorId)) {
return false;
}
final Object this$actorDisplayName = this.getActorDisplayName();
final Object other$actorDisplayName = other.getActorDisplayName();
if (this$actorDisplayName == null ? other$actorDisplayName != null : !this$actorDisplayName.equals(other$actorDisplayName)) {
return false;
}
if (this.getTimestamp() != other.getTimestamp()) {
return false;
}
final Object this$message = this.getMessage();
final Object other$message = other.getMessage();
if (this$message == null ? other$message != null : !this$message.equals(other$message)) {
return false;
}
final Object this$messageParameters = this.getMessageParameters();
final Object other$messageParameters = other.getMessageParameters();
if (this$messageParameters == null ? other$messageParameters != null : !this$messageParameters.equals(other$messageParameters)) {
return false;
}
final Object this$systemMessageType = this.getSystemMessageType();
final Object other$systemMessageType = other.getSystemMessageType();
if (this$systemMessageType == null ? other$systemMessageType != null : !this$systemMessageType.equals(other$systemMessageType)) {
return false;
}
if (this.isReplyable() != other.isReplyable()) {
return false;
}
final Object this$parentMessage = this.getParentMessage();
final Object other$parentMessage = other.getParentMessage();
if (this$parentMessage == null ? other$parentMessage != null : !this$parentMessage.equals(other$parentMessage)) {
return false;
}
final Object this$readStatus = this.getReadStatus();
final Object other$readStatus = other.getReadStatus();
if (this$readStatus == null ? other$readStatus != null : !this$readStatus.equals(other$readStatus)) {
return false;
}
final Object this$messageTypesToIgnore = this.getMessageTypesToIgnore();
final Object other$messageTypesToIgnore = other.getMessageTypesToIgnore();
return this$messageTypesToIgnore == null ? other$messageTypesToIgnore == null : this$messageTypesToIgnore.equals(other$messageTypesToIgnore);
}
protected boolean canEqual(final Object other) {
return other instanceof ChatMessage;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (this.isGrouped() ? 79 : 97);
result = result * PRIME + (this.isOneToOneConversation() ? 79 : 97);
final Object $activeUser = this.getActiveUser();
result = result * PRIME + ($activeUser == null ? 43 : $activeUser.hashCode());
final Object $selectedIndividualHashMap = this.getSelectedIndividualHashMap();
result = result * PRIME + ($selectedIndividualHashMap == null ? 43 : $selectedIndividualHashMap.hashCode());
result = result * PRIME + (this.isDeleted() ? 79 : 97);
result = result * PRIME + this.getJsonMessageId();
final Object $token = this.getToken();
result = result * PRIME + ($token == null ? 43 : $token.hashCode());
final Object $actorType = this.getActorType();
result = result * PRIME + ($actorType == null ? 43 : $actorType.hashCode());
final Object $actorId = this.getActorId();
result = result * PRIME + ($actorId == null ? 43 : $actorId.hashCode());
final Object $actorDisplayName = this.getActorDisplayName();
result = result * PRIME + ($actorDisplayName == null ? 43 : $actorDisplayName.hashCode());
final long $timestamp = this.getTimestamp();
result = result * PRIME + (int) ($timestamp >>> 32 ^ $timestamp);
final Object $message = this.getMessage();
result = result * PRIME + ($message == null ? 43 : $message.hashCode());
final Object $messageParameters = this.getMessageParameters();
result = result * PRIME + ($messageParameters == null ? 43 : $messageParameters.hashCode());
final Object $systemMessageType = this.getSystemMessageType();
result = result * PRIME + ($systemMessageType == null ? 43 : $systemMessageType.hashCode());
result = result * PRIME + (this.isReplyable() ? 79 : 97);
final Object $parentMessage = this.getParentMessage();
result = result * PRIME + ($parentMessage == null ? 43 : $parentMessage.hashCode());
final Object $readStatus = this.getReadStatus();
result = result * PRIME + ($readStatus == null ? 43 : $readStatus.hashCode());
final Object $messageTypesToIgnore = this.getMessageTypesToIgnore();
result = result * PRIME + ($messageTypesToIgnore == null ? 43 : $messageTypesToIgnore.hashCode());
return result;
}
public String toString() {
return "ChatMessage(isGrouped=" + this.isGrouped() + ", isOneToOneConversation=" + this.isOneToOneConversation() + ", activeUser=" + this.getActiveUser() + ", selectedIndividualHashMap=" + this.getSelectedIndividualHashMap() + ", isDeleted=" + this.isDeleted() + ", jsonMessageId=" + this.getJsonMessageId() + ", token=" + this.getToken() + ", actorType=" + this.getActorType() + ", actorId=" + this.getActorId() + ", actorDisplayName=" + this.getActorDisplayName() + ", timestamp=" + this.getTimestamp() + ", message=" + this.getMessage() + ", messageParameters=" + this.getMessageParameters() + ", systemMessageType=" + this.getSystemMessageType() + ", replyable=" + this.isReplyable() + ", parentMessage=" + this.getParentMessage() + ", readStatus=" + this.getReadStatus() + ", messageTypesToIgnore=" + this.getMessageTypesToIgnore() + ")";
}
public boolean isVoiceMessage() {
return "voice-message".equals(messageType);
}
public boolean isCommandMessage() {
return "command".equals(messageType);
}
public boolean isDeletedCommentMessage() {
return "comment_deleted".equals(messageType);
}
public enum MessageType {
REGULAR_TEXT_MESSAGE,
SYSTEM_MESSAGE,
SINGLE_LINK_GIPHY_MESSAGE,
SINGLE_LINK_TENOR_MESSAGE,
SINGLE_LINK_GIF_MESSAGE,
SINGLE_LINK_MESSAGE,
SINGLE_LINK_VIDEO_MESSAGE,
SINGLE_LINK_IMAGE_MESSAGE,
SINGLE_LINK_AUDIO_MESSAGE,
SINGLE_NC_ATTACHMENT_MESSAGE,
SINGLE_NC_GEOLOCATION_MESSAGE,
VOICE_MESSAGE
}
/**
* see https://nextcloud-talk.readthedocs.io/en/latest/chat/#system-messages
*/
public enum SystemMessageType {
DUMMY,
CONVERSATION_CREATED,
CONVERSATION_RENAMED,
DESCRIPTION_REMOVED,
DESCRIPTION_SET,
CALL_STARTED,
CALL_JOINED,
CALL_LEFT,
CALL_ENDED,
CALL_ENDED_EVERYONE,
CALL_MISSED,
CALL_TRIED,
READ_ONLY_OFF,
READ_ONLY,
LISTABLE_NONE,
LISTABLE_USERS,
LISTABLE_ALL,
LOBBY_NONE,
LOBBY_NON_MODERATORS,
LOBBY_OPEN_TO_EVERYONE,
GUESTS_ALLOWED,
GUESTS_DISALLOWED,
PASSWORD_SET,
PASSWORD_REMOVED,
USER_ADDED,
USER_REMOVED,
GROUP_ADDED,
GROUP_REMOVED,
CIRCLE_ADDED,
CIRCLE_REMOVED,
MODERATOR_PROMOTED,
MODERATOR_DEMOTED,
GUEST_MODERATOR_PROMOTED,
GUEST_MODERATOR_DEMOTED,
MESSAGE_DELETED,
FILE_SHARED,
OBJECT_SHARED,
MATTERBRIDGE_CONFIG_ADDED,
MATTERBRIDGE_CONFIG_EDITED,
MATTERBRIDGE_CONFIG_REMOVED,
MATTERBRIDGE_CONFIG_ENABLED,
MATTERBRIDGE_CONFIG_DISABLED,
CLEARED_CHAT,
REACTION,
REACTION_DELETED,
REACTION_REVOKED
}
}

View file

@ -0,0 +1,450 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
* 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.models.json.chat
import android.os.Parcelable
import android.text.TextUtils
import android.util.Log
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonIgnore
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatUtils.Companion.getParsedMessage
import com.nextcloud.talk.models.json.converters.EnumSystemMessageTypeConverter
import com.nextcloud.talk.utils.ApiUtils
import com.stfalcon.chatkit.commons.models.IUser
import com.stfalcon.chatkit.commons.models.MessageContentType
import kotlinx.android.parcel.Parcelize
import java.security.MessageDigest
import java.util.ArrayList
import java.util.Arrays
import java.util.Date
import java.util.HashMap
import java.util.LinkedHashMap
@Parcelize
@JsonObject
data class ChatMessage(
@JsonIgnore
var isGrouped: Boolean = false,
@JsonIgnore
var isOneToOneConversation: Boolean = false,
@JsonIgnore
var activeUser: UserEntity? = null,
@JsonIgnore
var selectedIndividualHashMap: Map<String?, String?>? = null,
@JsonIgnore
var isDeleted: Boolean = false,
@JsonField(name = ["id"])
var jsonMessageId: Int = 0,
@JsonIgnore
var previousMessageId: Int = -1,
@JsonField(name = ["token"])
var token: String? = null,
// guests or users
@JsonField(name = ["actorType"])
var actorType: String? = null,
@JsonField(name = ["actorId"])
var actorId: String? = null,
// send when crafting a message
@JsonField(name = ["actorDisplayName"])
var actorDisplayName: String? = null,
@JsonField(name = ["timestamp"])
var timestamp: Long = 0,
// send when crafting a message, max 1000 lines
@JsonField(name = ["message"])
var message: String? = null,
@JsonField(name = ["messageParameters"])
var messageParameters: HashMap<String?, HashMap<String?, String?>>? = null,
@JsonField(name = ["systemMessage"], typeConverter = EnumSystemMessageTypeConverter::class)
var systemMessageType: SystemMessageType? = null,
@JsonField(name = ["isReplyable"])
var replyable: Boolean = false,
@JsonField(name = ["parent"])
var parentMessage: ChatMessage? = null,
var readStatus: Enum<ReadStatus> = ReadStatus.NONE,
@JsonField(name = ["messageType"])
var messageType: String? = null,
@JsonField(name = ["reactions"])
var reactions: LinkedHashMap<String, Int>? = null,
@JsonField(name = ["reactionsSelf"])
var reactionsSelf: ArrayList<String>? = null,
var isDownloadingVoiceMessage: Boolean = false,
var resetVoiceMessage: Boolean = false,
var isPlayingVoiceMessage: Boolean = false,
var voiceMessageDuration: Int = 0,
var voiceMessagePlayedSeconds: Int = 0,
var voiceMessageDownloadProgress: Int = 0,
) : Parcelable, MessageContentType, MessageContentType.Image {
@JsonIgnore
var messageTypesToIgnore = Arrays.asList(
MessageType.REGULAR_TEXT_MESSAGE,
MessageType.SYSTEM_MESSAGE,
MessageType.SINGLE_LINK_VIDEO_MESSAGE,
MessageType.SINGLE_LINK_AUDIO_MESSAGE,
MessageType.SINGLE_LINK_MESSAGE,
MessageType.SINGLE_NC_GEOLOCATION_MESSAGE,
MessageType.VOICE_MESSAGE
)
fun hasFileAttachment(): Boolean {
if (messageParameters != null && messageParameters!!.size > 0) {
for ((_, individualHashMap) in messageParameters!!) {
if (MessageDigest.isEqual(
individualHashMap["type"]!!.toByteArray(),
"file".toByteArray()
)
) {
return true
}
}
}
return false
}
fun hasGeoLocation(): Boolean {
if (messageParameters != null && messageParameters!!.size > 0) {
for ((_, individualHashMap) in messageParameters!!) {
if (MessageDigest.isEqual(
individualHashMap["type"]!!.toByteArray(),
"geo-location".toByteArray()
)
) {
return true
}
}
}
return false
}
override fun getImageUrl(): String? {
if (messageParameters != null && messageParameters!!.size > 0) {
for ((_, individualHashMap) in messageParameters!!) {
if (MessageDigest.isEqual(
individualHashMap["type"]!!.toByteArray(),
"file".toByteArray()
)
) {
// TODO: this selectedIndividualHashMap stuff needs to be analyzed and most likely be refactored!
// it just feels wrong to fill this here inside getImageUrl()
selectedIndividualHashMap = individualHashMap
if (!isVoiceMessage) {
if (activeUser != null && activeUser!!.baseUrl != null) {
return ApiUtils.getUrlForFilePreviewWithFileId(
activeUser!!.baseUrl,
individualHashMap["id"],
sharedApplication!!.resources.getDimensionPixelSize(R.dimen.maximum_file_preview_size)
)
} else {
Log.e(
TAG, "activeUser or activeUser.getBaseUrl() were null when trying to " +
"getImageUrl()"
)
}
}
}
}
}
return if (!messageTypesToIgnore.contains(getCalculateMessageType())) {
message!!.trim { it <= ' ' }
} else null
}
fun getCalculateMessageType(): MessageType {
if (!TextUtils.isEmpty(systemMessage)) {
return MessageType.SYSTEM_MESSAGE
}
if (isVoiceMessage) {
return MessageType.VOICE_MESSAGE
}
if (hasFileAttachment()) {
return MessageType.SINGLE_NC_ATTACHMENT_MESSAGE
}
return if (hasGeoLocation()) {
MessageType.SINGLE_NC_GEOLOCATION_MESSAGE
} else MessageType.REGULAR_TEXT_MESSAGE
}
override fun getId(): String {
return Integer.toString(jsonMessageId)
}
override fun getText(): String {
return getParsedMessage(message, messageParameters)!!
}
/*} else if (getCalculateMessageType().equals(MessageType.SINGLE_LINK_MESSAGE)) {
if (actorId.equals(activeUser.getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_a_link_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_a_link),
!TextUtils.isEmpty(actorDisplayName) ? actorDisplayName : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}*/
val lastMessageDisplayText: String
get() {
if (getCalculateMessageType() == MessageType.REGULAR_TEXT_MESSAGE ||
getCalculateMessageType() == MessageType.SYSTEM_MESSAGE ||
getCalculateMessageType() == MessageType.SINGLE_LINK_MESSAGE) {
return text
} else {
if (MessageType.SINGLE_LINK_GIPHY_MESSAGE == getCalculateMessageType() ||
MessageType.SINGLE_LINK_TENOR_MESSAGE == getCalculateMessageType() ||
MessageType.SINGLE_LINK_GIF_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_a_gif_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_a_gif),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
} else if (MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_an_attachment_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_an_attachment),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
} else if (MessageType.SINGLE_NC_GEOLOCATION_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_location_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_location),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
} else if (MessageType.VOICE_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_voice_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_voice),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
/*} else if (getCalculateMessageType().equals(MessageType.SINGLE_LINK_MESSAGE)) {
if (actorId.equals(activeUser.getUserId())) {
return (NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_sent_a_link_you));
} else {
return (String.format(NextcloudTalkApplication.Companion.getSharedApplication().getResources().getString(R.string.nc_sent_a_link),
!TextUtils.isEmpty(actorDisplayName) ? actorDisplayName : NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_guest)));
}*/
} else if (MessageType.SINGLE_LINK_AUDIO_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_an_audio_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_an_audio),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
} else if (MessageType.SINGLE_LINK_VIDEO_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_a_video_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_a_video),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
} else if (MessageType.SINGLE_LINK_IMAGE_MESSAGE == getCalculateMessageType()) {
return if (actorId == activeUser!!.userId) {
sharedApplication!!.getString(R.string.nc_sent_an_image_you)
} else {
String.format(
sharedApplication!!.resources.getString(R.string.nc_sent_an_image),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(
R.string.nc_guest
)
)
}
}
}
return ""
}
override fun getUser(): IUser {
return object : IUser {
override fun getId(): String {
return "$actorType/$actorId"
}
override fun getName(): String {
return if (!TextUtils.isEmpty(actorDisplayName)) {
actorDisplayName!!
} else sharedApplication!!.getString(R.string.nc_guest)
}
override fun getAvatar(): String? {
return when {
activeUser == null -> {
null
}
actorType == "users" -> {
ApiUtils.getUrlForAvatar(activeUser!!.baseUrl, actorId, true)
}
actorType == "bridged" -> {
ApiUtils.getUrlForAvatar(
activeUser!!.baseUrl, "bridge-bot",
true
)
}
else -> {
var apiId: String? = sharedApplication!!.getString(R.string.nc_guest)
if (!TextUtils.isEmpty(actorDisplayName)) {
apiId = actorDisplayName
}
ApiUtils.getUrlForGuestAvatar(activeUser!!.baseUrl, apiId, true)
}
}
}
}
}
override fun getCreatedAt(): Date {
return Date(timestamp * 1000L)
}
override fun getSystemMessage(): String {
return EnumSystemMessageTypeConverter().convertToString(systemMessageType)
}
val isVoiceMessage: Boolean
get() = "voice-message" == messageType
val isCommandMessage: Boolean
get() = "command" == messageType
val isDeletedCommentMessage: Boolean
get() = "comment_deleted" == messageType
enum class MessageType {
REGULAR_TEXT_MESSAGE,
SYSTEM_MESSAGE,
SINGLE_LINK_GIPHY_MESSAGE,
SINGLE_LINK_TENOR_MESSAGE,
SINGLE_LINK_GIF_MESSAGE,
SINGLE_LINK_MESSAGE,
SINGLE_LINK_VIDEO_MESSAGE,
SINGLE_LINK_IMAGE_MESSAGE,
SINGLE_LINK_AUDIO_MESSAGE,
SINGLE_NC_ATTACHMENT_MESSAGE,
SINGLE_NC_GEOLOCATION_MESSAGE,
VOICE_MESSAGE
}
/**
* see https://nextcloud-talk.readthedocs.io/en/latest/chat/#system-messages
*/
enum class SystemMessageType {
DUMMY, CONVERSATION_CREATED,
CONVERSATION_RENAMED,
DESCRIPTION_REMOVED,
DESCRIPTION_SET,
CALL_STARTED,
CALL_JOINED,
CALL_LEFT,
CALL_ENDED,
CALL_ENDED_EVERYONE,
CALL_MISSED,
CALL_TRIED,
READ_ONLY_OFF,
READ_ONLY,
LISTABLE_NONE,
LISTABLE_USERS,
LISTABLE_ALL,
LOBBY_NONE,
LOBBY_NON_MODERATORS,
LOBBY_OPEN_TO_EVERYONE,
GUESTS_ALLOWED,
GUESTS_DISALLOWED,
PASSWORD_SET,
PASSWORD_REMOVED,
USER_ADDED,
USER_REMOVED,
GROUP_ADDED,
GROUP_REMOVED,
CIRCLE_ADDED,
CIRCLE_REMOVED,
MODERATOR_PROMOTED,
MODERATOR_DEMOTED,
GUEST_MODERATOR_PROMOTED,
GUEST_MODERATOR_DEMOTED,
MESSAGE_DELETED,
FILE_SHARED, OBJECT_SHARED,
MATTERBRIDGE_CONFIG_ADDED,
MATTERBRIDGE_CONFIG_EDITED,
MATTERBRIDGE_CONFIG_REMOVED,
MATTERBRIDGE_CONFIG_ENABLED,
MATTERBRIDGE_CONFIG_DISABLED,
CLEARED_CHAT,
REACTION,
REACTION_DELETED,
REACTION_REVOKED
}
companion object {
private const val TAG = "ChatMessage"
}
}

View file

@ -1,76 +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.models.json.chat;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.models.json.generic.GenericOCS;
import org.parceler.Parcel;
import java.util.List;
@Parcel
@JsonObject
public class ChatOCS extends GenericOCS {
@JsonField(name = "data")
public List<ChatMessage> data;
public List<ChatMessage> getData() {
return this.data;
}
public void setData(List<ChatMessage> data) {
this.data = data;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ChatOCS)) {
return false;
}
final ChatOCS other = (ChatOCS) o;
if (!other.canEqual((Object) this)) {
return false;
}
final Object this$data = this.getData();
final Object other$data = other.getData();
return this$data == null ? other$data == null : this$data.equals(other$data);
}
protected boolean canEqual(final Object other) {
return other instanceof ChatOCS;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $data = this.getData();
result = result * PRIME + ($data == null ? 43 : $data.hashCode());
return result;
}
public String toString() {
return "ChatOCS(data=" + this.getData() + ")";
}
}

View file

@ -0,0 +1,38 @@
/*
* 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.models.json.chat
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.models.json.generic.GenericMeta
import kotlinx.android.parcel.Parcelize
@Parcelize
@JsonObject
data class ChatOCS(
@JsonField(name = ["meta"])
var meta: GenericMeta?,
@JsonField(name = ["data"])
var data: List<ChatMessage>? = null
) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null)
}

View file

@ -1,74 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Marcel Hibbe
* Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
*
* 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.models.json.chat;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.models.json.generic.GenericOCS;
import org.parceler.Parcel;
@Parcel
@JsonObject
public class ChatOCSSingleMessage extends GenericOCS {
@JsonField(name = "data")
public ChatMessage data;
public ChatMessage getData() {
return this.data;
}
public void setData(ChatMessage data) {
this.data = data;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ChatOCSSingleMessage)) {
return false;
}
final ChatOCSSingleMessage other = (ChatOCSSingleMessage) o;
if (!other.canEqual((Object) this)) {
return false;
}
final Object this$data = this.getData();
final Object other$data = other.getData();
return this$data == null ? other$data == null : this$data.equals(other$data);
}
protected boolean canEqual(final Object other) {
return other instanceof ChatOCSSingleMessage;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $data = this.getData();
result = result * PRIME + ($data == null ? 43 : $data.hashCode());
return result;
}
public String toString() {
return "ChatOCSSingleMessage(data=" + this.getData() + ")";
}
}

View file

@ -0,0 +1,38 @@
/*
* Nextcloud Talk application
*
* @author Marcel Hibbe
* Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
*
* 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.models.json.chat
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.models.json.generic.GenericMeta
import kotlinx.android.parcel.Parcelize
@Parcelize
@JsonObject
data class ChatOCSSingleMessage(
@JsonField(name = ["meta"])
var meta: GenericMeta?,
@JsonField(name = ["data"])
var data: ChatMessage? = null
) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null)
}

View file

@ -1,624 +0,0 @@
/*
*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2017 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.models.json.conversations;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.chat.ChatMessage;
import com.nextcloud.talk.models.json.converters.EnumLobbyStateConverter;
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter;
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
import com.nextcloud.talk.models.json.converters.EnumReadOnlyConversationConverter;
import com.nextcloud.talk.models.json.converters.EnumRoomTypeConverter;
import com.nextcloud.talk.models.json.participants.Participant;
import org.parceler.Parcel;
import java.util.HashMap;
import java.util.Objects;
@Parcel
@JsonObject
public class Conversation {
@JsonField(name = "id")
public String roomId;
@JsonField(name = "token")
public String token;
@JsonField(name = "name")
public String name;
@JsonField(name = "displayName")
public String displayName;
@JsonField(name = "description")
public String description;
@JsonField(name = "type", typeConverter = EnumRoomTypeConverter.class)
public ConversationType type;
@JsonField(name = "lastPing")
public long lastPing;
@Deprecated
@JsonField(name = "participants")
public HashMap<String, HashMap<String, Object>> participants;
@JsonField(name = "participantType", typeConverter = EnumParticipantTypeConverter.class)
public Participant.ParticipantType participantType;
@JsonField(name = "hasPassword")
public boolean hasPassword;
@JsonField(name = "sessionId")
public String sessionId;
@JsonField(name = "actorId")
public String actorId;
@JsonField(name = "actorType")
public String actorType;
public String password;
@JsonField(name = "isFavorite")
public boolean isFavorite;
@JsonField(name = "lastActivity")
public long lastActivity;
@JsonField(name = "unreadMessages")
public int unreadMessages;
@JsonField(name = "unreadMention")
public boolean unreadMention;
@JsonField(name = "lastMessage")
public ChatMessage lastMessage;
@JsonField(name = "objectType")
public String objectType;
@JsonField(name = "notificationLevel", typeConverter = EnumNotificationLevelConverter.class)
public NotificationLevel notificationLevel;
@JsonField(name = "readOnly", typeConverter = EnumReadOnlyConversationConverter.class)
public ConversationReadOnlyState conversationReadOnlyState;
@JsonField(name = "lobbyState", typeConverter = EnumLobbyStateConverter.class)
public LobbyState lobbyState;
@JsonField(name = "lobbyTimer")
public Long lobbyTimer;
@JsonField(name = "lastReadMessage")
public int lastReadMessage;
@JsonField(name = "hasCall")
public boolean hasCall;
@JsonField(name = "callFlag")
public int callFlag;
@JsonField(name = "canStartCall")
public boolean canStartCall;
@JsonField(name = "canLeaveConversation")
public Boolean canLeaveConversation;
@JsonField(name = "canDeleteConversation")
public Boolean canDeleteConversation;
@JsonField(name = "unreadMentionDirect")
public Boolean unreadMentionDirect;
@JsonField(name = "notificationCalls")
public Integer notificationCalls;
@JsonField(name = "permissions")
public int permissions;
public boolean isPublic() {
return (ConversationType.ROOM_PUBLIC_CALL.equals(type));
}
public boolean isGuest() {
return (Participant.ParticipantType.GUEST.equals(participantType) ||
Participant.ParticipantType.GUEST_MODERATOR.equals(participantType) ||
Participant.ParticipantType.USER_FOLLOWING_LINK.equals(participantType));
}
private boolean isLockedOneToOne(UserEntity conversationUser) {
return (getType() == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms"));
}
public boolean canModerate(UserEntity conversationUser) {
return (isParticipantOwnerOrModerator() && !isLockedOneToOne(conversationUser));
}
public boolean isParticipantOwnerOrModerator() {
return (Participant.ParticipantType.OWNER.equals(participantType) ||
Participant.ParticipantType.GUEST_MODERATOR.equals(participantType) ||
Participant.ParticipantType.MODERATOR.equals(participantType));
}
public boolean shouldShowLobby(UserEntity conversationUser) {
return LobbyState.LOBBY_STATE_MODERATORS_ONLY.equals(getLobbyState()) && !canModerate(conversationUser);
}
public boolean isLobbyViewApplicable(UserEntity conversationUser) {
return !canModerate(conversationUser) && (getType() == ConversationType.ROOM_GROUP_CALL || getType() == ConversationType.ROOM_PUBLIC_CALL);
}
public boolean isNameEditable(UserEntity conversationUser) {
return (canModerate(conversationUser) && !ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL.equals(type));
}
public boolean canLeave(UserEntity conversationUser) {
if (canLeaveConversation != null) {
// Available since APIv2
return canLeaveConversation;
}
// Fallback for APIv1
return !canModerate(conversationUser) ||
(getType() != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && this.participants.size() > 1);
}
public boolean canDelete(UserEntity conversationUser) {
if (canDeleteConversation != null) {
// Available since APIv2
return canDeleteConversation;
}
// Fallback for APIv1
return canModerate(conversationUser);
}
public String getRoomId() {
return this.roomId;
}
public String getToken() {
return this.token;
}
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
}
public String getDisplayName() {
return this.displayName;
}
public ConversationType getType() {
return this.type;
}
public long getLastPing() {
return this.lastPing;
}
public Participant.ParticipantType getParticipantType() {
return this.participantType;
}
public String getActorId() {
return actorId;
}
public String getActorType() {
return actorType;
}
public boolean isHasPassword() {
return this.hasPassword;
}
public String getSessionId() {
return this.sessionId;
}
public String getPassword() {
return this.password;
}
public boolean isFavorite() {
return this.isFavorite;
}
public long getLastActivity() {
return this.lastActivity;
}
public int getUnreadMessages() {
return this.unreadMessages;
}
public boolean isUnreadMention() {
return this.unreadMention;
}
public ChatMessage getLastMessage() {
return this.lastMessage;
}
public String getObjectType() {
return this.objectType;
}
public NotificationLevel getNotificationLevel() {
return this.notificationLevel;
}
public ConversationReadOnlyState getConversationReadOnlyState() {
return this.conversationReadOnlyState;
}
public LobbyState getLobbyState() {
return this.lobbyState;
}
public Long getLobbyTimer() {
return this.lobbyTimer;
}
public int getLastReadMessage() {
return this.lastReadMessage;
}
public boolean getHasCall() {
return hasCall;
}
public int getCallFlag() {
return this.callFlag;
}
public boolean getCanStartCall() {
return canStartCall;
}
public Boolean getUnreadMentionDirect() {
return unreadMentionDirect;
}
public Integer getNotificationCalls() { return notificationCalls; }
public int getPermissions() {
return permissions;
}
public void setRoomId(String roomId) {
this.roomId = roomId;
}
public void setToken(String token) {
this.token = token;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public void setType(ConversationType type) {
this.type = type;
}
public void setLastPing(long lastPing) {
this.lastPing = lastPing;
}
@Deprecated
public void setParticipants(HashMap<String, HashMap<String, Object>> participants) {
this.participants = participants;
}
public void setParticipantType(Participant.ParticipantType participantType) {
this.participantType = participantType;
}
public void setActorId(String actorId) {
this.actorId = actorId;
}
public void setActorType(String actorType) {
this.actorType = actorType;
}
public void setHasPassword(boolean hasPassword) {
this.hasPassword = hasPassword;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public void setPassword(String password) {
this.password = password;
}
public void setFavorite(boolean isFavorite) {
this.isFavorite = isFavorite;
}
public void setLastActivity(long lastActivity) {
this.lastActivity = lastActivity;
}
public void setUnreadMessages(int unreadMessages) {
this.unreadMessages = unreadMessages;
}
public void setUnreadMention(boolean unreadMention) {
this.unreadMention = unreadMention;
}
public void setLastMessage(ChatMessage lastMessage) {
this.lastMessage = lastMessage;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
public void setNotificationLevel(NotificationLevel notificationLevel) {
this.notificationLevel = notificationLevel;
}
public void setConversationReadOnlyState(ConversationReadOnlyState conversationReadOnlyState) {
this.conversationReadOnlyState = conversationReadOnlyState;
}
public void setLobbyState(LobbyState lobbyState) {
this.lobbyState = lobbyState;
}
public void setLobbyTimer(Long lobbyTimer) {
this.lobbyTimer = lobbyTimer;
}
public void setLastReadMessage(int lastReadMessage) {
this.lastReadMessage = lastReadMessage;
}
public void setHasCall(boolean hasCall) {
this.hasCall = hasCall;
}
public void setCallFlag(int callFlag) {
this.callFlag = callFlag;
}
public void setCanStartCall(boolean canStartCall) {
this.canStartCall = canStartCall;
}
public void setUnreadMentionDirect(Boolean unreadMentionDirect) {
this.unreadMentionDirect = unreadMentionDirect;
}
public void setPermissions(int permissions) {
this.permissions = permissions;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Conversation that = (Conversation) o;
if (lastPing != that.lastPing) {
return false;
}
if (hasPassword != that.hasPassword) {
return false;
}
if (isFavorite != that.isFavorite) {
return false;
}
if (lastActivity != that.lastActivity) {
return false;
}
if (unreadMessages != that.unreadMessages) {
return false;
}
if (unreadMention != that.unreadMention) {
return false;
}
if (lastReadMessage != that.lastReadMessage) {
return false;
}
if (hasCall != that.hasCall) {
return false;
}
if (callFlag != that.callFlag) {
return false;
}
if (canStartCall != that.canStartCall) {
return false;
}
if (!Objects.equals(roomId, that.roomId)) {
return false;
}
if (!token.equals(that.token)) {
return false;
}
if (!Objects.equals(name, that.name)) {
return false;
}
if (!Objects.equals(displayName, that.displayName)) {
return false;
}
if (!Objects.equals(description, that.description)) {
return false;
}
if (type != that.type) {
return false;
}
if (!Objects.equals(participants, that.participants)) {
return false;
}
if (participantType != that.participantType) {
return false;
}
if (!Objects.equals(sessionId, that.sessionId)) {
return false;
}
if (!Objects.equals(actorId, that.actorId)) {
return false;
}
if (!Objects.equals(actorType, that.actorType)) {
return false;
}
if (!Objects.equals(password, that.password)) {
return false;
}
if (!Objects.equals(lastMessage, that.lastMessage)) {
return false;
}
if (!Objects.equals(objectType, that.objectType)) {
return false;
}
if (notificationLevel != that.notificationLevel) {
return false;
}
if (conversationReadOnlyState != that.conversationReadOnlyState) {
return false;
}
if (lobbyState != that.lobbyState) {
return false;
}
if (!Objects.equals(lobbyTimer, that.lobbyTimer)) {
return false;
}
if (!Objects.equals(canLeaveConversation, that.canLeaveConversation)) {
return false;
}
if (!Objects.equals(notificationCalls, that.notificationCalls)) {
return false;
}
if (permissions != that.permissions) {
return false;
}
return Objects.equals(canDeleteConversation, that.canDeleteConversation);
}
protected boolean canEqual(final Object other) {
return other instanceof Conversation;
}
@Override
public int hashCode() {
int result = roomId != null ? roomId.hashCode() : 0;
result = 31 * result + token.hashCode();
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + type.hashCode();
result = 31 * result + (int) (lastPing ^ (lastPing >>> 32));
result = 31 * result + (participants != null ? participants.hashCode() : 0);
result = 31 * result + (participantType != null ? participantType.hashCode() : 0);
result = 31 * result + (actorId != null ? actorId.hashCode() : 0);
result = 31 * result + (actorType != null ? actorType.hashCode() : 0);
result = 31 * result + (hasPassword ? 1 : 0);
result = 31 * result + (sessionId != null ? sessionId.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + (isFavorite ? 1 : 0);
result = 31 * result + (int) (lastActivity ^ (lastActivity >>> 32));
result = 31 * result + unreadMessages;
result = 31 * result + (unreadMention ? 1 : 0);
result = 31 * result + (lastMessage != null ? lastMessage.hashCode() : 0);
result = 31 * result + (objectType != null ? objectType.hashCode() : 0);
result = 31 * result + (notificationLevel != null ? notificationLevel.hashCode() : 0);
result = 31 * result + (conversationReadOnlyState != null ? conversationReadOnlyState.hashCode() : 0);
result = 31 * result + (lobbyState != null ? lobbyState.hashCode() : 0);
result = 31 * result + (lobbyTimer != null ? lobbyTimer.hashCode() : 0);
result = 31 * result + lastReadMessage;
result = 31 * result + (hasCall ? 1 : 0);
result = 31 * result + callFlag;
result = 31 * result + (canStartCall ? 1 : 0);
result = 31 * result + (canLeaveConversation != null ? canLeaveConversation.hashCode() : 0);
result = 31 * result + (canDeleteConversation != null ? canDeleteConversation.hashCode() : 0);
result = 31 * result + (notificationCalls != null ? notificationCalls.hashCode() : 0);
result = 31 * result + permissions;
return result;
}
@Override
public String toString() {
return "Conversation{" +
"roomId='" + roomId + '\'' +
", token='" + token + '\'' +
", name='" + name + '\'' +
", displayName='" + displayName + '\'' +
", description='" + description + '\'' +
", type=" + type +
", lastPing=" + lastPing +
", participants=" + participants +
", participantType=" + participantType +
", actorId=" + actorId +
", actorType=" + actorType +
", hasPassword=" + hasPassword +
", sessionId='" + sessionId + '\'' +
", password='" + password + '\'' +
", isFavorite=" + isFavorite +
", lastActivity=" + lastActivity +
", unreadMessages=" + unreadMessages +
", unreadMention=" + unreadMention +
", lastMessage=" + lastMessage +
", objectType='" + objectType + '\'' +
", notificationLevel=" + notificationLevel +
", conversationReadOnlyState=" + conversationReadOnlyState +
", lobbyState=" + lobbyState +
", lobbyTimer=" + lobbyTimer +
", lastReadMessage=" + lastReadMessage +
", hasCall=" + hasCall +
", callFlag=" + callFlag +
", canStartCall=" + canStartCall +
", canLeaveConversation=" + canLeaveConversation +
", canDeleteConversation=" + canDeleteConversation +
", notificationCalls=" + notificationCalls +
", permissions=" + permissions +
'}';
}
public enum NotificationLevel {
DEFAULT,
ALWAYS,
MENTION,
NEVER
}
public enum LobbyState {
LOBBY_STATE_ALL_PARTICIPANTS,
LOBBY_STATE_MODERATORS_ONLY
}
public enum ConversationReadOnlyState {
CONVERSATION_READ_WRITE,
CONVERSATION_READ_ONLY
}
@Parcel
public enum ConversationType {
DUMMY,
ROOM_TYPE_ONE_TO_ONE_CALL,
ROOM_GROUP_CALL,
ROOM_PUBLIC_CALL,
ROOM_SYSTEM
}
}

View file

@ -0,0 +1,191 @@
/*
*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Tim Krüger
* Copyright (C) 2021 Tim Krüger <t@timkrueger.me>
* Copyright (C) 2017 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.models.json.conversations
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.models.json.converters.EnumLobbyStateConverter
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter
import com.nextcloud.talk.models.json.converters.EnumReadOnlyConversationConverter
import com.nextcloud.talk.models.json.converters.EnumRoomTypeConverter
import com.nextcloud.talk.models.json.participants.Participant.ParticipantType
import kotlinx.android.parcel.Parcelize
@Parcelize
@JsonObject
data class Conversation(
@JsonField(name = ["id"])
var roomId: String? = null,
@JsonField(name = ["token"])
var token: String? = null,
@JsonField(name = ["name"])
var name: String? = null,
@JsonField(name = ["displayName"])
var displayName: String? = null,
@JsonField(name = ["description"])
var description: String? = null,
@JsonField(name = ["type"], typeConverter = EnumRoomTypeConverter::class)
var type: ConversationType? = null,
@JsonField(name = ["lastPing"])
var lastPing: Long = 0,
@JsonField(name = ["participantType"], typeConverter = EnumParticipantTypeConverter::class)
var participantType: ParticipantType? = null,
@JsonField(name = ["hasPassword"])
var hasPassword: Boolean = false,
@JsonField(name = ["sessionId"])
var sessionId: String? = null,
@JsonField(name = ["actorId"])
var actorId: String? = null,
@JsonField(name = ["actorType"])
var actorType: String? = null,
var password: String? = null,
@JsonField(name = ["isFavorite"])
var favorite: Boolean = false,
@JsonField(name = ["lastActivity"])
var lastActivity: Long = 0,
@JsonField(name = ["unreadMessages"])
var unreadMessages: Int = 0,
@JsonField(name = ["unreadMention"])
var unreadMention: Boolean = false,
@JsonField(name = ["lastMessage"])
var lastMessage: ChatMessage? = null,
@JsonField(name = ["objectType"])
var objectType: String? = null,
@JsonField(name = ["notificationLevel"], typeConverter = EnumNotificationLevelConverter::class)
var notificationLevel: NotificationLevel? = null,
@JsonField(name = ["readOnly"], typeConverter = EnumReadOnlyConversationConverter::class)
var conversationReadOnlyState: ConversationReadOnlyState? = null,
@JsonField(name = ["lobbyState"], typeConverter = EnumLobbyStateConverter::class)
var lobbyState: LobbyState? = null,
@JsonField(name = ["lobbyTimer"])
var lobbyTimer: Long? = null,
@JsonField(name = ["lastReadMessage"])
var lastReadMessage: Int = 0,
@JsonField(name = ["hasCall"])
var hasCall: Boolean = false,
@JsonField(name = ["callFlag"])
var callFlag: Int = 0,
@JsonField(name = ["canStartCall"])
var canStartCall: Boolean = false,
@JsonField(name = ["canLeaveConversation"])
var canLeaveConversation: Boolean? = null,
@JsonField(name = ["canDeleteConversation"])
var canDeleteConversation: Boolean? = null,
@JsonField(name = ["unreadMentionDirect"])
var unreadMentionDirect: Boolean? = null,
@JsonField(name = ["notificationCalls"])
var notificationCalls: Int? = null,
@JsonField(name = ["permissions"])
var permissions: Int = 0
) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null)
val isPublic: Boolean
get() = ConversationType.ROOM_PUBLIC_CALL == type
val isGuest: Boolean
get() = ParticipantType.GUEST == participantType || ParticipantType.GUEST_MODERATOR == participantType || ParticipantType.USER_FOLLOWING_LINK == participantType
val isParticipantOwnerOrModerator: Boolean
get() = ParticipantType.OWNER == participantType || ParticipantType.GUEST_MODERATOR == participantType || ParticipantType.MODERATOR == participantType
private fun isLockedOneToOne(conversationUser: UserEntity): Boolean {
return type == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL &&
CapabilitiesUtil.hasSpreedFeatureCapability(conversationUser, "locked-one-to-one-rooms")
}
fun canModerate(conversationUser: UserEntity): Boolean {
return isParticipantOwnerOrModerator && !isLockedOneToOne(conversationUser)
}
fun shouldShowLobby(conversationUser: UserEntity): Boolean {
return LobbyState.LOBBY_STATE_MODERATORS_ONLY == lobbyState && !canModerate(conversationUser)
}
fun isLobbyViewApplicable(conversationUser: UserEntity): Boolean {
return !canModerate(conversationUser) && (type == ConversationType.ROOM_GROUP_CALL || type == ConversationType.ROOM_PUBLIC_CALL)
}
fun isNameEditable(conversationUser: UserEntity): Boolean {
return canModerate(conversationUser) && ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL != type
}
fun canLeave(): Boolean {
return if (canLeaveConversation != null) {
// Available since APIv2
canLeaveConversation!!
} else {
true
}
}
fun canDelete(conversationUser: UserEntity): Boolean {
return if (canDeleteConversation != null) {
// Available since APIv2
canDeleteConversation!!
} else canModerate(conversationUser)
// Fallback for APIv1
}
enum class NotificationLevel {
DEFAULT, ALWAYS, MENTION, NEVER
}
enum class LobbyState {
LOBBY_STATE_ALL_PARTICIPANTS, LOBBY_STATE_MODERATORS_ONLY
}
enum class ConversationReadOnlyState {
CONVERSATION_READ_WRITE, CONVERSATION_READ_ONLY
}
enum class ConversationType {
DUMMY, ROOM_TYPE_ONE_TO_ONE_CALL, ROOM_GROUP_CALL, ROOM_PUBLIC_CALL, ROOM_SYSTEM
}
}

View file

@ -1,22 +1,23 @@
/*
* Nextcloud Talk application
*
* Nextcloud Talk application
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2017 Mario Danic (mario@lovelyhq.com)
*
* @author Mario Danic
* Copyright (C) 2017 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 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.
*
* 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/>.
* 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.models.json.generic

View file

@ -1,35 +0,0 @@
/*
*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017 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.models.json.participants;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.nextcloud.talk.models.json.generic.GenericOCS;
import com.nextcloud.talk.models.json.conversations.Conversation;
@JsonObject
public class AddParticipantOCS extends GenericOCS {
/*
Returned room will have only type set, and sometimes even that will be null
*/
@JsonField(name = "data")
Conversation data;
}

View file

@ -0,0 +1,42 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <info@andy-scherzinger.de>
* Copyright (C) 2017 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.models.json.participants
import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField
import com.bluelinelabs.logansquare.annotation.JsonObject
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericMeta
import kotlinx.android.parcel.Parcelize
@Parcelize
@JsonObject
data class AddParticipantOCS(
@JsonField(name = ["meta"])
var meta: GenericMeta?,
/* Returned room will have only type set, and sometimes even that will be null */
@JsonField(name = ["data"])
var data: Conversation? = null
) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null)
}

View file

@ -18,9 +18,6 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Parts related to account import were either copied from or inspired by the great work done by David Luhmer at:
* https://github.com/nextcloud/ownCloud-Account-Importer
*/
package com.nextcloud.talk.models.json.participants

View file

@ -149,15 +149,15 @@ class ProfileBottomSheet(val ncApi: NcApi, val userEntity: UserEntity, val route
override fun onNext(roomOverall: RoomOverall) {
val bundle = Bundle()
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, userEntity)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().getToken())
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().getRoomId())
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomOverall.getOcs().getData().token)
bundle.putString(BundleKeys.KEY_ROOM_ID, roomOverall.getOcs().getData().roomId)
// FIXME once APIv2+ is used only, the createRoom already returns all the data
ncApi.getRoom(
credentials,
ApiUtils.getUrlForRoom(
apiVersion, userEntity.baseUrl,
roomOverall.getOcs().getData().getToken()
roomOverall.getOcs().getData().token
)
)
.subscribeOn(Schedulers.io())
@ -174,7 +174,7 @@ class ProfileBottomSheet(val ncApi: NcApi, val userEntity: UserEntity, val route
)
ConductorRemapping.remapChatController(
router, userEntity.id,
roomOverall.getOcs().getData().getToken(), bundle, true
roomOverall.getOcs().getData().token!!, bundle, true
)
}

View file

@ -102,10 +102,10 @@ class ConversationsListBottomDialog(
}
private fun initHeaderDescription() {
if (!TextUtils.isEmpty(conversation.getDisplayName())) {
binding.conversationOperationHeader.text = conversation.getDisplayName()
} else if (!TextUtils.isEmpty(conversation.getName())) {
binding.conversationOperationHeader.text = conversation.getName()
if (!TextUtils.isEmpty(conversation.displayName)) {
binding.conversationOperationHeader.text = conversation.displayName
} else if (!TextUtils.isEmpty(conversation.name)) {
binding.conversationOperationHeader.text = conversation.name
}
}
@ -114,10 +114,10 @@ class ConversationsListBottomDialog(
val canModerate = conversation.canModerate(currentUser)
binding.conversationOperationRemoveFavorite.visibility = setVisibleIf(
hasFavoritesCapability && conversation.isFavorite()
hasFavoritesCapability && conversation.favorite
)
binding.conversationOperationAddFavorite.visibility = setVisibleIf(
hasFavoritesCapability && !conversation.isFavorite()
hasFavoritesCapability && !conversation.favorite
)
binding.conversationOperationMarkAsRead.visibility = setVisibleIf(
@ -133,15 +133,15 @@ class ConversationsListBottomDialog(
)
binding.conversationOperationChangePassword.visibility = setVisibleIf(
canModerate && conversation.isHasPassword && conversation.isPublic
canModerate && conversation.hasPassword && conversation.isPublic
)
binding.conversationOperationClearPassword.visibility = setVisibleIf(
canModerate && conversation.isHasPassword && conversation.isPublic
canModerate && conversation.hasPassword && conversation.isPublic
)
binding.conversationOperationSetPassword.visibility = setVisibleIf(
canModerate && !conversation.isHasPassword && conversation.isPublic
canModerate && !conversation.hasPassword && conversation.isPublic
)
binding.conversationOperationDelete.visibility = setVisibleIf(
@ -157,7 +157,7 @@ class ConversationsListBottomDialog(
)
binding.conversationOperationLeave.visibility = setVisibleIf(
conversation.canLeave(currentUser) &&
conversation.canLeave() &&
// leaving is by api not possible for the last user with moderator permissions.
// for now, hide this option for all moderators.
!conversation.canModerate(currentUser)
@ -183,7 +183,7 @@ class ConversationsListBottomDialog(
binding.conversationOperationLeave.setOnClickListener {
val dataBuilder = Data.Builder()
dataBuilder.putString(KEY_ROOM_TOKEN, conversation.getToken())
dataBuilder.putString(KEY_ROOM_TOKEN, conversation.token)
dataBuilder.putLong(KEY_INTERNAL_USER_ID, currentUser.id)
val data = dataBuilder.build()
@ -197,7 +197,7 @@ class ConversationsListBottomDialog(
}
binding.conversationOperationDelete.setOnClickListener {
if (!TextUtils.isEmpty(conversation.getToken())) {
if (!TextUtils.isEmpty(conversation.token)) {
val bundle = Bundle()
bundle.putLong(KEY_INTERNAL_USER_ID, currentUser.id)
bundle.putParcelable(KEY_ROOM, Parcels.wrap(conversation))

View file

@ -83,12 +83,12 @@ class MessageActionsDialog(
)
initMenuDeleteMessage(showMessageDeletionButton)
initMenuForwardMessage(
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getMessageType() &&
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE == message.getCalculateMessageType() &&
!(message.isDeletedCommentMessage || message.isDeleted)
)
initMenuMarkAsUnread(
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getMessageType() &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getCalculateMessageType() &&
BuildConfig.DEBUG
)
}

View file

@ -95,9 +95,9 @@ class ShowReactionsDialog(
private fun initEmojiReactions() {
adapter?.list?.clear()
if (chatMessage.reactions != null && chatMessage.reactions.isNotEmpty()) {
if (chatMessage.reactions != null && chatMessage.reactions!!.isNotEmpty()) {
var reactionsTotal = 0
for ((emoji, amount) in chatMessage.reactions) {
for ((emoji, amount) in chatMessage.reactions!!) {
reactionsTotal = reactionsTotal.plus(amount as Int)
val tab: TabLayout.Tab = binding.emojiReactionsTabs.newTab() // Create a new Tab names "First Tab"

View file

@ -58,14 +58,14 @@ class FileViewerUtils(private val context: Context, private val userEntity: User
message: ChatMessage,
progressUi: ProgressUi
) {
val fileName = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]!!
val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
val link = message.getSelectedIndividualHashMap()["link"]!!
val fileName = message.selectedIndividualHashMap!![MagicPreviewMessageViewHolder.KEY_NAME]!!
val mimetype = message.selectedIndividualHashMap!![MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
val link = message.selectedIndividualHashMap!!["link"]!!
val fileId = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]!!
val path = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_PATH]!!
val fileId = message.selectedIndividualHashMap!![MagicPreviewMessageViewHolder.KEY_ID]!!
val path = message.selectedIndividualHashMap!![MagicPreviewMessageViewHolder.KEY_PATH]!!
var size = message.getSelectedIndividualHashMap()["size"]
var size = message.selectedIndividualHashMap!!["size"]
if (size == null) {
size = "-1"
}

View file

@ -72,8 +72,8 @@ class SharedItemsViewModel(private val repository: SharedItemsRepository, privat
val mediaItems = response.body()!!.ocs!!.data
if (mediaItems != null) {
for (it in mediaItems) {
if (it.value.messageParameters.containsKey("file")) {
val fileParameters = it.value.messageParameters["file"]!!
if (it.value.messageParameters!!.containsKey("file")) {
val fileParameters = it.value.messageParameters!!["file"]!!
val previewAvailable =
"yes".equals(fileParameters["preview-available"], ignoreCase = true)

View file

@ -69,7 +69,7 @@ class ShareUtilsTest {
PowerMockito.mockStatic(TextUtils::class.java)
Mockito.`when`(userUtils!!.currentUser).thenReturn(userEntity)
Mockito.`when`(userEntity!!.baseUrl).thenReturn(baseUrl)
Mockito.`when`(conversation!!.getToken()).thenReturn(token)
Mockito.`when`(conversation!!.token).thenReturn(token)
Mockito.`when`(context!!.resources).thenReturn(resources)
Mockito.`when`(resources!!.getString(R.string.nc_share_text))
.thenReturn("Join the conversation at %1\$s/index.php/call/%2\$s")