mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 12:09:45 +01:00
More progress
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
b0c821462d
commit
2681e6ef24
@ -70,15 +70,18 @@ android {
|
|||||||
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
arguments = [
|
arguments = ["room.schemaLocation":
|
||||||
parcelerStacktrace: "true"
|
"$projectDir/schemas".toString()]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataBinding {
|
dataBinding {
|
||||||
enabled = true
|
enabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
androidExtensions {
|
||||||
|
experimental = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dexOptions {
|
dexOptions {
|
||||||
@ -109,6 +112,10 @@ android {
|
|||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
htmlReport true
|
htmlReport true
|
||||||
|
@ -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')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<CallItem.RoomItemViewHolder>
|
|
||||||
implements IFilterable<String> {
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -104,7 +104,7 @@ public class ConversationItem
|
|||||||
|
|
||||||
holder.dialogAvatar.setController(null);
|
holder.dialogAvatar.setController(null);
|
||||||
|
|
||||||
if (conversation.isUpdating()) {
|
if (conversation.getChanging()) {
|
||||||
holder.progressBar.setVisibility(View.VISIBLE);
|
holder.progressBar.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
holder.progressBar.setVisibility(View.GONE);
|
holder.progressBar.setVisibility(View.GONE);
|
||||||
@ -127,7 +127,7 @@ public class ConversationItem
|
|||||||
holder.dialogUnreadBubble.setText("99+");
|
holder.dialogUnreadBubble.setText("99+");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.isUnreadMention()) {
|
if (conversation.getUnreadMention()) {
|
||||||
holder.dialogUnreadBubble.setBackground(
|
holder.dialogUnreadBubble.setBackground(
|
||||||
context.getDrawable(R.drawable.bubble_circle_unread_mention));
|
context.getDrawable(R.drawable.bubble_circle_unread_mention));
|
||||||
} else {
|
} else {
|
||||||
@ -138,13 +138,13 @@ public class ConversationItem
|
|||||||
holder.dialogUnreadBubble.setVisibility(View.GONE);
|
holder.dialogUnreadBubble.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.isHasPassword()) {
|
if (conversation.getHasPassword()) {
|
||||||
holder.passwordProtectedRoomImageView.setVisibility(View.VISIBLE);
|
holder.passwordProtectedRoomImageView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
holder.passwordProtectedRoomImageView.setVisibility(View.GONE);
|
holder.passwordProtectedRoomImageView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.isFavorite()) {
|
if (conversation.getFavorite()) {
|
||||||
holder.pinnedConversationImageView.setVisibility(View.VISIBLE);
|
holder.pinnedConversationImageView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
holder.pinnedConversationImageView.setVisibility(View.GONE);
|
holder.pinnedConversationImageView.setVisibility(View.GONE);
|
||||||
@ -157,7 +157,7 @@ public class ConversationItem
|
|||||||
System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(conversation.getLastMessage().getSystemMessage())
|
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());
|
holder.dialogLastMessage.setText(conversation.getLastMessage().getText());
|
||||||
} else {
|
} else {
|
||||||
String authorDisplayName = "";
|
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];
|
Drawable[] layers = new Drawable[2];
|
||||||
layers[0] = context.getDrawable(R.drawable.ic_launcher_background);
|
layers[0] = context.getDrawable(R.drawable.ic_launcher_background);
|
||||||
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground);
|
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground);
|
||||||
@ -227,7 +227,7 @@ public class ConversationItem
|
|||||||
|
|
||||||
if (shouldLoadAvatar) {
|
if (shouldLoadAvatar) {
|
||||||
switch (conversation.getType()) {
|
switch (conversation.getType()) {
|
||||||
case ROOM_TYPE_ONE_TO_ONE_CALL:
|
case ONE_TO_ONE_CONVERSATION:
|
||||||
if (!TextUtils.isEmpty(conversation.getName())) {
|
if (!TextUtils.isEmpty(conversation.getName())) {
|
||||||
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
DraweeController draweeController = Fresco.newDraweeControllerBuilder()
|
||||||
.setOldController(holder.dialogAvatar.getController())
|
.setOldController(holder.dialogAvatar.getController())
|
||||||
@ -241,13 +241,13 @@ public class ConversationItem
|
|||||||
holder.dialogAvatar.setVisibility(View.GONE);
|
holder.dialogAvatar.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ROOM_GROUP_CALL:
|
case GROUP_CONVERSATION:
|
||||||
holder.dialogAvatar.getHierarchy()
|
holder.dialogAvatar.getHierarchy()
|
||||||
.setImage(new BitmapDrawable(
|
.setImage(new BitmapDrawable(
|
||||||
DisplayUtils.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
|
DisplayUtils.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
|
||||||
R.drawable.ic_people_group_white_24px)), 100, true);
|
R.drawable.ic_people_group_white_24px)), 100, true);
|
||||||
break;
|
break;
|
||||||
case ROOM_PUBLIC_CALL:
|
case PUBLIC_CONVERSATION:
|
||||||
holder.dialogAvatar.getHierarchy().setImage(new BitmapDrawable(DisplayUtils
|
holder.dialogAvatar.getHierarchy().setImage(new BitmapDrawable(DisplayUtils
|
||||||
.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
|
.getRoundedBitmapFromVectorDrawableResource(context.getResources(),
|
||||||
R.drawable.ic_link_white_24px)), 100, true);
|
R.drawable.ic_link_white_24px)), 100, true);
|
||||||
|
@ -411,7 +411,7 @@ public class CallNotificationController extends BaseController {
|
|||||||
|
|
||||||
private void loadAvatar() {
|
private void loadAvatar() {
|
||||||
switch (currentConversation.getType()) {
|
switch (currentConversation.getType()) {
|
||||||
case ROOM_TYPE_ONE_TO_ONE_CALL:
|
case ONE_TO_ONE_CONVERSATION:
|
||||||
avatarImageView.setVisibility(View.VISIBLE);
|
avatarImageView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
ImageRequest imageRequest =
|
ImageRequest imageRequest =
|
||||||
@ -463,12 +463,12 @@ public class CallNotificationController extends BaseController {
|
|||||||
}, UiThreadImmediateExecutorService.getInstance());
|
}, UiThreadImmediateExecutorService.getInstance());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ROOM_GROUP_CALL:
|
case GROUP_CONVERSATION:
|
||||||
avatarImageView.getHierarchy()
|
avatarImageView.getHierarchy()
|
||||||
.setImage(DisplayUtils.getRoundedDrawable(
|
.setImage(DisplayUtils.getRoundedDrawable(
|
||||||
context.getDrawable(R.drawable.ic_people_group_white_24px))
|
context.getDrawable(R.drawable.ic_people_group_white_24px))
|
||||||
, 100, true);
|
, 100, true);
|
||||||
case ROOM_PUBLIC_CALL:
|
case PUBLIC_CONVERSATION:
|
||||||
avatarImageView.getHierarchy()
|
avatarImageView.getHierarchy()
|
||||||
.setImage(DisplayUtils.getRoundedDrawable(
|
.setImage(DisplayUtils.getRoundedDrawable(
|
||||||
context.getDrawable(R.drawable.ic_people_group_white_24px))
|
context.getDrawable(R.drawable.ic_people_group_white_24px))
|
||||||
|
@ -312,7 +312,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
private fun loadAvatarForStatusBar() {
|
private fun loadAvatarForStatusBar() {
|
||||||
if (currentConversation != null && currentConversation?.type != null &&
|
if (currentConversation != null && currentConversation?.type != null &&
|
||||||
currentConversation?.type == Conversation.ConversationType
|
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(
|
val avatarSize = DisplayUtils.convertDpToPixel(
|
||||||
conversationVoiceCallMenuItem?.icon!!
|
conversationVoiceCallMenuItem?.icon!!
|
||||||
@ -536,9 +536,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkReadOnlyState() {
|
private fun checkReadOnlyState() {
|
||||||
if (currentConversation != null) {
|
if (currentConversation != null && conversationUser != null) {
|
||||||
if (currentConversation?.shouldShowLobby(
|
if (currentConversation?.shouldShowLobby(conversationUser
|
||||||
conversationUser
|
|
||||||
) == true || currentConversation?.conversationReadOnlyState != null && currentConversation?.conversationReadOnlyState == Conversation.ConversationReadOnlyState.CONVERSATION_READ_ONLY
|
) == 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
|
conversationVideoMenuItem?.icon?.alpha = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentConversation != null && currentConversation!!.shouldShowLobby
|
if (conversationUser != null && currentConversation != null && currentConversation!!
|
||||||
(conversationUser)
|
.shouldShowLobby(conversationUser)
|
||||||
) {
|
) {
|
||||||
messageInputView?.visibility = View.GONE
|
messageInputView?.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
@ -567,8 +566,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLobbyState() {
|
private fun checkLobbyState() {
|
||||||
if (currentConversation != null && currentConversation?.isLobbyViewApplicable(
|
if (currentConversation != null && conversationUser != null && currentConversation?.isLobbyViewApplicable(conversationUser
|
||||||
conversationUser
|
|
||||||
) == true
|
) == true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -754,9 +752,11 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
|
|
||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
if (currentConversation != null && currentConversation?.displayName != null) {
|
if (currentConversation != null && currentConversation?.displayName != null) {
|
||||||
return EmojiCompat.get()
|
return currentConversation!!.displayName?.let {
|
||||||
.process(currentConversation!!.displayName)
|
EmojiCompat.get()
|
||||||
|
.process(it)
|
||||||
.toString()
|
.toString()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -1032,7 +1032,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentConversation != null && currentConversation!!.shouldShowLobby(conversationUser)) {
|
if (currentConversation != null && conversationUser != null && currentConversation!!
|
||||||
|
.shouldShowLobby(conversationUser)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,8 +1051,8 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
lookingIntoFuture = true
|
lookingIntoFuture = true
|
||||||
} else if (isFirstMessagesProcessing) {
|
} else if (isFirstMessagesProcessing) {
|
||||||
if (currentConversation != null) {
|
if (currentConversation != null) {
|
||||||
globalLastKnownFutureMessageId = currentConversation!!.lastReadMessage
|
globalLastKnownFutureMessageId = currentConversation!!.lastReadMessageId
|
||||||
globalLastKnownPastMessageId = currentConversation!!.lastReadMessage
|
globalLastKnownPastMessageId = currentConversation!!.lastReadMessageId
|
||||||
fieldMap["includeLastKnown"] = 1
|
fieldMap["includeLastKnown"] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1188,7 +1189,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
|
|
||||||
val chatMessage = chatMessageList[i]
|
val chatMessage = chatMessageList[i]
|
||||||
chatMessage.isOneToOneConversation =
|
chatMessage.isOneToOneConversation =
|
||||||
currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
|
currentConversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
|
||||||
chatMessage.isLinkPreviewAllowed = isLinkPreviewAllowed
|
chatMessage.isLinkPreviewAllowed = isLinkPreviewAllowed
|
||||||
chatMessage.activeUser = conversationUser
|
chatMessage.activeUser = conversationUser
|
||||||
|
|
||||||
@ -1258,7 +1259,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
.actorId, -1
|
.actorId, -1
|
||||||
) && adapter!!.getSameAuthorLastMessagesCount(chatMessage.actorId) % 5 > 0)
|
) && adapter!!.getSameAuthorLastMessagesCount(chatMessage.actorId) % 5 > 0)
|
||||||
chatMessage.isOneToOneConversation =
|
chatMessage.isOneToOneConversation =
|
||||||
(currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
|
(currentConversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION)
|
||||||
adapter?.addToStart(chatMessage, shouldScroll)
|
adapter?.addToStart(chatMessage, shouldScroll)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1447,7 +1448,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
@Subscribe(threadMode = ThreadMode.BACKGROUND)
|
||||||
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
|
fun onMessageEvent(userMentionClickEvent: UserMentionClickEvent) {
|
||||||
if (currentConversation?.type != Conversation.ConversationType
|
if (currentConversation?.type != Conversation.ConversationType
|
||||||
.ROOM_TYPE_ONE_TO_ONE_CALL || currentConversation?.name !=
|
.ONE_TO_ONE_CONVERSATION || currentConversation?.name !=
|
||||||
userMentionClickEvent.userId
|
userMentionClickEvent.userId
|
||||||
) {
|
) {
|
||||||
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(
|
||||||
@ -1482,11 +1483,14 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
)
|
)
|
||||||
conversationIntent.putExtras(bundle)
|
conversationIntent.putExtras(bundle)
|
||||||
|
|
||||||
|
if (roomOverall != null && roomOverall.ocs != null && roomOverall.ocs.data !=
|
||||||
|
null && roomOverall.ocs.data.token != null) {
|
||||||
ConductorRemapping.remapChatController(
|
ConductorRemapping.remapChatController(
|
||||||
router, conversationUser.id,
|
router, conversationUser.id,
|
||||||
roomOverall.ocs.data.token, bundle, false
|
roomOverall.ocs.data.token!!, bundle, false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
conversationIntent.putExtras(bundle)
|
conversationIntent.putExtras(bundle)
|
||||||
|
@ -372,9 +372,9 @@ public class ContactsController extends BaseController implements SearchView.OnQ
|
|||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
Conversation.ConversationType roomType;
|
Conversation.ConversationType roomType;
|
||||||
if (isPublicCall) {
|
if (isPublicCall) {
|
||||||
roomType = Conversation.ConversationType.ROOM_PUBLIC_CALL;
|
roomType = Conversation.ConversationType.PUBLIC_CONVERSATION;
|
||||||
} else {
|
} else {
|
||||||
roomType = Conversation.ConversationType.ROOM_GROUP_CALL;
|
roomType = Conversation.ConversationType.GROUP_CONVERSATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<String> userIdsArray = new ArrayList<>(selectedUserIds);
|
ArrayList<String> userIdsArray = new ArrayList<>(selectedUserIds);
|
||||||
|
@ -63,7 +63,7 @@ import com.nextcloud.talk.jobs.LeaveConversationWorker
|
|||||||
import com.nextcloud.talk.models.database.UserEntity
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
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
|
||||||
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.conversations.RoomOverall
|
||||||
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
|
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
@ -253,8 +253,8 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
|
|
||||||
private fun setupWebinaryView() {
|
private fun setupWebinaryView() {
|
||||||
if (conversationUser!!.hasSpreedFeatureCapability("webinary-lobby") && (conversation!!.type
|
if (conversationUser!!.hasSpreedFeatureCapability("webinary-lobby") && (conversation!!.type
|
||||||
== Conversation.ConversationType.ROOM_GROUP_CALL || conversation!!.type ==
|
== Conversation.ConversationType.GROUP_CONVERSATION || conversation!!.type ==
|
||||||
Conversation.ConversationType.ROOM_PUBLIC_CALL) && conversation!!.canModerate(
|
Conversation.ConversationType.PUBLIC_CONVERSATION) && conversation!!.canModerate(
|
||||||
conversationUser
|
conversationUser
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -270,8 +270,8 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
startTimeView.setOnClickListener {
|
startTimeView.setOnClickListener {
|
||||||
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
|
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
|
||||||
val currentTimeCalendar = Calendar.getInstance()
|
val currentTimeCalendar = Calendar.getInstance()
|
||||||
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
|
if (conversation != null && conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
|
||||||
currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer * 1000
|
currentTimeCalendar.timeInMillis = conversation!!.lobbyTimer!! * 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
dateTimePicker(minDateTime = Calendar.getInstance(), requireFutureDateTime =
|
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) {
|
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != java.lang.Long.MIN_VALUE && conversation!!.lobbyTimer != 0L) {
|
||||||
startTimeView.setSummary(
|
startTimeView.setSummary(
|
||||||
DateUtils.getLocalDateStringFromTimestampForLobby(conversation!!.lobbyTimer)
|
conversation!!.lobbyTimer?.let { DateUtils.getLocalDateStringFromTimestampForLobby(it) }
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
startTimeView.setSummary(R.string.nc_manual)
|
startTimeView.setSummary(R.string.nc_manual)
|
||||||
@ -670,7 +670,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
deleteConversationAction.visibility = View.VISIBLE
|
deleteConversationAction.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) {
|
if (Conversation.ConversationType.SYSTEM_CONVERSATION == conversation!!.type) {
|
||||||
muteCalls.visibility = View.GONE
|
muteCalls.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +701,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupGeneralSettings() {
|
private fun setupGeneralSettings() {
|
||||||
if (conversation != null) {
|
if (conversation != null && conversationUser != null) {
|
||||||
changeConversationName.value = conversation!!.displayName
|
changeConversationName.value = conversation!!.displayName
|
||||||
|
|
||||||
if (conversation!!.isNameEditable(conversationUser)) {
|
if (conversation!!.isNameEditable(conversationUser)) {
|
||||||
@ -710,12 +710,12 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
changeConversationName.visibility = View.GONE
|
changeConversationName.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
favoriteConversationAction.value = conversation!!.isFavorite
|
favoriteConversationAction.value = conversation!!.favorite
|
||||||
if (conversation!!.type.equals(ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) || conversation!!
|
if (conversation!!.type!!.equals(ConversationType.ONE_TO_ONE_CONVERSATION) || conversation!!
|
||||||
.type.equals(ConversationType.ROOM_SYSTEM)) {
|
.type!!.equals(ConversationType.SYSTEM_CONVERSATION)) {
|
||||||
allowGuestsAction.visibility = View.GONE
|
allowGuestsAction.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
allowGuestsAction.value = conversation!!.type == ROOM_PUBLIC_CALL
|
allowGuestsAction.value = conversation!!.type == PUBLIC_CONVERSATION
|
||||||
}
|
}
|
||||||
|
|
||||||
(allowGuestsAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
|
(allowGuestsAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
|
||||||
@ -813,7 +813,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setProperNotificationValue(conversation: Conversation?) {
|
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
|
// hack to see if we get mentioned always or just on mention
|
||||||
if (conversationUser!!.hasSpreedFeatureCapability("mention-flag")) {
|
if (conversationUser!!.hasSpreedFeatureCapability("mention-flag")) {
|
||||||
messageNotificationLevel.value = "always"
|
messageNotificationLevel.value = "always"
|
||||||
@ -827,7 +827,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
|
|
||||||
private fun loadConversationAvatar() {
|
private fun loadConversationAvatar() {
|
||||||
when (conversation!!.type) {
|
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)
|
(conversation!!.name)
|
||||||
) {
|
) {
|
||||||
val draweeController = Fresco.newDraweeControllerBuilder()
|
val draweeController = Fresco.newDraweeControllerBuilder()
|
||||||
@ -844,21 +844,21 @@ class ConversationInfoController(args: Bundle) : BaseController(),
|
|||||||
.build()
|
.build()
|
||||||
conversationAvatarImageView.controller = draweeController
|
conversationAvatarImageView.controller = draweeController
|
||||||
}
|
}
|
||||||
Conversation.ConversationType.ROOM_GROUP_CALL -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
|
Conversation.ConversationType.GROUP_CONVERSATION -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
|
||||||
DisplayUtils
|
DisplayUtils
|
||||||
.getRoundedBitmapDrawableFromVectorDrawableResource(
|
.getRoundedBitmapDrawableFromVectorDrawableResource(
|
||||||
resources,
|
resources,
|
||||||
R.drawable.ic_people_group_white_24px
|
R.drawable.ic_people_group_white_24px
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Conversation.ConversationType.ROOM_PUBLIC_CALL -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
|
Conversation.ConversationType.PUBLIC_CONVERSATION -> conversationAvatarImageView.hierarchy.setPlaceholderImage(
|
||||||
DisplayUtils
|
DisplayUtils
|
||||||
.getRoundedBitmapDrawableFromVectorDrawableResource(
|
.getRoundedBitmapDrawableFromVectorDrawableResource(
|
||||||
resources,
|
resources,
|
||||||
R.drawable.ic_link_white_24px
|
R.drawable.ic_link_white_24px
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Conversation.ConversationType.ROOM_SYSTEM -> {
|
Conversation.ConversationType.SYSTEM_CONVERSATION -> {
|
||||||
val layers = arrayOfNulls<Drawable>(2)
|
val layers = arrayOfNulls<Drawable>(2)
|
||||||
layers[0] = context.getDrawable(R.drawable.ic_launcher_background)
|
layers[0] = context.getDrawable(R.drawable.ic_launcher_background)
|
||||||
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground)
|
layers[1] = context.getDrawable(R.drawable.ic_launcher_foreground)
|
||||||
|
@ -123,6 +123,9 @@ public class WebViewLoginController extends BaseController {
|
|||||||
|
|
||||||
private WebViewFidoBridge webViewFidoBridge;
|
private WebViewFidoBridge webViewFidoBridge;
|
||||||
|
|
||||||
|
public WebViewLoginController() {
|
||||||
|
}
|
||||||
|
|
||||||
public WebViewLoginController(String baseUrl, boolean isPasswordUpdate) {
|
public WebViewLoginController(String baseUrl, boolean isPasswordUpdate) {
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
this.isPasswordUpdate = isPasswordUpdate;
|
this.isPasswordUpdate = isPasswordUpdate;
|
||||||
|
@ -270,7 +270,7 @@ public class OperationsMenuController extends BaseController {
|
|||||||
invite = invitedGroups.get(0);
|
invite = invitedGroups.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversationType.equals(Conversation.ConversationType.ROOM_PUBLIC_CALL) ||
|
if (conversationType.equals(Conversation.ConversationType.PUBLIC_CONVERSATION) ||
|
||||||
!currentUser.hasSpreedFeatureCapability("empty-group-room")) {
|
!currentUser.hasSpreedFeatureCapability("empty-group-room")) {
|
||||||
retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(),
|
retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(),
|
||||||
"3", invite, conversationName);
|
"3", invite, conversationName);
|
||||||
@ -314,7 +314,7 @@ public class OperationsMenuController extends BaseController {
|
|||||||
public void onNext(RoomOverall roomOverall) {
|
public void onNext(RoomOverall roomOverall) {
|
||||||
conversation = roomOverall.getOcs().getData();
|
conversation = roomOverall.getOcs().getData();
|
||||||
if (conversationType.equals(
|
if (conversationType.equals(
|
||||||
Conversation.ConversationType.ROOM_PUBLIC_CALL)
|
Conversation.ConversationType.PUBLIC_CONVERSATION)
|
||||||
&& isGroupCallWorkaroundFinal) {
|
&& isGroupCallWorkaroundFinal) {
|
||||||
performGroupCallWorkaround(credentials);
|
performGroupCallWorkaround(credentials);
|
||||||
} else {
|
} else {
|
||||||
@ -490,7 +490,7 @@ public class OperationsMenuController extends BaseController {
|
|||||||
.getFeatures() != null && capabilitiesOverall.getOcs().getData()
|
.getFeatures() != null && capabilitiesOverall.getOcs().getData()
|
||||||
.getCapabilities().getSpreedCapability()
|
.getCapabilities().getSpreedCapability()
|
||||||
.getFeatures().contains("chat-v2")) {
|
.getFeatures().contains("chat-v2")) {
|
||||||
if (conversation.isHasPassword() && conversation.isGuest()) {
|
if (conversation.getHasPassword() && conversation.isGuest()) {
|
||||||
eventBus.post(new BottomSheetLockEvent(true, 0,
|
eventBus.post(new BottomSheetLockEvent(true, 0,
|
||||||
true, false));
|
true, false));
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
|
@ -27,7 +27,6 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.media.AudioAttributes;
|
import android.media.AudioAttributes;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -171,12 +170,12 @@ public class NotificationWorker extends Worker {
|
|||||||
|
|
||||||
intent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM(), Parcels.wrap(conversation));
|
intent.putExtra(BundleKeys.INSTANCE.getKEY_ROOM(), Parcels.wrap(conversation));
|
||||||
if (conversation.getType()
|
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
|
(!TextUtils.isEmpty(conversation.getObjectType()) && "share:password".equals
|
||||||
(conversation.getObjectType()))) {
|
(conversation.getObjectType()))) {
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
if (conversation.getType().equals(Conversation.ConversationType.ROOM_GROUP_CALL)) {
|
if (conversation.getType().equals(Conversation.ConversationType.GROUP_CONVERSATION)) {
|
||||||
conversationType = "group";
|
conversationType = "group";
|
||||||
} else {
|
} else {
|
||||||
conversationType = "public";
|
conversationType = "public";
|
||||||
|
@ -43,7 +43,7 @@ import org.parceler.Parcel;
|
|||||||
|
|
||||||
@Parcel
|
@Parcel
|
||||||
@Data
|
@Data
|
||||||
@JsonObject
|
@JsonObject(serializeNullCollectionElements = true, serializeNullObjects = true)
|
||||||
public class ChatMessage implements IMessage, MessageContentType, MessageContentType.Image {
|
public class ChatMessage implements IMessage, MessageContentType, MessageContentType.Image {
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isGrouped;
|
public boolean isGrouped;
|
||||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
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<String, HashMap<String, Object>> guestList;
|
|
||||||
@JsonField(name = "participants")
|
|
||||||
public HashMap<String, HashMap<String, Object>> participants;
|
|
||||||
@JsonField(name = "participantType", typeConverter = EnumParticipantTypeConverter.class)
|
|
||||||
public Participant.ParticipantType participantType;
|
|
||||||
@JsonField(name = "hasPassword")
|
|
||||||
public boolean hasPassword;
|
|
||||||
@JsonField(name = "sessionId")
|
|
||||||
public String sessionId;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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<String, HashMap<String, Any>>? = null*/
|
||||||
|
@JsonField(name = ["participants"])
|
||||||
|
var participants: HashMap<String, HashMap<String, Any>>? = 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)
|
||||||
|
}
|
||||||
|
}
|
@ -28,33 +28,31 @@ public class EnumRoomTypeConverter extends IntBasedTypeConverter<Conversation.Co
|
|||||||
public Conversation.ConversationType getFromInt(int i) {
|
public Conversation.ConversationType getFromInt(int i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 1:
|
case 1:
|
||||||
return Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL;
|
return Conversation.ConversationType.ONE_TO_ONE_CONVERSATION;
|
||||||
case 2:
|
case 2:
|
||||||
return Conversation.ConversationType.ROOM_GROUP_CALL;
|
return Conversation.ConversationType.GROUP_CONVERSATION;
|
||||||
case 3:
|
case 3:
|
||||||
return Conversation.ConversationType.ROOM_PUBLIC_CALL;
|
return Conversation.ConversationType.PUBLIC_CONVERSATION;
|
||||||
case 4:
|
case 4:
|
||||||
return Conversation.ConversationType.ROOM_SYSTEM;
|
return Conversation.ConversationType.SYSTEM_CONVERSATION;
|
||||||
default:
|
default:
|
||||||
return Conversation.ConversationType.DUMMY;
|
return Conversation.ConversationType.ONE_TO_ONE_CONVERSATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int convertToInt(Conversation.ConversationType object) {
|
public int convertToInt(Conversation.ConversationType object) {
|
||||||
switch (object) {
|
switch (object) {
|
||||||
case DUMMY:
|
case ONE_TO_ONE_CONVERSATION:
|
||||||
return 0;
|
|
||||||
case ROOM_TYPE_ONE_TO_ONE_CALL:
|
|
||||||
return 1;
|
return 1;
|
||||||
case ROOM_GROUP_CALL:
|
case GROUP_CONVERSATION:
|
||||||
return 2;
|
return 2;
|
||||||
case ROOM_PUBLIC_CALL:
|
case PUBLIC_CONVERSATION:
|
||||||
return 3;
|
return 3;
|
||||||
case ROOM_SYSTEM:
|
case SYSTEM_CONVERSATION:
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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<List<Conversation>> {
|
||||||
|
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<Conversation>
|
||||||
|
) {
|
||||||
|
nextcloudTalkDatabase.conversationsDao()
|
||||||
|
.updateConversationsForUser(
|
||||||
|
user.id,
|
||||||
|
conversations.map {
|
||||||
|
it.toConversationEntity()
|
||||||
|
}.toTypedArray()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteConversationForUserWithTimestamp(
|
||||||
|
user: UserEntity,
|
||||||
|
timestamp: Long
|
||||||
|
) {
|
||||||
|
nextcloudTalkDatabase.conversationsDao()
|
||||||
|
.deleteConversationsForUserWithTimestamp(user.id, timestamp)
|
||||||
|
}
|
||||||
|
}
|
@ -33,15 +33,21 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
|
|||||||
user: UserEntity,
|
user: UserEntity,
|
||||||
conversation: Conversation
|
conversation: Conversation
|
||||||
): GenericOverall {
|
): 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(
|
override suspend fun leaveConversationForUser(
|
||||||
user: UserEntity,
|
user: UserEntity,
|
||||||
conversation: Conversation
|
conversation: Conversation
|
||||||
): GenericOverall {
|
): GenericOverall {
|
||||||
return apiService.leaveConversation(user.getCredentials(), ApiUtils.getUrlForRemoveSelfFromRoom(user
|
return apiService.leaveConversation(
|
||||||
.baseUrl, conversation.token))
|
user.getCredentials(), ApiUtils.getUrlForRemoveSelfFromRoom(
|
||||||
|
user
|
||||||
|
.baseUrl, conversation.token
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setFavoriteValueForConversation(
|
override suspend fun setFavoriteValueForConversation(
|
||||||
@ -66,6 +72,7 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
|
|||||||
return apiService.getConversations(
|
return apiService.getConversations(
|
||||||
user.getCredentials(),
|
user.getCredentials(),
|
||||||
ApiUtils.getUrlForGetRooms(user.baseUrl)
|
ApiUtils.getUrlForGetRooms(user.baseUrl)
|
||||||
).ocs.data
|
)
|
||||||
|
.ocs.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.conversations.RoomsOverall
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
import io.reactivex.Observable
|
|
||||||
import retrofit2.http.DELETE
|
import retrofit2.http.DELETE
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Header
|
import retrofit2.http.Header
|
||||||
|
@ -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.ApiErrorHandler
|
||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiService
|
import com.nextcloud.talk.newarch.data.source.remote.ApiService
|
||||||
import com.nextcloud.talk.newarch.domain.repository.NextcloudTalkRepository
|
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
|
||||||
import com.nextcloud.talk.newarch.utils.NetworkUtils.GetProxyRunnable
|
import com.nextcloud.talk.newarch.utils.NetworkUtils.GetProxyRunnable
|
||||||
import com.nextcloud.talk.newarch.utils.NetworkUtils.MagicAuthenticator
|
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()) }
|
single { createOkHttpClient(androidContext(), get(), get(), get(), get(), get(), get(), get()) }
|
||||||
factory { createApiErrorHandler() }
|
factory { createApiErrorHandler() }
|
||||||
single { createNextcloudTalkRepository(get()) }
|
single { createNextcloudTalkRepository(get()) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCookieManager(): CookieManager {
|
fun createCookieManager(): CookieManager {
|
||||||
@ -253,10 +253,3 @@ fun createService(retrofit: Retrofit): ApiService {
|
|||||||
fun createNextcloudTalkRepository(apiService: ApiService): NextcloudTalkRepository {
|
fun createNextcloudTalkRepository(apiService: ApiService): NextcloudTalkRepository {
|
||||||
return NextcloudTalkRepositoryImpl(apiService)
|
return NextcloudTalkRepositoryImpl(apiService)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createGetConversationsUseCase(
|
|
||||||
nextcloudTalkRepository: NextcloudTalkRepository,
|
|
||||||
apiErrorHandler: ApiErrorHandler
|
|
||||||
): GetConversationsUseCase {
|
|
||||||
return GetConversationsUseCase(nextcloudTalkRepository, apiErrorHandler)
|
|
||||||
}
|
|
||||||
|
@ -21,8 +21,12 @@
|
|||||||
package com.nextcloud.talk.newarch.di.module
|
package com.nextcloud.talk.newarch.di.module
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
import com.nextcloud.talk.R.string
|
import com.nextcloud.talk.R.string
|
||||||
import com.nextcloud.talk.models.database.Models
|
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.database.user.UserUtils
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import io.requery.Persistable
|
import io.requery.Persistable
|
||||||
@ -31,6 +35,7 @@ import io.requery.reactivex.ReactiveEntityStore
|
|||||||
import io.requery.reactivex.ReactiveSupport
|
import io.requery.reactivex.ReactiveSupport
|
||||||
import io.requery.sql.EntityDataStore
|
import io.requery.sql.EntityDataStore
|
||||||
import net.orange_box.storebox.StoreBox
|
import net.orange_box.storebox.StoreBox
|
||||||
|
import org.koin.android.ext.koin.androidApplication
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
@ -39,6 +44,21 @@ val StorageModule = module {
|
|||||||
single { createSqlCipherDatabaseSource(androidContext()) }
|
single { createSqlCipherDatabaseSource(androidContext()) }
|
||||||
single { createDataStore(get()) }
|
single { createDataStore(get()) }
|
||||||
single { createUserUtils(get()) }
|
single { createUserUtils(get()) }
|
||||||
|
single { createNextcloudTalkOfflineRepository(get()) }
|
||||||
|
single { TalkDatabase.getInstance(androidApplication()) }
|
||||||
|
single { get<TalkDatabase>().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 {
|
fun createPreferences(context: Context): AppPreferences {
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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<List<Conversation>>
|
||||||
|
suspend fun clearConversationsForUser(user: UserEntity)
|
||||||
|
suspend fun saveConversationsForUser(
|
||||||
|
user: UserEntity,
|
||||||
|
conversations: List<Conversation>
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
@ -31,6 +31,14 @@ interface NextcloudTalkRepository {
|
|||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
favorite: Boolean
|
favorite: Boolean
|
||||||
): GenericOverall
|
): GenericOverall
|
||||||
suspend fun deleteConversationForUser(user: UserEntity, conversation: Conversation) : GenericOverall
|
|
||||||
suspend fun leaveConversationForUser(userEntity: UserEntity, conversation: Conversation) : GenericOverall
|
suspend fun deleteConversationForUser(
|
||||||
|
user: UserEntity,
|
||||||
|
conversation: Conversation
|
||||||
|
): GenericOverall
|
||||||
|
|
||||||
|
suspend fun leaveConversationForUser(
|
||||||
|
userEntity: UserEntity,
|
||||||
|
conversation: Conversation
|
||||||
|
): GenericOverall
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ package com.nextcloud.talk.newarch.domain.usecases.base
|
|||||||
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||||
|
|
||||||
interface UseCaseResponse<Type> {
|
interface UseCaseResponse<Type> {
|
||||||
fun onSuccess(result: Type)
|
suspend fun onSuccess(result: Type)
|
||||||
fun onError(errorModel: ErrorModel?)
|
fun onError(errorModel: ErrorModel?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ package com.nextcloud.talk.newarch.features.conversationsList
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
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.DeleteConversationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
|
||||||
@ -35,12 +36,15 @@ class ConversationListViewModelFactory constructor(
|
|||||||
private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
||||||
private val leaveConversationUseCase: LeaveConversationUseCase,
|
private val leaveConversationUseCase: LeaveConversationUseCase,
|
||||||
private val deleteConversationUseCase: DeleteConversationUseCase,
|
private val deleteConversationUseCase: DeleteConversationUseCase,
|
||||||
private val userUtils: UserUtils
|
private val userUtils: UserUtils,
|
||||||
|
private val offlineRepository: NextcloudTalkOfflineRepository
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return ConversationsListViewModel(application, conversationsUseCase,
|
return ConversationsListViewModel(
|
||||||
|
application, conversationsUseCase,
|
||||||
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
|
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
|
||||||
userUtils) as T
|
userUtils, offlineRepository
|
||||||
|
) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.errorStateTextView
|
||||||
import kotlinx.android.synthetic.main.view_states.view.loadingStateView
|
import kotlinx.android.synthetic.main.view_states.view.loadingStateView
|
||||||
import kotlinx.android.synthetic.main.view_states.view.stateWithMessageView
|
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.koin.android.ext.android.inject
|
||||||
import org.parceler.Parcels
|
import org.parceler.Parcels
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
@ -180,6 +181,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
container: ViewGroup
|
container: ViewGroup
|
||||||
): View {
|
): View {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
actionBar?.show()
|
||||||
|
|
||||||
viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java)
|
viewModel = viewModelProvider(factory).get(ConversationsListViewModel::class.java)
|
||||||
viewModel.apply {
|
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<ConversationItem>()
|
val newConversations = mutableListOf<ConversationItem>()
|
||||||
for (conversation in it) {
|
for (conversation in sortedConversationsList) {
|
||||||
newConversations.add(ConversationItem(conversation, viewModel.currentUser, activity))
|
newConversations.add(
|
||||||
|
ConversationItem(
|
||||||
|
conversation, viewModel.currentUserLiveData.value,
|
||||||
|
activity
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
recyclerViewAdapter.updateDataSet(newConversations as List<IFlexible<ViewHolder>>?)
|
recyclerViewAdapter.updateDataSet(newConversations as List<IFlexible<ViewHolder>>?)
|
||||||
@ -313,7 +334,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
var displayName =
|
var displayName =
|
||||||
(recyclerViewAdapter.getItem(position) as ConversationItem).model.displayName
|
(recyclerViewAdapter.getItem(position) as ConversationItem).model.displayName
|
||||||
|
|
||||||
if (displayName.length > 8) {
|
if (displayName!!.length > 8) {
|
||||||
displayName = displayName.substring(0, 4) + "..."
|
displayName = displayName.substring(0, 4) + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,12 +415,12 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
val conversation = (clickedItem as ConversationItem).model
|
val conversation = (clickedItem as ConversationItem).model
|
||||||
|
|
||||||
val bundle = Bundle()
|
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_TOKEN, conversation.token)
|
||||||
bundle.putString(BundleKeys.KEY_ROOM_ID, conversation.conversationId)
|
bundle.putString(BundleKeys.KEY_ROOM_ID, conversation.conversationId)
|
||||||
bundle.putParcelable(BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation))
|
bundle.putParcelable(BundleKeys.KEY_ACTIVE_CONVERSATION, Parcels.wrap(conversation))
|
||||||
ConductorRemapping.remapChatController(
|
ConductorRemapping.remapChatController(
|
||||||
router, viewModel.currentUser.id, conversation.token,
|
router, viewModel.currentUserLiveData.value!!.id, conversation!!.token!!,
|
||||||
bundle, false
|
bundle, false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.facebook.common.executors.UiThreadImmediateExecutorService
|
import com.facebook.common.executors.UiThreadImmediateExecutorService
|
||||||
import com.facebook.common.references.CloseableReference
|
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.models.json.generic.GenericOverall
|
||||||
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
|
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
|
||||||
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
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.DeleteConversationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.LeaveConversationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.SetConversationFavoriteValueUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
import com.nextcloud.talk.newarch.utils.ViewState
|
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.newarch.utils.ViewState.LOADING
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
import com.nextcloud.talk.utils.ShareUtils
|
import com.nextcloud.talk.utils.ShareUtils
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils
|
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
|
import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
class ConversationsListViewModel constructor(
|
class ConversationsListViewModel constructor(
|
||||||
@ -66,15 +64,18 @@ class ConversationsListViewModel constructor(
|
|||||||
private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
private val setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
||||||
private val leaveConversationUseCase: LeaveConversationUseCase,
|
private val leaveConversationUseCase: LeaveConversationUseCase,
|
||||||
private val deleteConversationUseCase: DeleteConversationUseCase,
|
private val deleteConversationUseCase: DeleteConversationUseCase,
|
||||||
private val userUtils: UserUtils
|
private val userUtils: UserUtils,
|
||||||
|
private val offlineRepository: NextcloudTalkOfflineRepository
|
||||||
) : BaseViewModel<ConversationsListView>(application) {
|
) : BaseViewModel<ConversationsListView>(application) {
|
||||||
|
|
||||||
private var conversations: MutableList<Conversation> = mutableListOf()
|
val viewState = MutableLiveData<ViewState>(LOADING)
|
||||||
val conversationsLiveListData = MutableLiveData<List<Conversation>>()
|
|
||||||
val viewState = MutableLiveData<ViewState>(INITIAL_LOAD)
|
|
||||||
var messageData: String? = null
|
var messageData: String? = null
|
||||||
val searchQuery = MutableLiveData<String>()
|
val searchQuery = MutableLiveData<String>()
|
||||||
var currentUser: UserEntity = userUtils.currentUser
|
val currentUserLiveData: MutableLiveData<UserEntity> = MutableLiveData()
|
||||||
|
val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
|
||||||
|
offlineRepository.getConversationsForUser(it)
|
||||||
|
}
|
||||||
|
|
||||||
var currentUserAvatar: MutableLiveData<Drawable> = MutableLiveData()
|
var currentUserAvatar: MutableLiveData<Drawable> = MutableLiveData()
|
||||||
get() {
|
get() {
|
||||||
if (field.value == null) {
|
if (field.value == null) {
|
||||||
@ -85,48 +86,53 @@ class ConversationsListViewModel constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun leaveConversation(conversation: Conversation) {
|
fun leaveConversation(conversation: Conversation) {
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, true)
|
setConversationUpdateStatus(conversation, true)
|
||||||
|
}
|
||||||
leaveConversationUseCase.invoke(viewModelScope, parametersOf(currentUser, conversation),
|
leaveConversationUseCase.invoke(viewModelScope, parametersOf(
|
||||||
|
currentUserLiveData.value,
|
||||||
|
conversation
|
||||||
|
),
|
||||||
object : UseCaseResponse<GenericOverall> {
|
object : UseCaseResponse<GenericOverall> {
|
||||||
override fun onSuccess(result: GenericOverall) {
|
override suspend fun onSuccess(result: GenericOverall) {
|
||||||
// TODO: Use binary search to find the right room
|
offlineRepository.deleteConversation(
|
||||||
conversations.find { it.conversationId == conversation.conversationId }
|
currentUserLiveData.value!!.id, conversation
|
||||||
?.let {
|
.conversationId
|
||||||
conversations.remove(it)
|
)
|
||||||
conversationsLiveListData.value = conversations
|
|
||||||
if (conversations.isEmpty()) {
|
|
||||||
viewState.value = LOADED_EMPTY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(errorModel: ErrorModel?) {
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
messageData = errorModel?.getErrorMessage()
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, false)
|
setConversationUpdateStatus(conversation, false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteConversation(conversation: Conversation) {
|
fun deleteConversation(conversation: Conversation) {
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, true)
|
setConversationUpdateStatus(conversation, true)
|
||||||
|
}
|
||||||
|
|
||||||
deleteConversationUseCase.invoke(viewModelScope, parametersOf(currentUser, conversation),
|
deleteConversationUseCase.invoke(viewModelScope, parametersOf(
|
||||||
|
currentUserLiveData.value,
|
||||||
|
conversation
|
||||||
|
),
|
||||||
object : UseCaseResponse<GenericOverall> {
|
object : UseCaseResponse<GenericOverall> {
|
||||||
override fun onSuccess(result: GenericOverall) {
|
override suspend fun onSuccess(result: GenericOverall) {
|
||||||
// TODO: Use binary search to find the right room
|
offlineRepository.deleteConversation(
|
||||||
conversations.find { it.conversationId == conversation.conversationId }
|
currentUserLiveData.value!!.id, conversation
|
||||||
?.let {
|
.conversationId
|
||||||
conversations.remove(it)
|
)
|
||||||
conversationsLiveListData.value = conversations
|
|
||||||
if (conversations.isEmpty()) {
|
|
||||||
viewState.value = LOADED_EMPTY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(errorModel: ErrorModel?) {
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
messageData = errorModel?.getErrorMessage()
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, false)
|
setConversationUpdateStatus(conversation, false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -135,74 +141,63 @@ class ConversationsListViewModel constructor(
|
|||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
favorite: Boolean
|
favorite: Boolean
|
||||||
) {
|
) {
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, true)
|
setConversationUpdateStatus(conversation, true)
|
||||||
|
}
|
||||||
|
|
||||||
setConversationFavoriteValueUseCase.invoke(viewModelScope, parametersOf(
|
setConversationFavoriteValueUseCase.invoke(viewModelScope, parametersOf(
|
||||||
currentUser,
|
currentUserLiveData.value,
|
||||||
conversation,
|
conversation,
|
||||||
favorite
|
favorite
|
||||||
),
|
),
|
||||||
object : UseCaseResponse<GenericOverall> {
|
object : UseCaseResponse<GenericOverall> {
|
||||||
override fun onSuccess(result: GenericOverall) {
|
override suspend fun onSuccess(result: GenericOverall) {
|
||||||
// TODO: Use binary search to find the right room
|
offlineRepository.setFavoriteValueForConversation(
|
||||||
conversations.find { it.conversationId == conversation.conversationId }
|
currentUserLiveData.value!!.id,
|
||||||
?.apply {
|
conversation.conversationId, favorite
|
||||||
updating = false
|
)
|
||||||
isFavorite = favorite
|
|
||||||
conversationsLiveListData.value = conversations
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(errorModel: ErrorModel?) {
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
messageData = errorModel?.getErrorMessage()
|
||||||
|
viewModelScope.launch {
|
||||||
setConversationUpdateStatus(conversation, false)
|
setConversationUpdateStatus(conversation, false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadConversations() {
|
fun loadConversations() {
|
||||||
val userChanged = !currentUser.equals(userUtils.currentUser)
|
val userChanged = !(currentUserLiveData.value?.equals(userUtils.currentUser) ?: false)
|
||||||
|
|
||||||
if (userChanged) {
|
if (userChanged) {
|
||||||
currentUser = userUtils.currentUser
|
currentUserLiveData.value = userUtils.currentUser
|
||||||
}
|
|
||||||
|
|
||||||
if ((FAILED).equals(viewState.value) || (LOADED_EMPTY).equals(viewState.value) ||
|
|
||||||
(INITIAL_LOAD).equals(viewState.value) || !currentUser.equals(userUtils.currentUser) || userChanged
|
|
||||||
) {
|
|
||||||
viewState.value = LOADING
|
viewState.value = LOADING
|
||||||
}
|
}
|
||||||
|
|
||||||
getConversationsUseCase.invoke(
|
getConversationsUseCase.invoke(viewModelScope, parametersOf(currentUserLiveData.value), object :
|
||||||
viewModelScope, parametersOf(currentUser), object : UseCaseResponse<List<Conversation>> {
|
UseCaseResponse<List<Conversation>> {
|
||||||
override fun onSuccess(result: List<Conversation>) {
|
override suspend fun onSuccess(result: List<Conversation>) {
|
||||||
val newConversations = result.toMutableList()
|
val mutableList = result.toMutableList()
|
||||||
|
mutableList.forEach {
|
||||||
|
it.user = currentUserLiveData.value!!.id
|
||||||
|
}
|
||||||
|
|
||||||
newConversations.sortWith(Comparator { conversation1, conversation2 ->
|
offlineRepository.saveConversationsForUser(currentUserLiveData.value!!, mutableList)
|
||||||
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
|
|
||||||
messageData = ""
|
messageData = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(errorModel: ErrorModel?) {
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
messageData = errorModel?.getErrorMessage()
|
messageData = errorModel?.getErrorMessage()
|
||||||
viewState.value = FAILED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadAvatar(avatarSize: Int) {
|
fun loadAvatar(avatarSize: Int) {
|
||||||
val imageRequest = DisplayUtils.getImageRequestForUrl(
|
val imageRequest = DisplayUtils.getImageRequestForUrl(
|
||||||
ApiUtils.getUrlForAvatarWithNameAndPixels(
|
ApiUtils.getUrlForAvatarWithNameAndPixels(
|
||||||
currentUser.baseUrl,
|
currentUserLiveData.value!!.baseUrl,
|
||||||
currentUser.userId, avatarSize
|
currentUserLiveData.value!!.userId, avatarSize
|
||||||
), null
|
), null
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -257,7 +252,7 @@ class ConversationsListViewModel constructor(
|
|||||||
fun getConversationMenuItemsForConversation(conversation: Conversation): MutableList<BasicListItemWithImage> {
|
fun getConversationMenuItemsForConversation(conversation: Conversation): MutableList<BasicListItemWithImage> {
|
||||||
val items = mutableListOf<BasicListItemWithImage>()
|
val items = mutableListOf<BasicListItemWithImage>()
|
||||||
|
|
||||||
if (conversation.isFavorite) {
|
if (conversation.favorite) {
|
||||||
items.add(
|
items.add(
|
||||||
BasicListItemWithImage(
|
BasicListItemWithImage(
|
||||||
drawable.ic_star_border_black_24dp,
|
drawable.ic_star_border_black_24dp,
|
||||||
@ -282,7 +277,7 @@ class ConversationsListViewModel constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.canLeave(currentUser)) {
|
if (conversation.canLeave(currentUserLiveData.value!!)) {
|
||||||
items.add(
|
items.add(
|
||||||
BasicListItemWithImage(
|
BasicListItemWithImage(
|
||||||
drawable.ic_exit_to_app_black_24dp, context.getString
|
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(
|
items.add(
|
||||||
BasicListItemWithImage(
|
BasicListItemWithImage(
|
||||||
drawable.ic_delete_grey600_24dp, context.getString(
|
drawable.ic_delete_grey600_24dp, context.getString(
|
||||||
@ -304,14 +299,13 @@ class ConversationsListViewModel constructor(
|
|||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setConversationUpdateStatus(
|
private suspend fun setConversationUpdateStatus(
|
||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
value: Boolean
|
value: Boolean
|
||||||
) {
|
) {
|
||||||
conversations.find { it.conversationId == conversation.conversationId }
|
offlineRepository.setChangingValueForConversation(
|
||||||
?.apply {
|
currentUserLiveData.value!!.id, conversation
|
||||||
updating = value
|
.conversationId, value
|
||||||
conversationsLiveListData.value = conversations
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package com.nextcloud.talk.newarch.features.conversationsList.di.module
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
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.repository.NextcloudTalkRepository
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.DeleteConversationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetConversationsUseCase
|
||||||
@ -41,7 +42,7 @@ val ConversationsListModule = module {
|
|||||||
factory {
|
factory {
|
||||||
createConversationListViewModelFactory(
|
createConversationListViewModelFactory(
|
||||||
androidApplication(), get(), get(), get(), get
|
androidApplication(), get(), get(), get(), get
|
||||||
(), get()
|
(), get(), get()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,11 +82,12 @@ fun createConversationListViewModelFactory(
|
|||||||
setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
setConversationFavoriteValueUseCase: SetConversationFavoriteValueUseCase,
|
||||||
leaveConversationUseCase: LeaveConversationUseCase,
|
leaveConversationUseCase: LeaveConversationUseCase,
|
||||||
deleteConversationUseCase: DeleteConversationUseCase,
|
deleteConversationUseCase: DeleteConversationUseCase,
|
||||||
userUtils: UserUtils
|
userUtils: UserUtils,
|
||||||
|
offlineRepository: NextcloudTalkOfflineRepository
|
||||||
): ConversationListViewModelFactory {
|
): ConversationListViewModelFactory {
|
||||||
return ConversationListViewModelFactory(
|
return ConversationListViewModelFactory(
|
||||||
application, getConversationsUseCase,
|
application, getConversationsUseCase,
|
||||||
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
|
setConversationFavoriteValueUseCase, leaveConversationUseCase, deleteConversationUseCase,
|
||||||
userUtils
|
userUtils, offlineRepository
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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<List<ConversationEntity>>
|
||||||
|
|
||||||
|
@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<ConversationEntity>
|
||||||
|
) {
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
|
||||||
|
val conversationsWithTimestampApplied = newConversations.map {
|
||||||
|
it.modifiedAt = System.currentTimeMillis()
|
||||||
|
it
|
||||||
|
}
|
||||||
|
.toTypedArray()
|
||||||
|
|
||||||
|
saveConversations(*conversationsWithTimestampApplied)
|
||||||
|
deleteConversationsForUserWithTimestamp(userId, timestamp)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk application
|
||||||
|
*
|
||||||
|
* @author Mario Danic
|
||||||
|
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk.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<String, HashMap<String, Any>>? = null,
|
||||||
|
@ColumnInfo(name = "participants") var participants: HashMap<String, HashMap<String, Any>>? =
|
||||||
|
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
|
||||||
|
}
|
@ -83,7 +83,8 @@ class NetworkUtils {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return response.request().newBuilder()
|
return response.request()
|
||||||
|
.newBuilder()
|
||||||
.header(authenticatorType, credentials)
|
.header(authenticatorType, credentials)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
package com.nextcloud.talk.newarch.utils
|
package com.nextcloud.talk.newarch.utils
|
||||||
|
|
||||||
enum class ViewState {
|
enum class ViewState {
|
||||||
INITIAL_LOAD,
|
|
||||||
LOADING,
|
LOADING,
|
||||||
LOADED_EMPTY,
|
LOADED_EMPTY,
|
||||||
LOADED,
|
LOADED,
|
||||||
|
@ -24,28 +24,36 @@
|
|||||||
android:id="@+id/generic_rv_layout"
|
android:id="@+id/generic_rv_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:animateLayoutChanges="true">
|
android:animateLayoutChanges="true"
|
||||||
|
>
|
||||||
|
|
||||||
<include layout="@layout/view_states"/>
|
<include
|
||||||
|
layout="@layout/view_states"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
android:id="@+id/swipeRefreshLayoutView"
|
android:id="@+id/swipeRefreshLayoutView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_behavior="com.nextcloud.talk.utils.FABAwareScrollingViewBehavior">
|
app:layout_behavior="com.nextcloud.talk.utils.FABAwareScrollingViewBehavior"
|
||||||
|
>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
android:id="@+id/dataStateView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/dataStateView"
|
android:visibility="invisible"
|
||||||
android:visibility="invisible">
|
>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:listitem="@layout/rv_item_conversation" />
|
tools:listitem="@layout/rv_item_conversation"
|
||||||
|
/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
@ -58,7 +66,8 @@
|
|||||||
android:layout_gravity="bottom|end"
|
android:layout_gravity="bottom|end"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:srcCompat="@drawable/ic_add_white_24px" />
|
app:srcCompat="@drawable/ic_add_white_24px"
|
||||||
|
/>
|
||||||
|
|
||||||
<include layout="@layout/fast_scroller" />
|
<include layout="@layout/fast_scroller" />
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Select an account</string>
|
<string name="nc_select_an_account">Select an account</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Start a conversation</string>
|
<string name="nc_start_conversation">Start a conversation</string>
|
||||||
<string name="nc_configure_room">Configure conversation</string>
|
<string name="nc_configure_room">Configure conversation</string>
|
||||||
<string name="nc_leave">Leave conversation</string>
|
<string name="nc_leave">Leave conversation</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Selecciona un compte</string>
|
<string name="nc_select_an_account">Selecciona un compte</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Enceta una conversa</string>
|
<string name="nc_start_conversation">Enceta una conversa</string>
|
||||||
<string name="nc_configure_room">Configura la conversa</string>
|
<string name="nc_configure_room">Configura la conversa</string>
|
||||||
<string name="nc_leave">Surt de la conversa</string>
|
<string name="nc_leave">Surt de la conversa</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Vyberte účet</string>
|
<string name="nc_select_an_account">Vyberte účet</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Začněte konverzaci</string>
|
<string name="nc_start_conversation">Začněte konverzaci</string>
|
||||||
<string name="nc_configure_room">Nastavení konverzace</string>
|
<string name="nc_configure_room">Nastavení konverzace</string>
|
||||||
<string name="nc_leave">Opustit konverzaci</string>
|
<string name="nc_leave">Opustit konverzaci</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Vælg konto</string>
|
<string name="nc_select_an_account">Vælg konto</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Start en samtale</string>
|
<string name="nc_start_conversation">Start en samtale</string>
|
||||||
<string name="nc_configure_room">Samtaleopsætning</string>
|
<string name="nc_configure_room">Samtaleopsætning</string>
|
||||||
<string name="nc_leave">Forlad samtale</string>
|
<string name="nc_leave">Forlad samtale</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Konto auswählen</string>
|
<string name="nc_select_an_account">Konto auswählen</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Starte eine Unterhaltung</string>
|
<string name="nc_start_conversation">Starte eine Unterhaltung</string>
|
||||||
<string name="nc_configure_room">Unterhaltung einrichten</string>
|
<string name="nc_configure_room">Unterhaltung einrichten</string>
|
||||||
<string name="nc_leave">Unterhaltung verlassen</string>
|
<string name="nc_leave">Unterhaltung verlassen</string>
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
<string name="nc_license_title">Άδεια χρήσης</string>
|
<string name="nc_license_title">Άδεια χρήσης</string>
|
||||||
<string name="nc_select_an_account">Επιλογή λογαριασμού</string>
|
<string name="nc_select_an_account">Επιλογή λογαριασμού</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Έναρξη συνομιλίας</string>
|
<string name="nc_start_conversation">Έναρξη συνομιλίας</string>
|
||||||
<string name="nc_configure_room">Ρύθμιση συνομιλίας</string>
|
<string name="nc_configure_room">Ρύθμιση συνομιλίας</string>
|
||||||
<string name="nc_leave">Εγκατάλειψη συνομιλίας</string>
|
<string name="nc_leave">Εγκατάλειψη συνομιλίας</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Selecciona una cuenta</string>
|
<string name="nc_select_an_account">Selecciona una cuenta</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Comienza una conversación</string>
|
<string name="nc_start_conversation">Comienza una conversación</string>
|
||||||
<string name="nc_configure_room">Configura la conversación</string>
|
<string name="nc_configure_room">Configura la conversación</string>
|
||||||
<string name="nc_leave">Abandonar conversación</string>
|
<string name="nc_leave">Abandonar conversación</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Choisissez un compte</string>
|
<string name="nc_select_an_account">Choisissez un compte</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Commencer une conversation</string>
|
<string name="nc_start_conversation">Commencer une conversation</string>
|
||||||
<string name="nc_configure_room">Configurer la conversation</string>
|
<string name="nc_configure_room">Configurer la conversation</string>
|
||||||
<string name="nc_leave">Quitter la conversation</string>
|
<string name="nc_leave">Quitter la conversation</string>
|
||||||
|
@ -127,7 +127,7 @@ Produciuse un fallo aorecuperar os axustes da sinalización</string>
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Seleccione unha conta</string>
|
<string name="nc_select_an_account">Seleccione unha conta</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Iniciar unha conversa</string>
|
<string name="nc_start_conversation">Iniciar unha conversa</string>
|
||||||
<string name="nc_configure_room">Configurar a conversa</string>
|
<string name="nc_configure_room">Configurar a conversa</string>
|
||||||
<string name="nc_leave">Abandonar a conversa</string>
|
<string name="nc_leave">Abandonar a conversa</string>
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Odaberi račun</string>
|
<string name="nc_select_an_account">Odaberi račun</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Započni razgovor</string>
|
<string name="nc_start_conversation">Započni razgovor</string>
|
||||||
<string name="nc_configure_room">Konfiguriraj razgovor</string>
|
<string name="nc_configure_room">Konfiguriraj razgovor</string>
|
||||||
<string name="nc_leave">Napusti razgovor</string>
|
<string name="nc_leave">Napusti razgovor</string>
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Válasszon fiókot</string>
|
<string name="nc_select_an_account">Válasszon fiókot</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Beszélgetés indítása</string>
|
<string name="nc_start_conversation">Beszélgetés indítása</string>
|
||||||
<string name="nc_configure_room">Beszélgetés beállításai</string>
|
<string name="nc_configure_room">Beszélgetés beállításai</string>
|
||||||
<string name="nc_leave">Beszélgetés elhagyása</string>
|
<string name="nc_leave">Beszélgetés elhagyása</string>
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Veldu aðgang</string>
|
<string name="nc_select_an_account">Veldu aðgang</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Hefja samtal</string>
|
<string name="nc_start_conversation">Hefja samtal</string>
|
||||||
<string name="nc_configure_room">Stilla samtal</string>
|
<string name="nc_configure_room">Stilla samtal</string>
|
||||||
<string name="nc_leave">Hætta í samtali</string>
|
<string name="nc_leave">Hætta í samtali</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Seleziona account</string>
|
<string name="nc_select_an_account">Seleziona account</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Inizia una conversazione</string>
|
<string name="nc_start_conversation">Inizia una conversazione</string>
|
||||||
<string name="nc_configure_room">Configura conversazione</string>
|
<string name="nc_configure_room">Configura conversazione</string>
|
||||||
<string name="nc_leave">Lascia la conversazione</string>
|
<string name="nc_leave">Lascia la conversazione</string>
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">בחירת חשבון</string>
|
<string name="nc_select_an_account">בחירת חשבון</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">התחלת דיון</string>
|
<string name="nc_start_conversation">התחלת דיון</string>
|
||||||
<string name="nc_configure_room">הגדרת דיון</string>
|
<string name="nc_configure_room">הגדרת דיון</string>
|
||||||
<string name="nc_leave">יציאה מהדיון</string>
|
<string name="nc_leave">יציאה מהדיון</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">アカウントを選択</string>
|
<string name="nc_select_an_account">アカウントを選択</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">会話を開始する</string>
|
<string name="nc_start_conversation">会話を開始する</string>
|
||||||
<string name="nc_configure_room">会話を構成する</string>
|
<string name="nc_configure_room">会話を構成する</string>
|
||||||
<string name="nc_leave">会話を離れる</string>
|
<string name="nc_leave">会話を離れる</string>
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">계정 선택</string>
|
<string name="nc_select_an_account">계정 선택</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">대화 시작</string>
|
<string name="nc_start_conversation">대화 시작</string>
|
||||||
<string name="nc_configure_room">대화 설정</string>
|
<string name="nc_configure_room">대화 설정</string>
|
||||||
<string name="nc_leave">대화 나가기</string>
|
<string name="nc_leave">대화 나가기</string>
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Velg en konto</string>
|
<string name="nc_select_an_account">Velg en konto</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Start en samtale</string>
|
<string name="nc_start_conversation">Start en samtale</string>
|
||||||
<string name="nc_configure_room">Konfigurer samtale</string>
|
<string name="nc_configure_room">Konfigurer samtale</string>
|
||||||
<string name="nc_leave">Forlat samtale</string>
|
<string name="nc_leave">Forlat samtale</string>
|
||||||
|
@ -126,7 +126,7 @@ Kies er eentje van een provider.</string>
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Selecteer een account</string>
|
<string name="nc_select_an_account">Selecteer een account</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Begin een gesprek</string>
|
<string name="nc_start_conversation">Begin een gesprek</string>
|
||||||
<string name="nc_configure_room">Configureren gesprek</string>
|
<string name="nc_configure_room">Configureren gesprek</string>
|
||||||
<string name="nc_leave">Verlaat gesprek</string>
|
<string name="nc_leave">Verlaat gesprek</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Wybierz konto</string>
|
<string name="nc_select_an_account">Wybierz konto</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Rozpocznij rozmowę</string>
|
<string name="nc_start_conversation">Rozpocznij rozmowę</string>
|
||||||
<string name="nc_configure_room">Konfiguruj rozmowę</string>
|
<string name="nc_configure_room">Konfiguruj rozmowę</string>
|
||||||
<string name="nc_leave">Opuść rozmowę</string>
|
<string name="nc_leave">Opuść rozmowę</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Selecionar uma conta</string>
|
<string name="nc_select_an_account">Selecionar uma conta</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Iniciar uma conversa</string>
|
<string name="nc_start_conversation">Iniciar uma conversa</string>
|
||||||
<string name="nc_configure_room">Configurar uma conversa</string>
|
<string name="nc_configure_room">Configurar uma conversa</string>
|
||||||
<string name="nc_leave">Sair da conversa</string>
|
<string name="nc_leave">Sair da conversa</string>
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Selecionar uma conta</string>
|
<string name="nc_select_an_account">Selecionar uma conta</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Iniciar uma conversação</string>
|
<string name="nc_start_conversation">Iniciar uma conversação</string>
|
||||||
<string name="nc_configure_room">Configurar conversação</string>
|
<string name="nc_configure_room">Configurar conversação</string>
|
||||||
<string name="nc_leave">Sair da conversação</string>
|
<string name="nc_leave">Sair da conversação</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Выберите учётную запись</string>
|
<string name="nc_select_an_account">Выберите учётную запись</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Начать беседу</string>
|
<string name="nc_start_conversation">Начать беседу</string>
|
||||||
<string name="nc_configure_room">Настроить беседу</string>
|
<string name="nc_configure_room">Настроить беседу</string>
|
||||||
<string name="nc_leave">Покинуть беседу</string>
|
<string name="nc_leave">Покинуть беседу</string>
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Zvoľte si účet</string>
|
<string name="nc_select_an_account">Zvoľte si účet</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Začať rozhovor</string>
|
<string name="nc_start_conversation">Začať rozhovor</string>
|
||||||
<string name="nc_configure_room">Nastavenia rozhovoru</string>
|
<string name="nc_configure_room">Nastavenia rozhovoru</string>
|
||||||
<string name="nc_leave">Odísť z rozhovoru</string>
|
<string name="nc_leave">Odísť z rozhovoru</string>
|
||||||
|
@ -115,7 +115,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Izbor računa</string>
|
<string name="nc_select_an_account">Izbor računa</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Začni s pogovorom</string>
|
<string name="nc_start_conversation">Začni s pogovorom</string>
|
||||||
<string name="nc_configure_room">Nastavitev pogovora</string>
|
<string name="nc_configure_room">Nastavitev pogovora</string>
|
||||||
<string name="nc_leave">Zapusti pogovor</string>
|
<string name="nc_leave">Zapusti pogovor</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Изаберите налог</string>
|
<string name="nc_select_an_account">Изаберите налог</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Започни разговор</string>
|
<string name="nc_start_conversation">Започни разговор</string>
|
||||||
<string name="nc_configure_room">Подеси разговор</string>
|
<string name="nc_configure_room">Подеси разговор</string>
|
||||||
<string name="nc_leave">Напусти разговор</string>
|
<string name="nc_leave">Напусти разговор</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Välj ett konto</string>
|
<string name="nc_select_an_account">Välj ett konto</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Starta en konversation</string>
|
<string name="nc_start_conversation">Starta en konversation</string>
|
||||||
<string name="nc_configure_room">Anpassa konversation</string>
|
<string name="nc_configure_room">Anpassa konversation</string>
|
||||||
<string name="nc_leave">Lämna konversationen</string>
|
<string name="nc_leave">Lämna konversationen</string>
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Bir hesap seçin</string>
|
<string name="nc_select_an_account">Bir hesap seçin</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Yeni bir görüşme başlat</string>
|
<string name="nc_start_conversation">Yeni bir görüşme başlat</string>
|
||||||
<string name="nc_configure_room">Görüşmeyi yapılandır</string>
|
<string name="nc_configure_room">Görüşmeyi yapılandır</string>
|
||||||
<string name="nc_leave">Görüşmeden ayrıl</string>
|
<string name="nc_leave">Görüşmeden ayrıl</string>
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Chọn một tài khoản</string>
|
<string name="nc_select_an_account">Chọn một tài khoản</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Bắt đầu một cuộc Đàm thoại</string>
|
<string name="nc_start_conversation">Bắt đầu một cuộc Đàm thoại</string>
|
||||||
<string name="nc_configure_room">Cấu hình đàm thoại</string>
|
<string name="nc_configure_room">Cấu hình đàm thoại</string>
|
||||||
<string name="nc_leave">Rời khỏi cuộc đàm thoại</string>
|
<string name="nc_leave">Rời khỏi cuộc đàm thoại</string>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">选择一个账户</string>
|
<string name="nc_select_an_account">选择一个账户</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">发起会话</string>
|
<string name="nc_start_conversation">发起会话</string>
|
||||||
<string name="nc_configure_room">配置会话</string>
|
<string name="nc_configure_room">配置会话</string>
|
||||||
<string name="nc_leave">离开会话</string>
|
<string name="nc_leave">离开会话</string>
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">選擇一個帳號</string>
|
<string name="nc_select_an_account">選擇一個帳號</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">新對話</string>
|
<string name="nc_start_conversation">新對話</string>
|
||||||
<string name="nc_configure_room">設定對話</string>
|
<string name="nc_configure_room">設定對話</string>
|
||||||
<string name="nc_leave">結束對話</string>
|
<string name="nc_leave">結束對話</string>
|
||||||
|
@ -144,7 +144,7 @@
|
|||||||
|
|
||||||
<string name="nc_select_an_account">Select an account</string>
|
<string name="nc_select_an_account">Select an account</string>
|
||||||
|
|
||||||
<!-- Conversation menu -->
|
<!-- ConversationEntity menu -->
|
||||||
<string name="nc_start_conversation">Start a conversation</string>
|
<string name="nc_start_conversation">Start a conversation</string>
|
||||||
<string name="nc_configure_room">Configure conversation</string>
|
<string name="nc_configure_room">Configure conversation</string>
|
||||||
<string name="nc_leave">Leave conversation</string>
|
<string name="nc_leave">Leave conversation</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user