diff --git a/app/build.gradle b/app/build.gradle
index 3cbd78b9d..fbf41f376 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -70,15 +70,18 @@ android {
javaCompileOptions {
annotationProcessorOptions {
- arguments = [
- parcelerStacktrace: "true"
- ]
+ arguments = ["room.schemaLocation":
+ "$projectDir/schemas".toString()]
}
}
dataBinding {
enabled = true
}
+
+ androidExtensions {
+ experimental = true
+ }
}
dexOptions {
@@ -109,6 +112,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+
lintOptions {
abortOnError false
htmlReport true
diff --git a/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
new file mode 100644
index 000000000..239bb5f9d
--- /dev/null
+++ b/app/schemas/com.nextcloud.talk.newarch.local.db.TalkDatabase/1.json
@@ -0,0 +1,179 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "a547a767687b46e3e5768a3d77d5d212",
+ "entities": [
+ {
+ "tableName": "conversations",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user` INTEGER NOT NULL, `conversation_id` TEXT NOT NULL, `token` TEXT, `name` TEXT, `display_name` TEXT, `type` INTEGER, `count` INTEGER NOT NULL, `number_of_guests` INTEGER NOT NULL, `participants_count` INTEGER NOT NULL, `participant_type` INTEGER, `has_password` INTEGER NOT NULL, `session_id` TEXT, `favorite` INTEGER NOT NULL, `last_activity` INTEGER NOT NULL, `unread_messages` INTEGER NOT NULL, `unread_mention` INTEGER NOT NULL, `last_message` TEXT, `object_type` TEXT, `notification_level` INTEGER, `read_only_state` INTEGER, `lobby_state` INTEGER, `lobby_timer` INTEGER, `last_read_message_id` INTEGER NOT NULL, `modified_at` INTEGER, `changing` INTEGER NOT NULL, PRIMARY KEY(`user`, `conversation_id`))",
+ "fields": [
+ {
+ "fieldPath": "userId",
+ "columnName": "user",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "conversationId",
+ "columnName": "conversation_id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "token",
+ "columnName": "token",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "displayName",
+ "columnName": "display_name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "count",
+ "columnName": "count",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "numberOfGuests",
+ "columnName": "number_of_guests",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "participantsCount",
+ "columnName": "participants_count",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "participantType",
+ "columnName": "participant_type",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "hasPassword",
+ "columnName": "has_password",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sessionId",
+ "columnName": "session_id",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "favorite",
+ "columnName": "favorite",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastActivity",
+ "columnName": "last_activity",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unreadMessages",
+ "columnName": "unread_messages",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unreadMention",
+ "columnName": "unread_mention",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lastMessage",
+ "columnName": "last_message",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "objectType",
+ "columnName": "object_type",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "notificationLevel",
+ "columnName": "notification_level",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "conversationReadOnlyState",
+ "columnName": "read_only_state",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lobbyState",
+ "columnName": "lobby_state",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lobbyTimer",
+ "columnName": "lobby_timer",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "lastReadMessageId",
+ "columnName": "last_read_message_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "modifiedAt",
+ "columnName": "modified_at",
+ "affinity": "INTEGER",
+ "notNull": false
+ },
+ {
+ "fieldPath": "changing",
+ "columnName": "changing",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "user",
+ "conversation_id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a547a767687b46e3e5768a3d77d5d212')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java
deleted file mode 100644
index ce6adfd67..000000000
--- a/app/src/main/java/com/nextcloud/talk/adapters/items/CallItem.java
+++ /dev/null
@@ -1,192 +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 .
- */
-
-package com.nextcloud.talk.adapters.items;
-
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import androidx.emoji.widget.EmojiTextView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import com.facebook.drawee.backends.pipeline.Fresco;
-import com.facebook.drawee.interfaces.DraweeController;
-import com.facebook.drawee.view.SimpleDraweeView;
-import com.nextcloud.talk.R;
-import com.nextcloud.talk.application.NextcloudTalkApplication;
-import com.nextcloud.talk.events.MoreMenuClickEvent;
-import com.nextcloud.talk.models.database.UserEntity;
-import com.nextcloud.talk.models.json.conversations.Conversation;
-import com.nextcloud.talk.utils.ApiUtils;
-import com.nextcloud.talk.utils.DisplayUtils;
-import eu.davidea.flexibleadapter.FlexibleAdapter;
-import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
-import eu.davidea.flexibleadapter.items.IFilterable;
-import eu.davidea.flexibleadapter.utils.FlexibleUtils;
-import eu.davidea.viewholders.FlexibleViewHolder;
-import java.util.List;
-import java.util.regex.Pattern;
-import org.greenrobot.eventbus.EventBus;
-
-public class CallItem extends AbstractFlexibleItem
- implements IFilterable {
-
- private Conversation conversation;
- private UserEntity userEntity;
-
- public CallItem(Conversation conversation, UserEntity userEntity) {
- this.conversation = conversation;
- this.userEntity = userEntity;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof CallItem) {
- CallItem inItem = (CallItem) o;
- return conversation.equals(inItem.getModel());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return conversation.hashCode();
- }
-
- /**
- * @return the model object
- */
-
- public Conversation getModel() {
- return conversation;
- }
-
- /**
- * Filter is applied to the model fields.
- */
-
- @Override
- public int getLayoutRes() {
- return R.layout.rv_item_conversation;
- }
-
- @Override
- public RoomItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) {
- return new RoomItemViewHolder(view, adapter);
- }
-
- @Override
- public void bindViewHolder(final FlexibleAdapter adapter, RoomItemViewHolder holder, int position,
- List payloads) {
- if (adapter.hasFilter()) {
- FlexibleUtils.highlightText(holder.roomDisplayName, conversation.getDisplayName(),
- String.valueOf(adapter.getFilter(String.class)),
- NextcloudTalkApplication.Companion.getSharedApplication()
- .getResources().getColor(R.color.colorPrimary));
- } else {
- holder.roomDisplayName.setText(conversation.getDisplayName());
- }
-
- if (conversation.getLastPing() == 0) {
- holder.roomLastPing.setText(R.string.nc_never);
- } else {
- holder.roomLastPing.setText(
- DateUtils.getRelativeTimeSpanString(conversation.getLastPing() * 1000L,
- System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
- }
-
- if (conversation.hasPassword) {
- holder.passwordProtectedImageView.setVisibility(View.VISIBLE);
- } else {
- holder.passwordProtectedImageView.setVisibility(View.GONE);
- }
-
- Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
- switch (conversation.getType()) {
- case ROOM_TYPE_ONE_TO_ONE_CALL:
- holder.avatarImageView.setVisibility(View.VISIBLE);
-
- holder.moreMenuButton.setContentDescription(String.format(resources.getString(R.string
- .nc_description_more_menu_one_to_one), conversation.getDisplayName()));
-
- if (!TextUtils.isEmpty(conversation.getName())) {
- DraweeController draweeController = Fresco.newDraweeControllerBuilder()
- .setOldController(holder.avatarImageView.getController())
- .setAutoPlayAnimations(true)
- .setImageRequest(DisplayUtils.getImageRequestForUrl(
- ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(),
- conversation.getName(),
- R.dimen.avatar_size), null))
- .build();
- holder.avatarImageView.setController(draweeController);
- } else {
- holder.avatarImageView.setVisibility(View.GONE);
- }
- break;
- case ROOM_GROUP_CALL:
- holder.moreMenuButton.setContentDescription(String.format(resources.getString(R.string
- .nc_description_more_menu_group), conversation.getDisplayName()));
- holder.avatarImageView.setActualImageResource(R.drawable.ic_people_group_white_24px);
- holder.avatarImageView.setVisibility(View.VISIBLE);
- break;
- case ROOM_PUBLIC_CALL:
- holder.moreMenuButton.setContentDescription(String.format(resources.getString(R.string
- .nc_description_more_menu_public), conversation.getDisplayName()));
- holder.avatarImageView.setActualImageResource(R.drawable.ic_link_white_24px);
- holder.avatarImageView.setVisibility(View.VISIBLE);
- break;
- default:
- holder.avatarImageView.setVisibility(View.GONE);
- }
-
- holder.moreMenuButton.setOnClickListener(
- view -> EventBus.getDefault().post(new MoreMenuClickEvent(conversation)));
- }
-
- @Override
- public boolean filter(String constraint) {
- return conversation.getDisplayName() != null &&
- Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
- .matcher(conversation.getDisplayName().trim())
- .find();
- }
-
- static class RoomItemViewHolder extends FlexibleViewHolder {
-
- @BindView(R.id.name_text)
- public EmojiTextView roomDisplayName;
- @BindView(R.id.secondary_text)
- public EmojiTextView roomLastPing;
- @BindView(R.id.avatar_image)
- public SimpleDraweeView avatarImageView;
- @BindView(R.id.more_menu)
- public ImageButton moreMenuButton;
- @BindView(R.id.password_protected_image_view)
- ImageView passwordProtectedImageView;
-
- RoomItemViewHolder(View view, FlexibleAdapter adapter) {
- super(view, adapter);
- ButterKnife.bind(this, view);
- }
- }
-}
diff --git a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java
index 0941860dd..a6ec18743 100644
--- a/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java
+++ b/app/src/main/java/com/nextcloud/talk/adapters/items/ConversationItem.java
@@ -104,7 +104,7 @@ public class ConversationItem
holder.dialogAvatar.setController(null);
- if (conversation.isUpdating()) {
+ if (conversation.getChanging()) {
holder.progressBar.setVisibility(View.VISIBLE);
} else {
holder.progressBar.setVisibility(View.GONE);
@@ -127,7 +127,7 @@ public class ConversationItem
holder.dialogUnreadBubble.setText("99+");
}
- if (conversation.isUnreadMention()) {
+ if (conversation.getUnreadMention()) {
holder.dialogUnreadBubble.setBackground(
context.getDrawable(R.drawable.bubble_circle_unread_mention));
} else {
@@ -138,13 +138,13 @@ public class ConversationItem
holder.dialogUnreadBubble.setVisibility(View.GONE);
}
- if (conversation.isHasPassword()) {
+ if (conversation.getHasPassword()) {
holder.passwordProtectedRoomImageView.setVisibility(View.VISIBLE);
} else {
holder.passwordProtectedRoomImageView.setVisibility(View.GONE);
}
- if (conversation.isFavorite()) {
+ if (conversation.getFavorite()) {
holder.pinnedConversationImageView.setVisibility(View.VISIBLE);
} else {
holder.pinnedConversationImageView.setVisibility(View.GONE);
@@ -157,7 +157,7 @@ public class ConversationItem
System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
if (!TextUtils.isEmpty(conversation.getLastMessage().getSystemMessage())
- || Conversation.ConversationType.ROOM_SYSTEM.equals(conversation.getType())) {
+ || Conversation.ConversationType.SYSTEM_CONVERSATION.equals(conversation.getType())) {
holder.dialogLastMessage.setText(conversation.getLastMessage().getText());
} else {
String authorDisplayName = "";
@@ -213,7 +213,7 @@ public class ConversationItem
}
}
- if (Conversation.ConversationType.ROOM_SYSTEM.equals(conversation.getType())) {
+ if (Conversation.ConversationType.SYSTEM_CONVERSATION.equals(conversation.getType())) {
Drawable[] layers = new Drawable[2];
layers[0] = context.getDrawable(R.drawable.ic_launcher_background);
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground);
@@ -227,7 +227,7 @@ public class ConversationItem
if (shouldLoadAvatar) {
switch (conversation.getType()) {
- case ROOM_TYPE_ONE_TO_ONE_CALL:
+ case ONE_TO_ONE_CONVERSATION:
if (!TextUtils.isEmpty(conversation.getName())) {
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(holder.dialogAvatar.getController())
@@ -241,13 +241,13 @@ public class ConversationItem
holder.dialogAvatar.setVisibility(View.GONE);
}
break;
- case ROOM_GROUP_CALL:
+ case GROUP_CONVERSATION:
holder.dialogAvatar.getHierarchy()
.setImage(new BitmapDrawable(
DisplayUtils.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
R.drawable.ic_people_group_white_24px)), 100, true);
break;
- case ROOM_PUBLIC_CALL:
+ case PUBLIC_CONVERSATION:
holder.dialogAvatar.getHierarchy().setImage(new BitmapDrawable(DisplayUtils
.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
R.drawable.ic_link_white_24px)), 100, true);
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
index 26b75aa40..1edfbe180 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
@@ -411,7 +411,7 @@ public class CallNotificationController extends BaseController {
private void loadAvatar() {
switch (currentConversation.getType()) {
- case ROOM_TYPE_ONE_TO_ONE_CALL:
+ case ONE_TO_ONE_CONVERSATION:
avatarImageView.setVisibility(View.VISIBLE);
ImageRequest imageRequest =
@@ -463,12 +463,12 @@ public class CallNotificationController extends BaseController {
}, UiThreadImmediateExecutorService.getInstance());
break;
- case ROOM_GROUP_CALL:
+ case GROUP_CONVERSATION:
avatarImageView.getHierarchy()
.setImage(DisplayUtils.getRoundedDrawable(
context.getDrawable(R.drawable.ic_people_group_white_24px))
, 100, true);
- case ROOM_PUBLIC_CALL:
+ case PUBLIC_CONVERSATION:
avatarImageView.getHierarchy()
.setImage(DisplayUtils.getRoundedDrawable(
context.getDrawable(R.drawable.ic_people_group_white_24px))
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
index 53ee3e71b..81ef833f4 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt
@@ -312,7 +312,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
private fun loadAvatarForStatusBar() {
if (currentConversation != null && currentConversation?.type != null &&
currentConversation?.type == Conversation.ConversationType
- .ROOM_TYPE_ONE_TO_ONE_CALL && activity != null && conversationVoiceCallMenuItem != null
+ .ONE_TO_ONE_CONVERSATION && activity != null && conversationVoiceCallMenuItem != null
) {
val avatarSize = DisplayUtils.convertDpToPixel(
conversationVoiceCallMenuItem?.icon!!
@@ -536,9 +536,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
}
private fun checkReadOnlyState() {
- if (currentConversation != null) {
- if (currentConversation?.shouldShowLobby(
- conversationUser
+ if (currentConversation != null && conversationUser != null) {
+ if (currentConversation?.shouldShowLobby(conversationUser
) == true || currentConversation?.conversationReadOnlyState != null && currentConversation?.conversationReadOnlyState == Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY
) {
@@ -555,8 +554,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
conversationVideoMenuItem?.icon?.alpha = 255
}
- if (currentConversation != null && currentConversation!!.shouldShowLobby
- (conversationUser)
+ if (conversationUser != null && currentConversation != null && currentConversation!!
+ .shouldShowLobby(conversationUser)
) {
messageInputView?.visibility = View.GONE
} else {
@@ -567,8 +566,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
}
private fun checkLobbyState() {
- if (currentConversation != null && currentConversation?.isLobbyViewApplicable(
- conversationUser
+ if (currentConversation != null && conversationUser != null && currentConversation?.isLobbyViewApplicable(conversationUser
) == true
) {
@@ -754,9 +752,11 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
override fun getTitle(): String? {
if (currentConversation != null && currentConversation?.displayName != null) {
- return EmojiCompat.get()
- .process(currentConversation!!.displayName)
- .toString()
+ return currentConversation!!.displayName?.let {
+ EmojiCompat.get()
+ .process(it)
+ .toString()
+ }
} else {
return ""
}
@@ -1032,7 +1032,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
return
}
- if (currentConversation != null && currentConversation!!.shouldShowLobby(conversationUser)) {
+ if (currentConversation != null && conversationUser != null && currentConversation!!
+ .shouldShowLobby(conversationUser)) {
return
}
@@ -1050,8 +1051,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
lookingIntoFuture = true
} else if (isFirstMessagesProcessing) {
if (currentConversation != null) {
- globalLastKnownFutureMessageId = currentConversation!!.lastReadMessage
- globalLastKnownPastMessageId = currentConversation!!.lastReadMessage
+ globalLastKnownFutureMessageId = currentConversation!!.lastReadMessageId
+ globalLastKnownPastMessageId = currentConversation!!.lastReadMessageId
fieldMap["includeLastKnown"] = 1
}
}
@@ -1188,7 +1189,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
val chatMessage = chatMessageList[i]
chatMessage.isOneToOneConversation =
- currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
+ currentConversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
chatMessage.isLinkPreviewAllowed = isLinkPreviewAllowed
chatMessage.activeUser = conversationUser
@@ -1258,7 +1259,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
.actorId, -1
) && adapter!!.getSameAuthorLastMessagesCount(chatMessage.actorId) % 5 > 0)
chatMessage.isOneToOneConversation =
- (currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
+ (currentConversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION)
adapter?.addToStart(chatMessage, shouldScroll)
}
@@ -1447,7 +1448,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
@Subscribe(threadMode = ThreadMode.BACKGROUND)
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
if (currentConversation?.type != Conversation.ConversationType
- .ROOM_TYPE_ONE_TO_ONE_CALL || currentConversation?.name !=
+ .ONE_TO_ONE_CONVERSATION || currentConversation?.name !=
userMentionClickEvent.userId
) {
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
@@ -1482,10 +1483,13 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
)
conversationIntent.putExtras(bundle)
- ConductorRemapping.remapChatController(
- router, conversationUser.id,
- roomOverall.ocs.data.token, bundle, false
- )
+ if (roomOverall != null && roomOverall.ocs != null && roomOverall.ocs.data !=
+ null && roomOverall.ocs.data.token != null) {
+ ConductorRemapping.remapChatController(
+ router, conversationUser.id,
+ roomOverall.ocs.data.token!!, bundle, false
+ )
+ }
}
} else {
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java
index 9c42d7dfa..a9f935a58 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java
@@ -372,9 +372,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
Bundle bundle = new Bundle();
Conversation.ConversationType roomType;
if (isPublicCall) {
- roomType = Conversation.ConversationType.ROOM_PUBLIC_CALL;
+ roomType = Conversation.ConversationType.PUBLIC_CONVERSATION;
} else {
- roomType = Conversation.ConversationType.ROOM_GROUP_CALL;
+ roomType = Conversation.ConversationType.GROUP_CONVERSATION;
}
ArrayList userIdsArray = new ArrayList<>(selectedUserIds);
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt
index 9cb3798b2..9160f013b 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt
@@ -63,7 +63,7 @@ import com.nextcloud.talk.jobs.LeaveConversationWorker
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
-import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ROOM_PUBLIC_CALL
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.PUBLIC_CONVERSATION
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
import com.nextcloud.talk.models.json.generic.GenericOverall
@@ -253,8 +253,8 @@ class ConversationInfoController(args: Bundle) : BaseController(),
private fun setupWebinaryView() {
if (conversationUser!!.hasSpreedFeatureCapability("webinary-lobby") && (conversation!!.type
- == Conversation.ConversationType.ROOM_GROUP_CALL || conversation!!.type ==
- Conversation.ConversationType.ROOM_PUBLIC_CALL) && conversation!!.canModerate(
+ == Conversation.ConversationType.GROUP_CONVERSATION || conversation!!.type ==
+ Conversation.ConversationType.PUBLIC_CONVERSATION) && conversation!!.canModerate(
conversationUser
)
) {
@@ -270,8 +270,8 @@ class ConversationInfoController(args: Bundle) : BaseController(),
startTimeView.setOnClickListener {
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
val currentTimeCalendar = Calendar.getInstance()
- if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
- currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer * 1000
+ if (conversation != null && conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
+ currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * 1000
}
dateTimePicker(minDateTime = Calendar.getInstance(), requireFutureDateTime =
@@ -309,7 +309,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != java.lang.Long.MIN_VALUE && conversation!!.lobbyTimer != 0L) {
startTimeView.setSummary(
- DateUtils.getLocalDateStringFromTimestampForLobby(conversation!!.lobbyTimer)
+ conversation!!.lobbyTimer?.let { DateUtils.getLocalDateStringFromTimestampForLobby(it) }
)
} else {
startTimeView.setSummary(R.string.nc_manual)
@@ -670,7 +670,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
deleteConversationAction.visibility = View.VISIBLE
}
- if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) {
+ if (Conversation.ConversationType.SYSTEM_CONVERSATION == conversation!!.type) {
muteCalls.visibility = View.GONE
}
@@ -701,7 +701,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
}
private fun setupGeneralSettings() {
- if (conversation != null) {
+ if (conversation != null && conversationUser != null) {
changeConversationName.value = conversation!!.displayName
if (conversation!!.isNameEditable(conversationUser)) {
@@ -710,12 +710,12 @@ class ConversationInfoController(args: Bundle) : BaseController(),
changeConversationName.visibility = View.GONE
}
- favoriteConversationAction.value = conversation!!.isFavorite
- if (conversation!!.type.equals(ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) || conversation!!
- .type.equals(ConversationType.ROOM_SYSTEM)) {
+ favoriteConversationAction.value = conversation!!.favorite
+ if (conversation!!.type!!.equals(ConversationType.ONE_TO_ONE_CONVERSATION) || conversation!!
+ .type!!.equals(ConversationType.SYSTEM_CONVERSATION)) {
allowGuestsAction.visibility = View.GONE
} else {
- allowGuestsAction.value = conversation!!.type == ROOM_PUBLIC_CALL
+ allowGuestsAction.value = conversation!!.type == PUBLIC_CONVERSATION
}
(allowGuestsAction.findViewById(R.id.mp_checkable) as SwitchCompat)
@@ -813,7 +813,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
}
private fun setProperNotificationValue(conversation: Conversation?) {
- if (conversation!!.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
+ if (conversation!!.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION) {
// hack to see if we get mentioned always or just on mention
if (conversationUser!!.hasSpreedFeatureCapability("mention-flag")) {
messageNotificationLevel.value = "always"
@@ -827,7 +827,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
private fun loadConversationAvatar() {
when (conversation!!.type) {
- Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty
+ Conversation.ConversationType.ONE_TO_ONE_CONVERSATION -> if (!TextUtils.isEmpty
(conversation!!.name)
) {
val draweeController = Fresco.newDraweeControllerBuilder()
@@ -844,21 +844,21 @@ class ConversationInfoController(args: Bundle) : BaseController(),
.build()
conversationAvatarImageView.controller = draweeController
}
- Conversation.ConversationType.ROOM_GROUP_CALL -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
+ Conversation.ConversationType.GROUP_CONVERSATION -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
DisplayUtils
.getRoundedBitmapDrawableFromVectorDrawableResource(
resources,
R.drawable.ic_people_group_white_24px
)
)
- Conversation.ConversationType.ROOM_PUBLIC_CALL -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
+ Conversation.ConversationType.PUBLIC_CONVERSATION -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
DisplayUtils
.getRoundedBitmapDrawableFromVectorDrawableResource(
resources,
R.drawable.ic_link_white_24px
)
)
- Conversation.ConversationType.ROOM_SYSTEM -> {
+ Conversation.ConversationType.SYSTEM_CONVERSATION -> {
val layers = arrayOfNulls(2)
layers[0] = context.getDrawable(R.drawable.ic_launcher_background)
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground)
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java b/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
index 05b18c449..b5f4a0184 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
@@ -123,6 +123,9 @@ public class WebViewLoginController extends BaseController {
private WebViewFidoBridge webViewFidoBridge;
+ public WebViewLoginController() {
+ }
+
public WebViewLoginController(String baseUrl, boolean isPasswordUpdate) {
this.baseUrl = baseUrl;
this.isPasswordUpdate = isPasswordUpdate;
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java
index aed36a97c..0a23d3c04 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java
@@ -270,7 +270,7 @@ public class OperationsMenuController extends BaseController {
invite = invitedGroups.get(0);
}
- if (conversationType.equals(Conversation.ConversationType.ROOM_PUBLIC_CALL) ||
+ if (conversationType.equals(Conversation.ConversationType.PUBLIC_CONVERSATION) ||
!currentUser.hasSpreedFeatureCapability("empty-group-room")) {
retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(),
"3", invite, conversationName);
@@ -314,7 +314,7 @@ public class OperationsMenuController extends BaseController {
public void onNext(RoomOverall roomOverall) {
conversation = roomOverall.getOcs().getData();
if (conversationType.equals(
- Conversation.ConversationType.ROOM_PUBLIC_CALL)
+ Conversation.ConversationType.PUBLIC_CONVERSATION)
&& isGroupCallWorkaroundFinal) {
performGroupCallWorkaround(credentials);
} else {
@@ -490,7 +490,7 @@ public class OperationsMenuController extends BaseController {
.getFeatures() != null && capabilitiesOverall.getOcs().getData()
.getCapabilities().getSpreedCapability()
.getFeatures().contains("chat-v2")) {
- if (conversation.isHasPassword() && conversation.isGuest()) {
+ if (conversation.getHasPassword() && conversation.isGuest()) {
eventBus.post(new BottomSheetLockEvent(true, 0,
true, false));
Bundle bundle = new Bundle();
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java
index aed265a9c..3eeee34e8 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java
+++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java
@@ -27,7 +27,6 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.net.Uri;
@@ -171,12 +170,12 @@ public class NotificationWorker extends Worker {
intent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM(), Parcels.wrap(conversation));
if (conversation.getType()
- .equals(Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) ||
+ .equals(Conversation.ConversationType.ONE_TO_ONE_CONVERSATION) ||
(!TextUtils.isEmpty(conversation.getObjectType()) && "share:password".equals
(conversation.getObjectType()))) {
context.startActivity(intent);
} else {
- if (conversation.getType().equals(Conversation.ConversationType.ROOM_GROUP_CALL)) {
+ if (conversation.getType().equals(Conversation.ConversationType.GROUP_CONVERSATION)) {
conversationType = "group";
} else {
conversationType = "public";
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
index 6e3d31af3..1b272771c 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java
@@ -43,7 +43,7 @@ import org.parceler.Parcel;
@Parcel
@Data
-@JsonObject
+@JsonObject(serializeNullCollectionElements = true, serializeNullObjects = true)
public class ChatMessage implements IMessage, MessageContentType, MessageContentType.Image {
@JsonIgnore
public boolean isGrouped;
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.java b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.java
deleted file mode 100644
index 7c0a3fc6a..000000000
--- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.java
+++ /dev/null
@@ -1,173 +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 .
- */
-package com.nextcloud.talk.models.json.conversations;
-
-import android.content.res.Resources;
-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.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 java.util.HashMap;
-import lombok.Data;
-import org.parceler.Parcel;
-
-@Parcel
-@Data
-@JsonObject
-public class Conversation {
- @JsonField(name = "id")
- public String conversationId;
- @JsonField(name = "token")
- public String token;
- @JsonField(name = "name")
- public String name;
- @JsonField(name = "displayName")
- public String displayName;
- @JsonField(name = "type", typeConverter = EnumRoomTypeConverter.class)
- public ConversationType type;
- @JsonField(name = "count")
- public long count;
- @JsonField(name = "lastPing")
- public long lastPing;
- @JsonField(name = "numGuests")
- public long numberOfGuests;
- @JsonField(name = "guestList")
- public HashMap> guestList;
- @JsonField(name = "participants")
- public HashMap> participants;
- @JsonField(name = "participantType", typeConverter = EnumParticipantTypeConverter.class)
- public Participant.ParticipantType participantType;
- @JsonField(name = "hasPassword")
- public boolean hasPassword;
- @JsonField(name = "sessionId")
- public String sessionId;
- 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;
- public boolean updating;
-
- public boolean isPublic() {
- return (ConversationType.ROOM_PUBLIC_CALL.equals(type));
- }
-
- public boolean isGuest() {
- return (Participant.ParticipantType.GUEST.equals(participantType) ||
- Participant.ParticipantType.USER_FOLLOWING_LINK.equals(participantType));
- }
-
- private boolean isLockedOneToOne(UserEntity conversationUser) {
- return (getType() == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
- && conversationUser.hasSpreedFeatureCapability("locked-one-to-one-rooms"));
- }
-
- public boolean canModerate(UserEntity conversationUser) {
- return ((Participant.ParticipantType.OWNER.equals(participantType)
- || Participant.ParticipantType.MODERATOR.equals(participantType)) && !isLockedOneToOne(
- conversationUser));
- }
-
- 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) {
- return !canModerate(conversationUser) || (getType()
- != ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && getParticipants().size() > 1);
- }
-
- public String getDeleteWarningMessage() {
- Resources resources = NextcloudTalkApplication.Companion.getSharedApplication().getResources();
- if (getType() == ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
- return String.format(resources.getString(R.string.nc_delete_conversation_one2one),
- getDisplayName());
- } else if (getParticipants().size() > 1) {
- return resources.getString(R.string.nc_delete_conversation_more);
- }
-
- return resources.getString(R.string.nc_delete_conversation_default);
- }
-
- 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
- }
-}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt
new file mode 100644
index 000000000..f73eda166
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt
@@ -0,0 +1,180 @@
+/*
+ *
+ * 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 .
+ */
+package com.nextcloud.talk.models.json.conversations
+
+import androidx.annotation.NonNull
+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.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 lombok.Data
+import org.parceler.Parcel
+import org.parceler.ParcelConstructor
+import java.util.HashMap
+
+@Parcel
+@Data
+@JsonObject(serializeNullCollectionElements = true, serializeNullObjects = true)
+class Conversation {
+ @JsonIgnore
+ @NonNull
+ var user: Long = 0L
+ @JsonField(name = ["id"])
+ var conversationId: String = ""
+ @JsonField(name = ["token"])
+ var token: String? = null
+ @JsonField(name = ["name"])
+ var name: String? = null
+ @JsonField(name = ["displayName"])
+ var displayName: String? = null
+ @JsonField(name = ["type"], typeConverter = EnumRoomTypeConverter::class)
+ var type: ConversationType? = null
+ @JsonField(name = ["count"])
+ var count: Long = 0
+ /*@JsonField(name = ["lastPing"])
+ var lastPing: Long = 0*/
+ @JsonField(name = ["numGuests"])
+ var numberOfGuests: Long = 0
+ /*@JsonField(name = ["guestList"])
+ var guestList: HashMap>? = null*/
+ @JsonField(name = ["participants"])
+ var participants: HashMap>? = null
+ @JsonField(name = ["participantType"], typeConverter = EnumParticipantTypeConverter::class)
+ var participantType: Participant.ParticipantType? = null
+ @JsonField(name = ["hasPassword"])
+ var hasPassword: Boolean = false
+ @JsonField(name = ["sessionId"])
+ var sessionId: String? = null
+ @JsonIgnore 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? = 0
+ @JsonField(name = ["lastReadMessageId"])
+ var lastReadMessageId: Int = 0
+ var changing: Boolean = false
+
+ val isPublic: Boolean = ConversationType.PUBLIC_CONVERSATION == type
+ val isGuest: Boolean =
+ Participant.ParticipantType.GUEST == participantType ||
+ Participant.ParticipantType.USER_FOLLOWING_LINK == participantType
+
+ val deleteWarningMessage: String
+ get() {
+ val resources = NextcloudTalkApplication.sharedApplication!!.resources
+ if (type == ConversationType.ONE_TO_ONE_CONVERSATION) {
+ return String.format(
+ resources.getString(R.string.nc_delete_conversation_one2one),
+ displayName!!
+ )
+ } else if (participants!!.size > 1) {
+ return resources.getString(R.string.nc_delete_conversation_more)
+ }
+
+ return resources.getString(R.string.nc_delete_conversation_default)
+ }
+
+ private fun isLockedOneToOne(conversationUser: UserEntity): Boolean {
+ return type == ConversationType.ONE_TO_ONE_CONVERSATION && conversationUser
+ .hasSpreedFeatureCapability(
+ "locked-one-to-one-rooms"
+ )
+ }
+
+ fun canModerate(conversationUser: UserEntity): Boolean {
+ return (Participant.ParticipantType.OWNER == participantType || Participant.ParticipantType.MODERATOR == participantType) && !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.GROUP_CONVERSATION || type == ConversationType.PUBLIC_CONVERSATION)
+ }
+
+ fun isNameEditable(conversationUser: UserEntity): Boolean {
+ return canModerate(conversationUser) && ConversationType.ONE_TO_ONE_CONVERSATION != type
+ }
+
+ fun canLeave(conversationUser: UserEntity): Boolean {
+ return !canModerate(
+ conversationUser
+ ) || type != ConversationType.ONE_TO_ONE_CONVERSATION && participants!!.size > 1
+ }
+
+ 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
+ }
+
+ @Parcel
+ enum class ConversationType @ParcelConstructor constructor(val value: Int = 1) {
+ ONE_TO_ONE_CONVERSATION(1),
+ GROUP_CONVERSATION(2),
+ PUBLIC_CONVERSATION(3),
+ SYSTEM_CONVERSATION(4)
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java
index 7c1744a88..cd7b9cda6 100644
--- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java
+++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumRoomTypeConverter.java
@@ -28,33 +28,31 @@ public class EnumRoomTypeConverter extends IntBasedTypeConverter
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.data.repository
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.map
+import com.nextcloud.talk.models.database.UserEntity
+import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository
+import com.nextcloud.talk.newarch.local.db.TalkDatabase
+import com.nextcloud.talk.newarch.local.models.toConversation
+import com.nextcloud.talk.newarch.local.models.toConversationEntity
+
+class NextcloudTalkOfflineRepositoryImpl(val nextcloudTalkDatabase: TalkDatabase) :
+ NextcloudTalkOfflineRepository {
+ override suspend fun setChangingValueForConversation(
+ userId: Long,
+ conversationId: String,
+ changing: Boolean
+ ) {
+ nextcloudTalkDatabase.conversationsDao()
+ .updateChangingValueForConversation(userId, conversationId, changing)
+ }
+
+ override suspend fun setFavoriteValueForConversation(
+ userId: Long,
+ conversationId: String,
+ favorite: Boolean
+ ) {
+ nextcloudTalkDatabase.conversationsDao()
+ .updateFavoriteValueForConversation(userId, conversationId, favorite)
+ }
+
+ override suspend fun deleteConversation(
+ userId: Long,
+ conversationId: String
+ ) {
+ nextcloudTalkDatabase.conversationsDao()
+ .deleteConversation(userId, conversationId)
+ }
+
+ override fun getConversationsForUser(user: UserEntity): LiveData> {
+ return nextcloudTalkDatabase.conversationsDao()
+ .getConversationsForUser(user.id)
+ .map { data ->
+ data.map {
+ it.toConversation()
+ }
+ }
+ }
+
+ internal fun getDatabase(): TalkDatabase {
+ return nextcloudTalkDatabase
+ }
+
+ override suspend fun clearConversationsForUser(user: UserEntity) {
+ nextcloudTalkDatabase.conversationsDao()
+ .clearConversationsForUser(user.id)
+ }
+
+ override suspend fun saveConversationsForUser(
+ user: UserEntity,
+ conversations: List
+ ) {
+ nextcloudTalkDatabase.conversationsDao()
+ .updateConversationsForUser(
+ user.id,
+ conversations.map {
+ it.toConversationEntity()
+ }.toTypedArray()
+ )
+ }
+
+ override suspend fun deleteConversationForUserWithTimestamp(
+ user: UserEntity,
+ timestamp: Long
+ ) {
+ nextcloudTalkDatabase.conversationsDao()
+ .deleteConversationsForUserWithTimestamp(user.id, timestamp)
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/NextcloudTalkRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/NextcloudTalkRepositoryImpl.kt
index d4b7fedac..a5e41df68 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/repository/NextcloudTalkRepositoryImpl.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/repository/NextcloudTalkRepositoryImpl.kt
@@ -33,15 +33,21 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
user: UserEntity,
conversation: Conversation
): GenericOverall {
- return apiService.deleteConversation(user.getCredentials(), ApiUtils.getRoom(user.baseUrl, conversation.token))
+ return apiService.deleteConversation(
+ user.getCredentials(), ApiUtils.getRoom(user.baseUrl, conversation.token)
+ )
}
override suspend fun leaveConversationForUser(
user: UserEntity,
conversation: Conversation
): GenericOverall {
- return apiService.leaveConversation(user.getCredentials(), ApiUtils.getUrlForRemoveSelfFromRoom(user
- .baseUrl, conversation.token))
+ return apiService.leaveConversation(
+ user.getCredentials(), ApiUtils.getUrlForRemoveSelfFromRoom(
+ user
+ .baseUrl, conversation.token
+ )
+ )
}
override suspend fun setFavoriteValueForConversation(
@@ -66,6 +72,7 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
return apiService.getConversations(
user.getCredentials(),
ApiUtils.getUrlForGetRooms(user.baseUrl)
- ).ocs.data
+ )
+ .ocs.data
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt b/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
index 5807d9fad..fd731b9c2 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/data/source/remote/ApiService.kt
@@ -22,7 +22,6 @@ package com.nextcloud.talk.newarch.data.source.remote
import com.nextcloud.talk.models.json.conversations.RoomsOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
-import io.reactivex.Observable
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt
index cfd3548c2..2a7882fbc 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/di/module/NetworkModule.kt
@@ -31,7 +31,6 @@ import com.nextcloud.talk.newarch.data.repository.NextcloudTalkRepositoryImpl
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
import com.nextcloud.talk.newarch.data.source.remote.ApiService
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository
-import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.utils.NetworkUtils
import com.nextcloud.talk.newarch.utils.NetworkUtils.GetProxyRunnable
import com.nextcloud.talk.newarch.utils.NetworkUtils.MagicAuthenticator
@@ -81,6 +80,7 @@ val NetworkModule = module {
single { createOkHttpClient(androidContext(), get(), get(), get(), get(), get(), get(), get()) }
factory { createApiErrorHandler() }
single { createNextcloudTalkRepository(get()) }
+
}
fun createCookieManager(): CookieManager {
@@ -253,10 +253,3 @@ fun createService(retrofit: Retrofit): ApiService {
fun createNextcloudTalkRepository(apiService: ApiService): NextcloudTalkRepository {
return NextcloudTalkRepositoryImpl(apiService)
}
-
-fun createGetConversationsUseCase(
- nextcloudTalkRepository: NextcloudTalkRepository,
- apiErrorHandler: ApiErrorHandler
-): GetConversationsUseCase {
- return GetConversationsUseCase(nextcloudTalkRepository, apiErrorHandler)
-}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/di/module/StorageModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/di/module/StorageModule.kt
index e3bf510bf..cbd013175 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/di/module/StorageModule.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/di/module/StorageModule.kt
@@ -21,8 +21,12 @@
package com.nextcloud.talk.newarch.di.module
import android.content.Context
+import androidx.room.Room
import com.nextcloud.talk.R.string
import com.nextcloud.talk.models.database.Models
+import com.nextcloud.talk.newarch.data.repository.NextcloudTalkOfflineRepositoryImpl
+import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository
+import com.nextcloud.talk.newarch.local.db.TalkDatabase
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.preferences.AppPreferences
import io.requery.Persistable
@@ -31,6 +35,7 @@ import io.requery.reactivex.ReactiveEntityStore
import io.requery.reactivex.ReactiveSupport
import io.requery.sql.EntityDataStore
import net.orange_box.storebox.StoreBox
+import org.koin.android.ext.koin.androidApplication
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
@@ -39,6 +44,21 @@ val StorageModule = module {
single { createSqlCipherDatabaseSource(androidContext()) }
single { createDataStore(get()) }
single { createUserUtils(get()) }
+ single { createNextcloudTalkOfflineRepository(get()) }
+ single { TalkDatabase.getInstance(androidApplication()) }
+ single { get().conversationsDao() }
+}
+
+fun createNextcloudTalkOfflineRepository(database: TalkDatabase): NextcloudTalkOfflineRepository {
+ return NextcloudTalkOfflineRepositoryImpl(database)
+}
+
+fun createDatabase(context: Context): TalkDatabase {
+ return Room.databaseBuilder(
+ context,
+ TalkDatabase::class.java, "talk.db"
+ )
+ .build()
}
fun createPreferences(context: Context): AppPreferences {
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkOfflineRepository.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkOfflineRepository.kt
new file mode 100644
index 000000000..e71d24df0
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkOfflineRepository.kt
@@ -0,0 +1,56 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.domain.repository
+
+import androidx.lifecycle.LiveData
+import com.nextcloud.talk.models.database.UserEntity
+import com.nextcloud.talk.models.json.conversations.Conversation
+
+interface NextcloudTalkOfflineRepository {
+ fun getConversationsForUser(user: UserEntity): LiveData>
+ suspend fun clearConversationsForUser(user: UserEntity)
+ suspend fun saveConversationsForUser(
+ user: UserEntity,
+ conversations: List
+ )
+
+ suspend fun setChangingValueForConversation(
+ userId: Long,
+ conversationId: String,
+ changing: Boolean
+ )
+
+ suspend fun setFavoriteValueForConversation(
+ userId: Long,
+ conversationId: String,
+ favorite: Boolean
+ )
+
+ suspend fun deleteConversation(
+ userId: Long,
+ conversationId: String
+ )
+
+ suspend fun deleteConversationForUserWithTimestamp(
+ user: UserEntity,
+ timestamp: Long
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkRepository.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkRepository.kt
index 7987d1b56..7aed61f6f 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkRepository.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/repository/NextcloudTalkRepository.kt
@@ -30,7 +30,15 @@ interface NextcloudTalkRepository {
user: UserEntity,
conversation: Conversation,
favorite: Boolean
- ) : GenericOverall
- suspend fun deleteConversationForUser(user: UserEntity, conversation: Conversation) : GenericOverall
- suspend fun leaveConversationForUser(userEntity: UserEntity, conversation: Conversation) : GenericOverall
+ ): GenericOverall
+
+ suspend fun deleteConversationForUser(
+ user: UserEntity,
+ conversation: Conversation
+ ): GenericOverall
+
+ suspend fun leaveConversationForUser(
+ userEntity: UserEntity,
+ conversation: Conversation
+ ): GenericOverall
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/base/UseCaseResponse.kt b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/base/UseCaseResponse.kt
index 2c33f963f..73cb26898 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/base/UseCaseResponse.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/domain/usecases/base/UseCaseResponse.kt
@@ -23,7 +23,7 @@ package com.nextcloud.talk.newarch.domain.usecases.base
import com.nextcloud.talk.newarch.data.model.ErrorModel
interface UseCaseResponse {
- fun onSuccess(result: Type)
+ suspend fun onSuccess(result: Type)
fun onError(errorModel: ErrorModel?)
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt
index 66b35e6a6..d2ccf64e8 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationListViewModelFactory.kt
@@ -23,6 +23,7 @@ package com.nextcloud.talk.newarch.features.conversationsList
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
@@ -32,15 +33,18 @@ import com.nextcloud.talk.utils.database.user.UserUtils
class ConversationListViewModelFactory constructor(
private val application: Application,
private val conversationsUseCase: GetConversationsUseCase,
- private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
+ private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
private val leaveConversationUseCase: LeaveConversationUseCase,
private val deleteConversationUseCase: DeleteConversationUseCase,
- private val userUtils: UserUtils
+ private val userUtils: UserUtils,
+ private val offlineRepository: NextcloudTalkOfflineRepository
) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
- return ConversationsListViewModel(application, conversationsUseCase,
+ return ConversationsListViewModel(
+ application, conversationsUseCase,
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
- userUtils) as T
+ userUtils, offlineRepository
+ ) as T
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
index 6d9547ab9..f378cbbb0 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListView.kt
@@ -75,6 +75,7 @@ import kotlinx.android.synthetic.main.view_states.view.errorStateImageView
import kotlinx.android.synthetic.main.view_states.view.errorStateTextView
import kotlinx.android.synthetic.main.view_states.view.loadingStateView
import kotlinx.android.synthetic.main.view_states.view.stateWithMessageView
+import org.apache.commons.lang3.builder.CompareToBuilder
import org.koin.android.ext.android.inject
import org.parceler.Parcels
import java.util.ArrayList
@@ -180,6 +181,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
container: ViewGroup
): View {
setHasOptionsMenu(true)
+ actionBar?.show()
viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java)
viewModel.apply {
@@ -243,10 +245,29 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
}
})
- conversationsLiveListData.observe(this@ConversationsListView, Observer {
+ conversationsLiveData.observe(this@ConversationsListView, Observer {
+ if (it.size == 0) {
+ viewState.value = LOADED_EMPTY
+ } else {
+ viewState.value = LOADED
+ }
+ val sortedConversationsList = it.toMutableList()
+
+ sortedConversationsList.sortWith(Comparator { conversation1, conversation2 ->
+ CompareToBuilder()
+ .append(conversation2.favorite, conversation1.favorite)
+ .append(conversation2.lastActivity, conversation1.lastActivity)
+ .toComparison()
+ })
+
val newConversations = mutableListOf()
- for (conversation in it) {
- newConversations.add(ConversationItem(conversation, viewModel.currentUser, activity))
+ for (conversation in sortedConversationsList) {
+ newConversations.add(
+ ConversationItem(
+ conversation, viewModel.currentUserLiveData.value,
+ activity
+ )
+ )
}
recyclerViewAdapter.updateDataSet(newConversations as List>?)
@@ -313,7 +334,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
var displayName =
(recyclerViewAdapter.getItem(position) as ConversationItem).model.displayName
- if (displayName.length > 8) {
+ if (displayName!!.length > 8) {
displayName = displayName.substring(0, 4) + "..."
}
@@ -394,12 +415,12 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
val conversation = (clickedItem as ConversationItem).model
val bundle = Bundle()
- bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, viewModel.currentUser)
+ bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, viewModel.currentUserLiveData.value)
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, conversation.token)
bundle.putString(BundleKeys.KEY_ROOM_ID, conversation.conversationId)
bundle.putParcelable(BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation))
ConductorRemapping.remapChatController(
- router, viewModel.currentUser.id, conversation.token,
+ router, viewModel.currentUserLiveData.value!!.id, conversation!!.token!!,
bundle, false
)
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
index c2f3550b8..0968d52ec 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/ConversationsListViewModel.kt
@@ -26,6 +26,7 @@ import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Transformations
import androidx.lifecycle.viewModelScope
import com.facebook.common.executors.UiThreadImmediateExecutorService
import com.facebook.common.references.CloseableReference
@@ -42,22 +43,19 @@ import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
import com.nextcloud.talk.newarch.data.model.ErrorModel
+import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.utils.ViewState
-import com.nextcloud.talk.newarch.utils.ViewState.FAILED
-import com.nextcloud.talk.newarch.utils.ViewState.INITIAL_LOAD
-import com.nextcloud.talk.newarch.utils.ViewState.LOADED
-import com.nextcloud.talk.newarch.utils.ViewState.LOADED_EMPTY
import com.nextcloud.talk.newarch.utils.ViewState.LOADING
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.ShareUtils
import com.nextcloud.talk.utils.database.user.UserUtils
-import org.apache.commons.lang3.builder.CompareToBuilder
+import kotlinx.coroutines.launch
import org.koin.core.parameter.parametersOf
class ConversationsListViewModel constructor(
@@ -66,15 +64,18 @@ class ConversationsListViewModel constructor(
private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
private val leaveConversationUseCase: LeaveConversationUseCase,
private val deleteConversationUseCase: DeleteConversationUseCase,
- private val userUtils: UserUtils
+ private val userUtils: UserUtils,
+ private val offlineRepository: NextcloudTalkOfflineRepository
) : BaseViewModel(application) {
- private var conversations: MutableList = mutableListOf()
- val conversationsLiveListData = MutableLiveData>()
- val viewState = MutableLiveData(INITIAL_LOAD)
+ val viewState = MutableLiveData(LOADING)
var messageData: String? = null
val searchQuery = MutableLiveData()
- var currentUser: UserEntity = userUtils.currentUser
+ val currentUserLiveData: MutableLiveData = MutableLiveData()
+ val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
+ offlineRepository.getConversationsForUser(it)
+ }
+
var currentUserAvatar: MutableLiveData = MutableLiveData()
get() {
if (field.value == null) {
@@ -85,47 +86,52 @@ class ConversationsListViewModel constructor(
}
fun leaveConversation(conversation: Conversation) {
- setConversationUpdateStatus(conversation, true)
-
- leaveConversationUseCase.invoke(viewModelScope, parametersOf(currentUser, conversation),
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, true)
+ }
+ leaveConversationUseCase.invoke(viewModelScope, parametersOf(
+ currentUserLiveData.value,
+ conversation
+ ),
object : UseCaseResponse {
- override fun onSuccess(result: GenericOverall) {
- // TODO: Use binary search to find the right room
- conversations.find { it.conversationId == conversation.conversationId }
- ?.let {
- conversations.remove(it)
- conversationsLiveListData.value = conversations
- if (conversations.isEmpty()) {
- viewState.value = LOADED_EMPTY
- }
- }
+ override suspend fun onSuccess(result: GenericOverall) {
+ offlineRepository.deleteConversation(
+ currentUserLiveData.value!!.id, conversation
+ .conversationId
+ )
}
override fun onError(errorModel: ErrorModel?) {
- setConversationUpdateStatus(conversation, false)
+ messageData = errorModel?.getErrorMessage()
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, false)
+ }
}
})
}
fun deleteConversation(conversation: Conversation) {
- setConversationUpdateStatus(conversation, true)
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, true)
+ }
- deleteConversationUseCase.invoke(viewModelScope, parametersOf(currentUser, conversation),
+ deleteConversationUseCase.invoke(viewModelScope, parametersOf(
+ currentUserLiveData.value,
+ conversation
+ ),
object : UseCaseResponse {
- override fun onSuccess(result: GenericOverall) {
- // TODO: Use binary search to find the right room
- conversations.find { it.conversationId == conversation.conversationId }
- ?.let {
- conversations.remove(it)
- conversationsLiveListData.value = conversations
- if (conversations.isEmpty()) {
- viewState.value = LOADED_EMPTY
- }
- }
+ override suspend fun onSuccess(result: GenericOverall) {
+ offlineRepository.deleteConversation(
+ currentUserLiveData.value!!.id, conversation
+ .conversationId
+ )
}
override fun onError(errorModel: ErrorModel?) {
- setConversationUpdateStatus(conversation, false)
+ messageData = errorModel?.getErrorMessage()
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, false)
+ }
}
})
@@ -135,74 +141,63 @@ class ConversationsListViewModel constructor(
conversation: Conversation,
favorite: Boolean
) {
- setConversationUpdateStatus(conversation, true)
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, true)
+ }
setConversationFavoriteValueUseCase.invoke(viewModelScope, parametersOf(
- currentUser,
+ currentUserLiveData.value,
conversation,
favorite
),
object : UseCaseResponse {
- override fun onSuccess(result: GenericOverall) {
- // TODO: Use binary search to find the right room
- conversations.find { it.conversationId == conversation.conversationId }
- ?.apply {
- updating = false
- isFavorite = favorite
- conversationsLiveListData.value = conversations
- }
+ override suspend fun onSuccess(result: GenericOverall) {
+ offlineRepository.setFavoriteValueForConversation(
+ currentUserLiveData.value!!.id,
+ conversation.conversationId, favorite
+ )
}
override fun onError(errorModel: ErrorModel?) {
- setConversationUpdateStatus(conversation, false)
+ messageData = errorModel?.getErrorMessage()
+ viewModelScope.launch {
+ setConversationUpdateStatus(conversation, false)
+ }
}
})
}
fun loadConversations() {
- val userChanged = !currentUser.equals(userUtils.currentUser)
+ val userChanged = !(currentUserLiveData.value?.equals(userUtils.currentUser) ?: false)
if (userChanged) {
- currentUser = userUtils.currentUser
- }
-
- if ((FAILED).equals(viewState.value) || (LOADED_EMPTY).equals(viewState.value) ||
- (INITIAL_LOAD).equals(viewState.value) || !currentUser.equals(userUtils.currentUser) || userChanged
- ) {
+ currentUserLiveData.value = userUtils.currentUser
viewState.value = LOADING
}
- getConversationsUseCase.invoke(
- viewModelScope, parametersOf(currentUser), object : UseCaseResponse> {
- override fun onSuccess(result: List) {
- val newConversations = result.toMutableList()
+ getConversationsUseCase.invoke(viewModelScope, parametersOf(currentUserLiveData.value), object :
+ UseCaseResponse> {
+ override suspend fun onSuccess(result: List) {
+ val mutableList = result.toMutableList()
+ mutableList.forEach {
+ it.user = currentUserLiveData.value!!.id
+ }
- newConversations.sortWith(Comparator { conversation1, conversation2 ->
- CompareToBuilder()
- .append(conversation2.isFavorite, conversation1.isFavorite)
- .append(conversation2.lastActivity, conversation1.lastActivity)
- .toComparison()
- })
-
- conversations = newConversations
- conversationsLiveListData.value = conversations
- viewState.value = if (newConversations.isNotEmpty()) LOADED else LOADED_EMPTY
+ offlineRepository.saveConversationsForUser(currentUserLiveData.value!!, mutableList)
messageData = ""
}
override fun onError(errorModel: ErrorModel?) {
messageData = errorModel?.getErrorMessage()
- viewState.value = FAILED
}
-
})
}
fun loadAvatar(avatarSize: Int) {
val imageRequest = DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatarWithNameAndPixels(
- currentUser.baseUrl,
- currentUser.userId, avatarSize
+ currentUserLiveData.value!!.baseUrl,
+ currentUserLiveData.value!!.userId, avatarSize
), null
)
@@ -257,7 +252,7 @@ class ConversationsListViewModel constructor(
fun getConversationMenuItemsForConversation(conversation: Conversation): MutableList {
val items = mutableListOf()
- if (conversation.isFavorite) {
+ if (conversation.favorite) {
items.add(
BasicListItemWithImage(
drawable.ic_star_border_black_24dp,
@@ -282,7 +277,7 @@ class ConversationsListViewModel constructor(
)
}
- if (conversation.canLeave(currentUser)) {
+ if (conversation.canLeave(currentUserLiveData.value!!)) {
items.add(
BasicListItemWithImage(
drawable.ic_exit_to_app_black_24dp, context.getString
@@ -291,7 +286,7 @@ class ConversationsListViewModel constructor(
)
}
- if (conversation.canModerate(currentUser)) {
+ if (conversation.canModerate(currentUserLiveData.value!!)) {
items.add(
BasicListItemWithImage(
drawable.ic_delete_grey600_24dp, context.getString(
@@ -304,14 +299,13 @@ class ConversationsListViewModel constructor(
return items
}
- private fun setConversationUpdateStatus(
+ private suspend fun setConversationUpdateStatus(
conversation: Conversation,
value: Boolean
) {
- conversations.find { it.conversationId == conversation.conversationId }
- ?.apply {
- updating = value
- conversationsLiveListData.value = conversations
- }
+ offlineRepository.setChangingValueForConversation(
+ currentUserLiveData.value!!.id, conversation
+ .conversationId, value
+ )
}
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt
index bf5c2e96b..a92292f3e 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/features/conversationsList/di/module/ConversationsListModule.kt
@@ -22,6 +22,7 @@ package com.nextcloud.talk.newarch.features.conversationsList.di.module
import android.app.Application
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
+import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkOfflineRepository
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
@@ -41,7 +42,7 @@ val ConversationsListModule = module {
factory {
createConversationListViewModelFactory(
androidApplication(), get(), get(), get(), get
- (), get()
+ (), get(), get()
)
}
}
@@ -81,11 +82,12 @@ fun createConversationListViewModelFactory(
setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
leaveConversationUseCase: LeaveConversationUseCase,
deleteConversationUseCase: DeleteConversationUseCase,
- userUtils: UserUtils
+ userUtils: UserUtils,
+ offlineRepository: NextcloudTalkOfflineRepository
): ConversationListViewModelFactory {
return ConversationListViewModelFactory(
application, getConversationsUseCase,
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
- userUtils
+ userUtils, offlineRepository
)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ChatMessageConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ChatMessageConverter.kt
new file mode 100644
index 000000000..02809b946
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ChatMessageConverter.kt
@@ -0,0 +1,41 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.bluelinelabs.logansquare.LoganSquare
+import com.nextcloud.talk.models.json.chat.ChatMessage
+
+class ChatMessageConverter {
+ @TypeConverter
+ fun fromChatMessageToString(chatMessage: ChatMessage?): String {
+ if (chatMessage == null) {
+ return ""
+ } else {
+ return LoganSquare.serialize(chatMessage)
+ }
+ }
+
+ @TypeConverter
+ fun fromStringToChatMessage(value: String): ChatMessage? {
+ return LoganSquare.parse(value, ChatMessage::class.java)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt
new file mode 100644
index 000000000..4a0572113
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationReadOnlyStateConverter.kt
@@ -0,0 +1,42 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationReadOnlyState
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationReadOnlyState.CONVERSATION_READ_WRITE
+
+class ConversationReadOnlyStateConverter {
+ @TypeConverter
+ fun fromConversationReadOnlyStateToInt(conversationReadOnlyState: ConversationReadOnlyState):
+ Int {
+ return conversationReadOnlyState.ordinal
+ }
+
+ @TypeConverter
+ fun fromIntToConversationType(value: Int): ConversationReadOnlyState {
+ when (value) {
+ 0 -> return CONVERSATION_READ_WRITE
+ else -> return CONVERSATION_READ_ONLY
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationTypeConverter.kt
new file mode 100644
index 000000000..c5de80f54
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ConversationTypeConverter.kt
@@ -0,0 +1,45 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.GROUP_CONVERSATION
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.PUBLIC_CONVERSATION
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.SYSTEM_CONVERSATION
+
+class ConversationTypeConverter {
+ @TypeConverter
+ fun fromConversationTypeToInt(conversationType: ConversationType): Int {
+ return conversationType.value
+ }
+
+ @TypeConverter
+ fun fromIntToConversationType(value: Int): ConversationType {
+ when (value) {
+ 1 -> return ONE_TO_ONE_CONVERSATION
+ 2 -> return GROUP_CONVERSATION
+ 3 -> return PUBLIC_CONVERSATION
+ else -> return SYSTEM_CONVERSATION
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/LobbyStateConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/LobbyStateConverter.kt
new file mode 100644
index 000000000..d59523701
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/LobbyStateConverter.kt
@@ -0,0 +1,39 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.nextcloud.talk.models.json.conversations.Conversation.LobbyState
+
+class LobbyStateConverter {
+ @TypeConverter
+ fun fromLobbyStateToInt(lobbyState: LobbyState): Int {
+ return lobbyState.ordinal
+ }
+
+ @TypeConverter
+ fun fromIntToLobbyState(value: Int): LobbyState {
+ when (value) {
+ 0 -> return LobbyState.LOBBY_STATE_ALL_PARTICIPANTS
+ else -> return LobbyState.LOBBY_STATE_ALL_PARTICIPANTS
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/NotificationLevelConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/NotificationLevelConverter.kt
new file mode 100644
index 000000000..303f34264
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/NotificationLevelConverter.kt
@@ -0,0 +1,45 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel.ALWAYS
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel.DEFAULT
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel.MENTION
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel.NEVER
+
+class NotificationLevelConverter {
+ @TypeConverter
+ fun fromNotificationLevelToInt(notificationLevel: NotificationLevel): Int {
+ return notificationLevel.ordinal
+ }
+
+ @TypeConverter
+ fun fromIntToNotificationLevel(value: Int): NotificationLevel {
+ when (value) {
+ 0 -> return DEFAULT
+ 1 -> return ALWAYS
+ 2 -> return MENTION
+ else -> return NEVER
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt
new file mode 100644
index 000000000..f051fc2b1
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/converters/ParticipantTypeConverter.kt
@@ -0,0 +1,50 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.converters
+
+import androidx.room.TypeConverter
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.DUMMY
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.GUEST
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.MODERATOR
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.OWNER
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.USER
+import com.nextcloud.talk.models.json.participants.Participant.ParticipantType.USER_FOLLOWING_LINK
+
+class ParticipantTypeConverter {
+ @TypeConverter
+ fun fromParticipantType(participantType: ParticipantType): Int {
+ return participantType.ordinal
+ }
+
+ @TypeConverter
+ fun fromIntToParticipantType(value: Int): ParticipantType {
+ when (value) {
+ 0 -> return DUMMY
+ 1 -> return OWNER
+ 2 -> return MODERATOR
+ 3 -> return USER
+ 4 -> return GUEST
+ else -> return USER_FOLLOWING_LINK
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt
new file mode 100644
index 000000000..11a5747b4
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/dao/ConversationsDao.kt
@@ -0,0 +1,103 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.dao
+
+import androidx.lifecycle.LiveData
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import com.nextcloud.talk.newarch.local.models.ConversationEntity
+
+@Dao
+abstract class ConversationsDao {
+ @Query("SELECT * FROM conversations WHERE user = :userId")
+ abstract fun getConversationsForUser(userId: Long): LiveData>
+
+ @Query("DELETE FROM conversations WHERE user = :userId")
+ abstract suspend fun clearConversationsForUser(userId: Long)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ abstract suspend fun saveConversation(conversation: ConversationEntity)
+
+ suspend fun saveConversationWithTimestamp(conversation: ConversationEntity) {
+ saveConversation(conversation.apply {
+ modifiedAt = System.currentTimeMillis()
+ })
+ }
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ abstract suspend fun saveConversations(vararg conversations: ConversationEntity)
+
+ @Query(
+ "UPDATE conversations SET changing = :changing WHERE user = :userId AND " +
+ "'conversation_id' = :conversationId"
+ )
+ abstract suspend fun updateChangingValueForConversation(
+ userId: Long,
+ conversationId: String,
+ changing: Boolean
+ )
+
+ @Query(
+ "UPDATE conversations SET favorite = :favorite, changing = 0 WHERE user = :userId AND 'conversation_id' = :conversationId"
+ )
+ abstract suspend fun updateFavoriteValueForConversation(
+ userId: Long,
+ conversationId: String,
+ favorite: Boolean
+ )
+
+ @Query("DELETE FROM conversations WHERE user = :userId AND 'conversation_id' = :conversationId")
+ abstract suspend fun deleteConversation(
+ userId: Long,
+ conversationId: String
+ )
+
+ @Delete
+ abstract suspend fun deleteConversations(vararg conversation: ConversationEntity)
+
+ @Query("DELETE FROM conversations WHERE user = :userId AND 'modified_at' < :timestamp")
+ abstract suspend fun deleteConversationsForUserWithTimestamp(
+ userId: Long,
+ timestamp: Long
+ )
+
+ @Transaction
+ open suspend fun updateConversationsForUser(
+ userId: Long,
+ newConversations:
+ Array
+ ) {
+ val timestamp = System.currentTimeMillis()
+
+ val conversationsWithTimestampApplied = newConversations.map {
+ it.modifiedAt = System.currentTimeMillis()
+ it
+ }
+ .toTypedArray()
+
+ saveConversations(*conversationsWithTimestampApplied)
+ deleteConversationsForUserWithTimestamp(userId, timestamp)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt
new file mode 100644
index 000000000..b84afa16c
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/db/TalkDatabase.kt
@@ -0,0 +1,63 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.db
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import com.nextcloud.talk.newarch.local.converters.ChatMessageConverter
+import com.nextcloud.talk.newarch.local.converters.ConversationReadOnlyStateConverter
+import com.nextcloud.talk.newarch.local.converters.ConversationTypeConverter
+import com.nextcloud.talk.newarch.local.converters.LobbyStateConverter
+import com.nextcloud.talk.newarch.local.converters.NotificationLevelConverter
+import com.nextcloud.talk.newarch.local.converters.ParticipantTypeConverter
+import com.nextcloud.talk.newarch.local.dao.ConversationsDao
+import com.nextcloud.talk.newarch.local.models.ConversationEntity
+
+@Database(entities = arrayOf(ConversationEntity::class), version = 1)
+@TypeConverters(
+ ChatMessageConverter::class, LobbyStateConverter::class,
+ ConversationReadOnlyStateConverter::class, NotificationLevelConverter::class,
+ ConversationTypeConverter::class, ParticipantTypeConverter::class
+)
+
+abstract class TalkDatabase : RoomDatabase() {
+
+ abstract fun conversationsDao(): ConversationsDao
+
+ companion object {
+ private const val DB_NAME = "talk.db"
+ @Volatile
+ private var INSTANCE: TalkDatabase? = null
+
+ fun getInstance(context: Context): TalkDatabase =
+ INSTANCE ?: synchronized(this) {
+ INSTANCE ?: build(context).also { INSTANCE = it }
+ }
+
+ private fun build(context: Context) =
+ Room.databaseBuilder(context.applicationContext, TalkDatabase::class.java, DB_NAME)
+ .build()
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
new file mode 100644
index 000000000..9b8baa341
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/newarch/local/models/ConversationEntity.kt
@@ -0,0 +1,130 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.newarch.local.models
+
+import androidx.annotation.NonNull
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import com.nextcloud.talk.models.json.chat.ChatMessage
+import com.nextcloud.talk.models.json.conversations.Conversation
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationReadOnlyState
+import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType
+import com.nextcloud.talk.models.json.conversations.Conversation.LobbyState
+import com.nextcloud.talk.models.json.conversations.Conversation.NotificationLevel
+import com.nextcloud.talk.models.json.participants.Participant
+import java.util.HashMap
+
+@Entity(tableName = "conversations", primaryKeys = ["user", "conversation_id"])
+data class ConversationEntity(
+ @NonNull @ColumnInfo(name = "user") var userId: Long,
+ @NonNull @ColumnInfo(name = "conversation_id") var conversationId: String,
+ @ColumnInfo(name = "token") var token: String? = null,
+ @ColumnInfo(name = "name") var name: String? = null,
+ @ColumnInfo(name = "display_name") var displayName: String? = null,
+ @ColumnInfo(name = "type") var type: ConversationType? = null,
+ @ColumnInfo(name = "count") var count: Long = 0,
+ @ColumnInfo(name = "number_of_guests") var numberOfGuests: Long = 0,
+ /*@ColumnInfo(name = "guest_list") var guestList: HashMap>? = null,
+ @ColumnInfo(name = "participants") var participants: HashMap>? =
+ null,
+ */
+ // hack for participants list
+ @ColumnInfo(name = "participants_count") var participantsCount: Int = 0,
+ @ColumnInfo(name = "participant_type") var participantType: Participant.ParticipantType? = null,
+ @ColumnInfo(name = "has_password") var hasPassword: Boolean = false,
+ @ColumnInfo(name = "session_id") var sessionId: String? = null,
+ @ColumnInfo(name = "favorite") var favorite: Boolean = false,
+ @ColumnInfo(name = "last_activity") var lastActivity: Long = 0,
+ @ColumnInfo(name = "unread_messages") var unreadMessages: Int = 0,
+ @ColumnInfo(name = "unread_mention") var unreadMention: Boolean = false,
+ @ColumnInfo(name = "last_message") var lastMessage: ChatMessage? = null,
+ @ColumnInfo(name = "object_type") var objectType: String? = null,
+ @ColumnInfo(name = "notification_level") var notificationLevel: NotificationLevel? = null,
+ @ColumnInfo(
+ name = "read_only_state"
+ ) var conversationReadOnlyState: ConversationReadOnlyState? = null,
+ @ColumnInfo(name = "lobby_state") var lobbyState: LobbyState? = null,
+ @ColumnInfo(name = "lobby_timer") var lobbyTimer: Long? = null,
+ @ColumnInfo(name = "last_read_message_id") var lastReadMessageId: Int = 0,
+ @ColumnInfo(name = "modified_at") var modifiedAt: Long? = null,
+ @ColumnInfo(name = "changing") var changing: Boolean = false
+)
+
+fun ConversationEntity.toConversation(): Conversation {
+ val conversation = Conversation()
+ conversation.user = this.userId
+ conversation.conversationId = this.conversationId
+ conversation.type = this.type
+ conversation.token = this.token
+ conversation.name = this.name
+ conversation.displayName = this.displayName
+ conversation.count = this.count
+ conversation.numberOfGuests = this.numberOfGuests
+ conversation.participants = HashMap()
+ for (i in 0 until participantsCount) {
+ conversation.participants?.put(i.toString(), HashMap())
+ }
+ conversation.participantType = this.participantType
+ conversation.hasPassword = this.hasPassword
+ conversation.sessionId = this.sessionId
+ conversation.favorite = this.favorite
+ conversation.lastActivity = this.lastActivity
+ conversation.unreadMessages = this.unreadMessages
+ conversation.unreadMention = this.unreadMention
+ conversation.lastMessage = this.lastMessage
+ conversation.objectType = this.objectType
+ conversation.notificationLevel = this.notificationLevel
+ conversation.conversationReadOnlyState = this.conversationReadOnlyState
+ conversation.lobbyState = this.lobbyState
+ conversation.lobbyTimer = this.lobbyTimer
+ conversation.lastReadMessageId = this.lastReadMessageId
+ conversation.changing = this.changing
+
+ return conversation
+}
+
+fun Conversation.toConversationEntity(): ConversationEntity {
+ val conversationEntity = ConversationEntity(this.user, this.conversationId)
+ conversationEntity.token = this.token
+ conversationEntity.name = this.name
+ conversationEntity.displayName = this.displayName
+ conversationEntity.count = this.count
+ conversationEntity.numberOfGuests = this.numberOfGuests
+ conversationEntity.participantsCount = this.participants?.size ?: 0
+ conversationEntity.participantType = this.participantType
+ conversationEntity.hasPassword = this.hasPassword
+ conversationEntity.sessionId = this.sessionId
+ conversationEntity.favorite = this.favorite
+ conversationEntity.lastActivity = this.lastActivity
+ conversationEntity.unreadMessages = this.unreadMessages
+ conversationEntity.unreadMention = this.unreadMention
+ conversationEntity.lastMessage = this.lastMessage
+ conversationEntity.objectType = this.objectType
+ conversationEntity.notificationLevel = this.notificationLevel
+ conversationEntity.conversationReadOnlyState = this.conversationReadOnlyState
+ conversationEntity.lobbyState = this.lobbyState
+ conversationEntity.lobbyTimer = this.lobbyTimer
+ conversationEntity.lastReadMessageId = this.lastReadMessageId
+ conversationEntity.type = this.type
+ conversationEntity.changing = this.changing
+
+ return conversationEntity
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/Extensions.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/Extensions.kt
index eeca61937..474e583c2 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/utils/Extensions.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/Extensions.kt
@@ -23,4 +23,4 @@ package com.nextcloud.talk.newarch.utils
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.utils.ApiUtils
-fun UserEntity.getCredentials() = ApiUtils.getCredentials(username, token)
\ No newline at end of file
+fun UserEntity.getCredentials() = ApiUtils.getCredentials(username, token)
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/NetworkUtils.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/NetworkUtils.kt
index 95b5a4373..7c658071e 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/utils/NetworkUtils.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/NetworkUtils.kt
@@ -83,7 +83,8 @@ class NetworkUtils {
return null
}
}
- return response.request().newBuilder()
+ return response.request()
+ .newBuilder()
.header(authenticatorType, credentials)
.build()
}
diff --git a/app/src/main/java/com/nextcloud/talk/newarch/utils/ViewState.kt b/app/src/main/java/com/nextcloud/talk/newarch/utils/ViewState.kt
index cf20d3080..23f996292 100644
--- a/app/src/main/java/com/nextcloud/talk/newarch/utils/ViewState.kt
+++ b/app/src/main/java/com/nextcloud/talk/newarch/utils/ViewState.kt
@@ -21,7 +21,6 @@
package com.nextcloud.talk.newarch.utils
enum class ViewState {
- INITIAL_LOAD,
LOADING,
LOADED_EMPTY,
LOADED,
diff --git a/app/src/main/res/layout/controller_conversations_rv.xml b/app/src/main/res/layout/controller_conversations_rv.xml
index 0038e77c9..102ee1793 100644
--- a/app/src/main/res/layout/controller_conversations_rv.xml
+++ b/app/src/main/res/layout/controller_conversations_rv.xml
@@ -24,42 +24,51 @@
android:id="@+id/generic_rv_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:animateLayoutChanges="true">
+ android:animateLayoutChanges="true"
+ >
-
+
-
+
+
+ android:visibility="invisible"
+ >
-
+
-
+
-
+
-
+
-
-
-
+
diff --git a/app/src/main/res/values-b+en+001/strings.xml b/app/src/main/res/values-b+en+001/strings.xml
index 457571a5f..b35445d77 100644
--- a/app/src/main/res/values-b+en+001/strings.xml
+++ b/app/src/main/res/values-b+en+001/strings.xml
@@ -88,7 +88,7 @@
Select an account
-
+
Start a conversation
Configure conversation
Leave conversation
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 579236190..293b51bb3 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -124,7 +124,7 @@
Selecciona un compte
-
+
Enceta una conversa
Configura la conversa
Surt de la conversa
diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml
index df02f32dc..bd3e34ee6 100644
--- a/app/src/main/res/values-cs-rCZ/strings.xml
+++ b/app/src/main/res/values-cs-rCZ/strings.xml
@@ -124,7 +124,7 @@
Vyberte účet
-
+
Začněte konverzaci
Nastavení konverzace
Opustit konverzaci
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 49d32b72d..f530004b6 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -124,7 +124,7 @@
Vælg konto
-
+
Start en samtale
Samtaleopsætning
Forlad samtale
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9b75de8b0..576f68a02 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -125,7 +125,7 @@
Konto auswählen
-
+
Starte eine Unterhaltung
Unterhaltung einrichten
Unterhaltung verlassen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 680a30972..4728d569a 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -93,7 +93,7 @@
Άδεια χρήσης
Επιλογή λογαριασμού
-
+
Έναρξη συνομιλίας
Ρύθμιση συνομιλίας
Εγκατάλειψη συνομιλίας
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 0a571604a..584574d72 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -124,7 +124,7 @@
Selecciona una cuenta
-
+
Comienza una conversación
Configura la conversación
Abandonar conversación
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 26dd1a81e..d0cfcf11e 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -124,7 +124,7 @@
Choisissez un compte
-
+
Commencer une conversation
Configurer la conversation
Quitter la conversation
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 3ae4ec987..f22d56306 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -127,7 +127,7 @@ Produciuse un fallo aorecuperar os axustes da sinalización
Seleccione unha conta
-
+
Iniciar unha conversa
Configurar a conversa
Abandonar a conversa
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 6e1bd0aa4..c322e2ff5 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -123,7 +123,7 @@
Odaberi račun
-
+
Započni razgovor
Konfiguriraj razgovor
Napusti razgovor
diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml
index 7db8f59d3..f6a323661 100644
--- a/app/src/main/res/values-hu-rHU/strings.xml
+++ b/app/src/main/res/values-hu-rHU/strings.xml
@@ -123,7 +123,7 @@
Válasszon fiókot
-
+
Beszélgetés indítása
Beszélgetés beállításai
Beszélgetés elhagyása
diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml
index 06f8b4b6a..9cbfd2ad9 100644
--- a/app/src/main/res/values-is/strings.xml
+++ b/app/src/main/res/values-is/strings.xml
@@ -110,7 +110,7 @@
Veldu aðgang
-
+
Hefja samtal
Stilla samtal
Hætta í samtali
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 506d1014f..85d0bd0c8 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -125,7 +125,7 @@
Seleziona account
-
+
Inizia una conversazione
Configura conversazione
Lascia la conversazione
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index 37a1c8d9e..461112f0a 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -103,7 +103,7 @@
בחירת חשבון
-
+
התחלת דיון
הגדרת דיון
יציאה מהדיון
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index 8707399c9..07b8f049c 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -124,7 +124,7 @@
アカウントを選択
-
+
会話を開始する
会話を構成する
会話を離れる
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 4fb349415..8263cd6c8 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -104,7 +104,7 @@
계정 선택
-
+
대화 시작
대화 설정
대화 나가기
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index affe95111..99a1673d9 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -93,7 +93,7 @@
Velg en konto
-
+
Start en samtale
Konfigurer samtale
Forlat samtale
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 6fd10647f..9dd98b13e 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -126,7 +126,7 @@ Kies er eentje van een provider.
Selecteer een account
-
+
Begin een gesprek
Configureren gesprek
Verlaat gesprek
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 822bfc36b..3ab69643e 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -125,7 +125,7 @@
Wybierz konto
-
+
Rozpocznij rozmowę
Konfiguruj rozmowę
Opuść rozmowę
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 6c0bc6d68..bd0ed66ee 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -125,7 +125,7 @@
Selecionar uma conta
-
+
Iniciar uma conversa
Configurar uma conversa
Sair da conversa
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 05bdfb24c..b150033b3 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -95,7 +95,7 @@
Selecionar uma conta
-
+
Iniciar uma conversação
Configurar conversação
Sair da conversação
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 0209cea4b..874684e25 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -124,7 +124,7 @@
Выберите учётную запись
-
+
Начать беседу
Настроить беседу
Покинуть беседу
diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml
index 8cb5b3c84..f0c8f77c3 100644
--- a/app/src/main/res/values-sk-rSK/strings.xml
+++ b/app/src/main/res/values-sk-rSK/strings.xml
@@ -123,7 +123,7 @@
Zvoľte si účet
-
+
Začať rozhovor
Nastavenia rozhovoru
Odísť z rozhovoru
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 141d81437..c1e376f4d 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -115,7 +115,7 @@
Izbor računa
-
+
Začni s pogovorom
Nastavitev pogovora
Zapusti pogovor
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 9baa52443..6c4afd20d 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -124,7 +124,7 @@
Изаберите налог
-
+
Започни разговор
Подеси разговор
Напусти разговор
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index ffc83ca4e..283fa509f 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -125,7 +125,7 @@
Välj ett konto
-
+
Starta en konversation
Anpassa konversation
Lämna konversationen
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 640f1101a..d349e251b 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -125,7 +125,7 @@
Bir hesap seçin
-
+
Yeni bir görüşme başlat
Görüşmeyi yapılandır
Görüşmeden ayrıl
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 6e0e66757..dcf27e1ee 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -83,7 +83,7 @@
Chọn một tài khoản
-
+
Bắt đầu một cuộc Đàm thoại
Cấu hình đàm thoại
Rời khỏi cuộc đàm thoại
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 0ca36e35f..ae102d93a 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -124,7 +124,7 @@
选择一个账户
-
+
发起会话
配置会话
离开会话
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 54e0ac190..1dc8e4a4e 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -99,7 +99,7 @@
選擇一個帳號
-
+
新對話
設定對話
結束對話
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e29e73483..98a01a533 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -144,7 +144,7 @@
Select an account
-
+
Start a conversation
Configure conversation
Leave conversation