mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-23 13:40:43 +01:00
Fix some of the issues
This commit is contained in:
parent
a9933b484c
commit
4cd1b9fb18
@ -2,7 +2,7 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"identityHash": "26585a95894baebb7d811a80f3811b85",
|
"identityHash": "0bb77d35d80f74e97eea4a5415d9a102",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "conversations",
|
"tableName": "conversations",
|
||||||
@ -15,7 +15,7 @@
|
|||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "user",
|
"fieldPath": "userId",
|
||||||
"columnName": "user_id",
|
"columnName": "user_id",
|
||||||
"affinity": "INTEGER",
|
"affinity": "INTEGER",
|
||||||
"notNull": false
|
"notNull": false
|
||||||
@ -198,7 +198,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "messages",
|
"tableName": "messages",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `conversation_id` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `system_message_type` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `conversation_id` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `actor_id` TEXT, `actor_type` TEXT, `actor_display_name` TEXT, `timestamp` INTEGER NOT NULL, `message` TEXT, `replyable` INTEGER NOT NULL, `system_message_type` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`conversation_id`) REFERENCES `conversations`(`id`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@ -207,7 +207,7 @@
|
|||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "conversation",
|
"fieldPath": "conversationId",
|
||||||
"columnName": "conversation_id",
|
"columnName": "conversation_id",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
@ -248,6 +248,12 @@
|
|||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": false
|
"notNull": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "replyable",
|
||||||
|
"columnName": "replyable",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "systemMessageType",
|
"fieldPath": "systemMessageType",
|
||||||
"columnName": "system_message_type",
|
"columnName": "system_message_type",
|
||||||
@ -369,7 +375,7 @@
|
|||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"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, '26585a95894baebb7d811a80f3811b85')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0bb77d35d80f74e97eea4a5415d9a102')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -34,6 +34,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage
|
|||||||
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.ONE_TO_ONE_CONVERSATION
|
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
import com.nextcloud.talk.newarch.local.models.getCredentials
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -67,14 +68,14 @@ class ConversationItem(
|
|||||||
&& model.unreadMention == comparedConversation.unreadMention
|
&& model.unreadMention == comparedConversation.unreadMention
|
||||||
&& model.objectType == comparedConversation.objectType
|
&& model.objectType == comparedConversation.objectType
|
||||||
&& model.changing == comparedConversation.changing
|
&& model.changing == comparedConversation.changing
|
||||||
&& user.id == inItem.user.id)
|
&& inItem.user.id == other.user.id)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
return Objects.hash(
|
return Objects.hash(
|
||||||
model.conversationId, model.token,
|
model.token,
|
||||||
user.id
|
user.id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -245,6 +246,7 @@ class ConversationItem(
|
|||||||
model.name, R.dimen.avatar_size
|
model.name, R.dimen.avatar_size
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
addHeader("Authorization", user.getCredentials())
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import coil.transform.CircleCropTransformation
|
|||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
import com.nextcloud.talk.newarch.local.models.getCredentials
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
@ -112,6 +113,7 @@ class MentionAutocompleteItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
holder.avatarImageView!!.load(avatarUrl) {
|
holder.avatarImageView!!.load(avatarUrl) {
|
||||||
|
addHeader("Authorization", currentUser.getCredentials())
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation
|
|||||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
||||||
import com.nextcloud.talk.models.json.participants.Participant
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
import com.nextcloud.talk.models.json.participants.ParticipantsOverall
|
import com.nextcloud.talk.models.json.participants.ParticipantsOverall
|
||||||
|
import com.nextcloud.talk.newarch.utils.getCredentials
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.DoNotDisturbUtils
|
import com.nextcloud.talk.utils.DoNotDisturbUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
@ -393,6 +394,7 @@ class CallNotificationController(private val originalBundle: Bundle) : BaseContr
|
|||||||
currentConversation!!.name, R.dimen.avatar_size_very_big
|
currentConversation!!.name, R.dimen.avatar_size_very_big
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
addHeader("Authorization", userBeingCalled.getCredentials())
|
||||||
transformations(CircleCropTransformation())
|
transformations(CircleCropTransformation())
|
||||||
listener(onSuccess = { data, dataSource ->
|
listener(onSuccess = { data, dataSource ->
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
|
@ -105,7 +105,6 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
.OnMessageLongClickListener<IMessage>, MessageHolders.ContentChecker<IMessage> {
|
.OnMessageLongClickListener<IMessage>, MessageHolders.ContentChecker<IMessage> {
|
||||||
|
|
||||||
val ncApi: NcApi by inject()
|
val ncApi: NcApi by inject()
|
||||||
val userUtils: UserUtils by inject()
|
|
||||||
|
|
||||||
@BindView(R.id.messagesListView)
|
@BindView(R.id.messagesListView)
|
||||||
@JvmField
|
@JvmField
|
||||||
@ -306,7 +305,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
|
|||||||
imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
|
imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
|
||||||
conversationUser?.baseUrl,
|
conversationUser?.baseUrl,
|
||||||
currentConversation?.name, avatarSize / 2
|
currentConversation?.name, avatarSize / 2
|
||||||
), null, target, null,
|
), conversationUser, target, null,
|
||||||
CircleCropTransformation()
|
CircleCropTransformation()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -256,10 +256,10 @@ class SettingsController : BaseController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun removeCurrentAccount() {
|
private fun removeCurrentAccount() {
|
||||||
val user = usersRepository.getActiveUser()
|
|
||||||
user!!.status = UserStatus.PENDING_DELETE
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
val job = async {
|
val job = async {
|
||||||
|
val user = usersRepository.getActiveUser()
|
||||||
|
user!!.status = UserStatus.PENDING_DELETE
|
||||||
usersRepository.updateUser(user)
|
usersRepository.updateUser(user)
|
||||||
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java)
|
val accountRemovalWork = OneTimeWorkRequest.Builder(AccountRemovalWorker::class.java)
|
||||||
.build()
|
.build()
|
||||||
@ -274,13 +274,14 @@ class SettingsController : BaseController() {
|
|||||||
onAttach(view!!)
|
onAttach(view!!)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
router.setRoot(RouterTransaction.with(
|
withContext(Dispatchers.Main) {
|
||||||
ServerSelectionController()
|
router.setRoot(RouterTransaction.with(
|
||||||
)
|
ServerSelectionController()
|
||||||
.pushChangeHandler(VerticalChangeHandler())
|
)
|
||||||
.popChangeHandler(VerticalChangeHandler())
|
.pushChangeHandler(VerticalChangeHandler())
|
||||||
)
|
.popChangeHandler(VerticalChangeHandler())
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,7 +294,7 @@ class SettingsController : BaseController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
var hasMultipleUsers: Boolean = false
|
var hasMultipleUsers = false
|
||||||
val job = async {
|
val job = async {
|
||||||
currentUser = usersRepository.getActiveUser()
|
currentUser = usersRepository.getActiveUser()
|
||||||
hasMultipleUsers = usersRepository.getUsers().size > 0
|
hasMultipleUsers = usersRepository.getUsers().size > 0
|
||||||
|
@ -37,12 +37,21 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
|
|||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.adapters.items.AdvancedUserItem
|
import com.nextcloud.talk.adapters.items.AdvancedUserItem
|
||||||
import com.nextcloud.talk.controllers.base.BaseController
|
import com.nextcloud.talk.controllers.base.BaseController
|
||||||
|
import com.nextcloud.talk.models.ImportAccount
|
||||||
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
import com.nextcloud.talk.newarch.local.models.other.UserStatus
|
||||||
import com.nextcloud.talk.utils.AccountUtils
|
import com.nextcloud.talk.utils.AccountUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils
|
import com.nextcloud.talk.utils.database.user.UserUtils
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import java.net.CookieManager
|
import java.net.CookieManager
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -53,7 +62,7 @@ class SwitchAccountController : BaseController {
|
|||||||
internal var recyclerView: RecyclerView? = null
|
internal var recyclerView: RecyclerView? = null
|
||||||
|
|
||||||
val cookieManager: CookieManager by inject()
|
val cookieManager: CookieManager by inject()
|
||||||
val userUtils: UserUtils by inject()
|
val usersRepository: UsersRepository by inject()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@BindView(R.id.swipe_refresh_layout)
|
@BindView(R.id.swipe_refresh_layout)
|
||||||
@ -75,30 +84,13 @@ class SwitchAccountController : BaseController {
|
|||||||
private val onSwitchItemClickListener = FlexibleAdapter.OnItemClickListener { view, position ->
|
private val onSwitchItemClickListener = FlexibleAdapter.OnItemClickListener { view, position ->
|
||||||
if (userItems.size > position) {
|
if (userItems.size > position) {
|
||||||
val userEntity = (userItems[position] as AdvancedUserItem).entity
|
val userEntity = (userItems[position] as AdvancedUserItem).entity
|
||||||
/*userUtils!!.createOrUpdateUser(null, null, null, null, null, true, null, userEntity!!.getId(), null, null, null)
|
GlobalScope.launch {
|
||||||
.`as`(AutoDispose.autoDisposable<Any>(scopeProvider))
|
usersRepository.setUserAsActiveWithId(userEntity!!.id!!)
|
||||||
.subscribe(object : Observer<UserEntity> {
|
cookieManager.cookieStore.removeAll()
|
||||||
override fun onSubscribe(d: Disposable) {
|
withContext(Dispatchers.Main) {
|
||||||
|
router.popCurrentController()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
override fun onNext(userEntity: UserEntity) {
|
|
||||||
cookieManager!!.cookieStore.removeAll()
|
|
||||||
|
|
||||||
userUtils!!.disableAllUsersWithoutId(userEntity.getId())
|
|
||||||
if (activity != null) {
|
|
||||||
activity!!.runOnUiThread { router.popCurrentController() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
})*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@ -130,7 +122,69 @@ class SwitchAccountController : BaseController {
|
|||||||
return inflater.inflate(R.layout.controller_generic_rv, container, false)
|
return inflater.inflate(R.layout.controller_generic_rv, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewBound(view: View) {
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup
|
||||||
|
): View {
|
||||||
|
swipeRefreshLayout?.isEnabled = false
|
||||||
|
actionBar?.show()
|
||||||
|
|
||||||
|
adapter = FlexibleAdapter(userItems, activity, false)
|
||||||
|
GlobalScope.launch {
|
||||||
|
val users = usersRepository.getUsers()
|
||||||
|
var userEntity: UserNgEntity
|
||||||
|
var participant: Participant
|
||||||
|
|
||||||
|
if (isAccountImport) {
|
||||||
|
var account: Account
|
||||||
|
var importAccount: ImportAccount
|
||||||
|
for (accountObject in AccountUtils.findAccounts(users)) {
|
||||||
|
account = accountObject
|
||||||
|
importAccount = AccountUtils.getInformationFromAccount(account)
|
||||||
|
|
||||||
|
participant = Participant()
|
||||||
|
participant.name = importAccount.username
|
||||||
|
participant.userId = importAccount.username
|
||||||
|
userEntity = UserNgEntity(-1, "!", "!", importAccount.baseUrl)
|
||||||
|
userItems.add(AdvancedUserItem(participant, userEntity, account))
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter!!.addListener(onImportItemClickListener)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter!!.updateDataSet(userItems, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (userEntityObject in users) {
|
||||||
|
userEntity = userEntityObject
|
||||||
|
if (userEntity.status != UserStatus.ACTIVE) {
|
||||||
|
participant = Participant()
|
||||||
|
participant.name = userEntity.displayName
|
||||||
|
|
||||||
|
val userId: String
|
||||||
|
|
||||||
|
if (userEntity.userId != null) {
|
||||||
|
userId = userEntity.userId
|
||||||
|
} else {
|
||||||
|
userId = userEntity.username
|
||||||
|
}
|
||||||
|
participant.userId = userId
|
||||||
|
userItems.add(AdvancedUserItem(participant, userEntity, null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter!!.addListener(onSwitchItemClickListener)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter!!.updateDataSet(userItems, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return super.onCreateView(inflater, container)
|
||||||
|
}
|
||||||
|
override fun onViewBound(view: View) {
|
||||||
super.onViewBound(view)
|
super.onViewBound(view)
|
||||||
swipeRefreshLayout!!.isEnabled = false
|
swipeRefreshLayout!!.isEnabled = false
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ class NotificationWorker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val request = Images().getRequestForUrl(
|
val request = Images().getRequestForUrl(
|
||||||
Coil.loader(), context!!, avatarUrl!!, null,
|
Coil.loader(), context!!, avatarUrl!!, signatureVerification!!.userEntity,
|
||||||
target, null, CircleCropTransformation()
|
target, null, CircleCropTransformation()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
|
|||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.converters.*
|
import com.nextcloud.talk.models.json.converters.*
|
||||||
import com.nextcloud.talk.models.json.participants.Participant
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
|
import com.nextcloud.talk.newarch.local.models.ConversationEntity
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
import lombok.Data
|
import lombok.Data
|
||||||
import org.parceler.Parcel
|
import org.parceler.Parcel
|
||||||
@ -42,8 +43,6 @@ class Conversation {
|
|||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@NonNull
|
@NonNull
|
||||||
var internalUserId: Long? = null
|
var internalUserId: Long? = null
|
||||||
@JsonIgnore
|
|
||||||
var internalId: Long? = null
|
|
||||||
@JsonField(name = ["id"])
|
@JsonField(name = ["id"])
|
||||||
var conversationId: String? = null
|
var conversationId: String? = null
|
||||||
@JsonField(name = ["token"])
|
@JsonField(name = ["token"])
|
||||||
|
@ -20,9 +20,7 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.newarch.data.repository.offline
|
package com.nextcloud.talk.newarch.data.repository.offline
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.*
|
||||||
import androidx.lifecycle.Transformations
|
|
||||||
import androidx.lifecycle.map
|
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
||||||
import com.nextcloud.talk.newarch.local.dao.ConversationsDao
|
import com.nextcloud.talk.newarch.local.dao.ConversationsDao
|
||||||
@ -58,14 +56,11 @@ class ConversationsRepositoryImpl(val conversationsDao: ConversationsDao) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> {
|
override fun getConversationsForUser(userId: Long): LiveData<List<Conversation>> {
|
||||||
return Transformations.distinctUntilChanged(conversationsDao
|
return conversationsDao.getConversationsForUser(userId).distinctUntilChanged().map { data ->
|
||||||
.getConversationsForUser(userId)
|
data.map {
|
||||||
.map { data ->
|
it.toConversation()
|
||||||
data.map {
|
}
|
||||||
it.toConversation()
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getConversationForUserWithToken(userId: Long, token: String): Conversation? {
|
override suspend fun getConversationForUserWithToken(userId: Long, token: String): Conversation? {
|
||||||
|
@ -21,13 +21,15 @@
|
|||||||
package com.nextcloud.talk.newarch.data.repository.offline
|
package com.nextcloud.talk.newarch.data.repository.offline
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.Transformations
|
||||||
|
import androidx.lifecycle.distinctUntilChanged
|
||||||
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
import com.nextcloud.talk.newarch.local.dao.UsersDao
|
import com.nextcloud.talk.newarch.local.dao.UsersDao
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
|
||||||
class UsersRepositoryImpl(val usersDao: UsersDao) : UsersRepository {
|
class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
|
||||||
override fun getActiveUserLiveData(): LiveData<UserNgEntity> {
|
override fun getActiveUserLiveData(): LiveData<UserNgEntity> {
|
||||||
return usersDao.getActiveUserLiveData()
|
return usersDao.getActiveUserLiveData().distinctUntilChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getActiveUser(): UserNgEntity {
|
override fun getActiveUser(): UserNgEntity {
|
||||||
|
@ -55,18 +55,26 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
|
|||||||
return apiService.getConversation(userEntity.getCredentials(), conversationToken)
|
return apiService.getConversation(userEntity.getCredentials(), conversationToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun joinConversationForUser(userNgEntity: UserNgEntity, conversationToken: String, conversationPassword: String?): RoomOverall {
|
||||||
|
return apiService.joinConversation(userNgEntity.getCredentials(), ApiUtils.getUrlForSettingMyselfAsActiveParticipant(userNgEntity.baseUrl, conversationToken), conversationPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun exitConversationForUser(userNgEntity: UserNgEntity, conversationToken: String): GenericOverall {
|
||||||
|
return apiService.exitConversation(userNgEntity.getCredentials(), ApiUtils.getUrlForSettingMyselfAsActiveParticipant(userNgEntity.baseUrl, conversationToken))
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun setFavoriteValueForConversation(
|
override suspend fun setFavoriteValueForConversation(
|
||||||
user: UserNgEntity,
|
user: UserNgEntity,
|
||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
favorite: Boolean
|
favorite: Boolean
|
||||||
): GenericOverall {
|
): GenericOverall {
|
||||||
if (favorite) {
|
return if (favorite) {
|
||||||
return apiService.addConversationToFavorites(
|
apiService.addConversationToFavorites(
|
||||||
user.getCredentials(),
|
user.getCredentials(),
|
||||||
ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
|
ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return apiService.removeConversationFromFavorites(
|
apiService.removeConversationFromFavorites(
|
||||||
user.getCredentials(),
|
user.getCredentials(),
|
||||||
ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
|
ApiUtils.getUrlForConversationFavorites(user.baseUrl, conversation.token)
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,7 @@ package com.nextcloud.talk.newarch.data.source.remote
|
|||||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
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.*
|
import retrofit2.http.*
|
||||||
|
|
||||||
interface ApiService {
|
interface ApiService {
|
||||||
@ -63,4 +64,14 @@ interface ApiService {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
suspend fun getConversation(@Header("Authorization") authorization: String, @Url url: String): RoomOverall
|
suspend fun getConversation(@Header("Authorization") authorization: String, @Url url: String): RoomOverall
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST
|
||||||
|
suspend fun joinConversation(@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String, @Field("password") password: String?): RoomOverall
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
suspend fun exitConversation(@Header("Authorization") authorization: String,
|
||||||
|
@Url url: String): GenericOverall
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,4 +47,15 @@ interface NextcloudTalkRepository {
|
|||||||
userEntity: UserNgEntity,
|
userEntity: UserNgEntity,
|
||||||
conversationToken: String
|
conversationToken: String
|
||||||
): RoomOverall
|
): RoomOverall
|
||||||
|
|
||||||
|
suspend fun joinConversationForUser(
|
||||||
|
userNgEntity: UserNgEntity,
|
||||||
|
conversationToken: String,
|
||||||
|
conversationPassword: String?
|
||||||
|
): RoomOverall
|
||||||
|
|
||||||
|
suspend fun exitConversationForUser(
|
||||||
|
userNgEntity: UserNgEntity,
|
||||||
|
conversationToken: String
|
||||||
|
): GenericOverall
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.usecases
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||||
|
import org.koin.core.parameter.DefinitionParameters
|
||||||
|
|
||||||
|
class ExitConversationUseCase constructor(
|
||||||
|
private val nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler?
|
||||||
|
) : UseCase<GenericOverall, Any?>(apiErrorHandler) {
|
||||||
|
|
||||||
|
override suspend fun run(params: Any?): GenericOverall {
|
||||||
|
val definitionParameters = params as DefinitionParameters
|
||||||
|
return nextcloudTalkRepository.exitConversationForUser(
|
||||||
|
definitionParameters[0],
|
||||||
|
definitionParameters[1])
|
||||||
|
}
|
||||||
|
}
|
@ -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.domain.usecases
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||||
|
import org.koin.core.parameter.DefinitionParameters
|
||||||
|
|
||||||
|
class JoinConversationUseCase constructor(
|
||||||
|
private val nextcloudTalkRepository: NextcloudTalkRepository,
|
||||||
|
apiErrorHandler: ApiErrorHandler?
|
||||||
|
) : UseCase<RoomOverall, Any?>(apiErrorHandler) {
|
||||||
|
|
||||||
|
override suspend fun run(params: Any?): RoomOverall {
|
||||||
|
val definitionParameters = params as DefinitionParameters
|
||||||
|
return nextcloudTalkRepository.joinConversationForUser(
|
||||||
|
definitionParameters[0],
|
||||||
|
definitionParameters[1],
|
||||||
|
definitionParameters[2]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -355,7 +355,8 @@ class ChatView : BaseView(), MessageHolders.ContentChecker<IMessage>, MessagesLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.startsWith(viewModel.user.baseUrl) && url.contains("index.php/core/preview?fileId=")) {
|
val needsAuthBasedOnUrl = url.contains("index.php/core/preview?fileId=") || url.contains("index.php/avatar/")
|
||||||
|
if (url.startsWith(viewModel.user.baseUrl) && needsAuthBasedOnUrl) {
|
||||||
addHeader("Authorization", viewModel.user.getCredentials())
|
addHeader("Authorization", viewModel.user.getCredentials())
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -384,7 +385,7 @@ class ChatView : BaseView(), MessageHolders.ContentChecker<IMessage>, MessagesLi
|
|||||||
imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
|
imageLoader, context, ApiUtils.getUrlForAvatarWithNameAndPixels(
|
||||||
viewModel.user.baseUrl,
|
viewModel.user.baseUrl,
|
||||||
it.name, avatarSize / 2
|
it.name, avatarSize / 2
|
||||||
), null, target, this,
|
), viewModel.user, target, this,
|
||||||
CircleCropTransformation()
|
CircleCropTransformation()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,16 +2,37 @@ package com.nextcloud.talk.newarch.features.chat
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
|
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.domain.repository.offline.ConversationsRepository
|
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
|
import com.nextcloud.talk.newarch.features.conversationsList.ConversationsListViewState
|
||||||
|
import com.nextcloud.talk.newarch.local.models.MessageEntity
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
|
|
||||||
class ChatViewModel constructor(application: Application, private val conversationsRepository: ConversationsRepository) : BaseViewModel<ChatView>(application) {
|
class ChatViewModel constructor(application: Application,
|
||||||
|
private val joinConversationUseCase: JoinConversationUseCase,
|
||||||
|
private val exitConversationUseCase: ExitConversationUseCase,
|
||||||
|
private val conversationsRepository: ConversationsRepository,
|
||||||
|
private val messagesRepository: MessagesRepository) : BaseViewModel<ChatView>(application) {
|
||||||
lateinit var user: UserNgEntity
|
lateinit var user: UserNgEntity
|
||||||
val conversation: MutableLiveData<Conversation?> = MutableLiveData()
|
val conversation: MutableLiveData<Conversation?> = MutableLiveData()
|
||||||
|
val messagesLiveData = Transformations.switchMap(conversation) {
|
||||||
|
it?.let {
|
||||||
|
messagesRepository.getMessagesWithUserForConversation(it.conversationId!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
var conversationPassword: String? = null
|
var conversationPassword: String? = null
|
||||||
|
|
||||||
|
|
||||||
@ -23,6 +44,38 @@ class ChatViewModel constructor(application: Application, private val conversati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun joinConversation() {
|
||||||
|
joinConversationUseCase.invoke(viewModelScope, parametersOf(
|
||||||
|
user,
|
||||||
|
conversation.value!!.token,
|
||||||
|
conversationPassword
|
||||||
|
),
|
||||||
|
object : UseCaseResponse<RoomOverall> {
|
||||||
|
override suspend fun onSuccess(result: RoomOverall) {
|
||||||
|
conversationsRepository.saveConversationsForUser(user.id!!, listOf(result.ocs.data))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
// what do we do on error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun exitConversation() {
|
||||||
|
exitConversationUseCase.invoke(backgroundScope, parametersOf(
|
||||||
|
user,
|
||||||
|
conversation.value!!.token
|
||||||
|
),
|
||||||
|
object : UseCaseResponse<GenericOverall> {
|
||||||
|
override suspend fun onSuccess(result: GenericOverall) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
// what do we do on error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fun sendMessage(message: CharSequence) {
|
fun sendMessage(message: CharSequence) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,21 @@ 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.offline.ConversationsRepository
|
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.MessagesRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.ExitConversationUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
|
||||||
|
|
||||||
class ChatViewModelFactory constructor(
|
class ChatViewModelFactory constructor(
|
||||||
private val application: Application,
|
private val application: Application,
|
||||||
private val conversationsRepository: ConversationsRepository
|
private val joinConversationUseCase: JoinConversationUseCase,
|
||||||
|
private val exitConversationUseCase: ExitConversationUseCase,
|
||||||
|
private val conversationsRepository: ConversationsRepository,
|
||||||
|
private val messagesRepository: MessagesRepository
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return ChatViewModel(
|
return ChatViewModel(
|
||||||
application, conversationsRepository
|
application, joinConversationUseCase, exitConversationUseCase, conversationsRepository, messagesRepository
|
||||||
) as T
|
) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,15 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
import androidx.appcompat.widget.SearchView.OnQueryTextListener
|
||||||
import androidx.core.view.MenuItemCompat
|
import androidx.core.view.MenuItemCompat
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.distinctUntilChanged
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
import butterknife.OnClick
|
import butterknife.OnClick
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
@ -74,11 +77,12 @@ import java.util.*
|
|||||||
class ConversationsListView : BaseView(), OnQueryTextListener,
|
class ConversationsListView : BaseView(), OnQueryTextListener,
|
||||||
OnItemClickListener, OnItemLongClickListener {
|
OnItemClickListener, OnItemLongClickListener {
|
||||||
|
|
||||||
lateinit var viewModel: ConversationsListViewModel
|
private lateinit var viewModel: ConversationsListViewModel
|
||||||
val factory: ConversationListViewModelFactory by inject()
|
val factory: ConversationListViewModelFactory by inject()
|
||||||
val imageLoader: ImageLoader by inject()
|
private val imageLoader: ImageLoader by inject()
|
||||||
|
private val viewState: MutableLiveData<ConversationsListViewState> = MutableLiveData(LOADING)
|
||||||
|
|
||||||
private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, true)
|
private val recyclerViewAdapter = FlexibleAdapter(mutableListOf(), null, false)
|
||||||
|
|
||||||
private var searchItem: MenuItem? = null
|
private var searchItem: MenuItem? = null
|
||||||
private var settingsItem: MenuItem? = null
|
private var settingsItem: MenuItem? = null
|
||||||
@ -178,9 +182,12 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
searchView!!.imeOptions = imeOptions
|
searchView!!.imeOptions = imeOptions
|
||||||
searchView!!.queryHint = resources?.getString(R.string.nc_search)
|
searchView!!.queryHint = resources?.getString(R.string.nc_search)
|
||||||
searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
|
searchView!!.setSearchableInfo(searchManager.getSearchableInfo(activity!!.componentName))
|
||||||
|
|
||||||
searchView!!.setOnQueryTextListener(this)
|
searchView!!.setOnQueryTextListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRestoreViewState(view: View, savedViewState: Bundle) {
|
||||||
|
super.onRestoreViewState(view, savedViewState)
|
||||||
|
viewModel.loadConversations()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||||
@ -208,71 +215,15 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
loadAvatar()
|
loadAvatar()
|
||||||
})
|
})
|
||||||
|
|
||||||
viewState.observe(this@ConversationsListView, Observer { value ->
|
|
||||||
when (value) {
|
|
||||||
LOADING -> {
|
|
||||||
view?.swipeRefreshLayoutView?.isEnabled = false
|
|
||||||
view?.loadingStateView?.visibility = View.VISIBLE
|
|
||||||
view?.stateWithMessageView?.visibility = View.GONE
|
|
||||||
view?.dataStateView?.visibility = View.GONE
|
|
||||||
view?.floatingActionButton?.visibility = View.GONE
|
|
||||||
searchItem?.isVisible = false
|
|
||||||
}
|
|
||||||
LOADED -> {
|
|
||||||
view?.swipeRefreshLayoutView?.isEnabled = true
|
|
||||||
view?.swipeRefreshLayoutView?.post {
|
|
||||||
view?.swipeRefreshLayoutView?.isRefreshing = false
|
|
||||||
}
|
|
||||||
view?.loadingStateView?.visibility = View.GONE
|
|
||||||
view?.stateWithMessageView?.visibility = View.GONE
|
|
||||||
view?.dataStateView?.visibility = View.VISIBLE
|
|
||||||
view?.floatingActionButton?.visibility = View.VISIBLE
|
|
||||||
searchItem?.isVisible = true
|
|
||||||
}
|
|
||||||
LOADED_EMPTY, FAILED -> {
|
|
||||||
view?.swipeRefreshLayoutView?.post {
|
|
||||||
view?.swipeRefreshLayoutView?.isRefreshing = false
|
|
||||||
}
|
|
||||||
view?.swipeRefreshLayoutView?.isEnabled = true
|
|
||||||
view?.loadingStateView?.visibility = View.GONE
|
|
||||||
view?.dataStateView?.visibility = View.GONE
|
|
||||||
searchItem?.isVisible = false
|
|
||||||
|
|
||||||
if (value.equals(FAILED)) {
|
|
||||||
view?.stateWithMessageView?.errorStateTextView?.text = messageData
|
|
||||||
if (messageData.equals(
|
|
||||||
context.resources.getString(R.string.nc_no_connection_error)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
view?.stateWithMessageView?.errorStateImageView?.setImageResource(
|
|
||||||
drawable.ic_signal_wifi_off_white_24dp
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
view?.stateWithMessageView?.errorStateImageView?.setImageResource(
|
|
||||||
drawable.ic_announcement_white_24dp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
view?.floatingActionButton?.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
view?.floatingActionButton?.visibility = View.VISIBLE
|
|
||||||
view?.stateWithMessageView?.errorStateTextView?.text =
|
|
||||||
resources?.getText(R.string.nc_conversations_empty)
|
|
||||||
view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
|
|
||||||
}
|
|
||||||
|
|
||||||
view?.stateWithMessageView?.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// We should not be here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
conversationsLiveData.observe(this@ConversationsListView, Observer {
|
conversationsLiveData.observe(this@ConversationsListView, Observer {
|
||||||
if (it.isEmpty()) {
|
if (it.isEmpty()) {
|
||||||
viewState.value = LOADED_EMPTY
|
if (viewState.value != LOADED_EMPTY) {
|
||||||
|
viewState.value = LOADED_EMPTY
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
viewState.value = LOADED
|
if (viewState.value != LOADED) {
|
||||||
|
viewState.value = LOADED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newConversations = mutableListOf<ConversationItem>()
|
val newConversations = mutableListOf<ConversationItem>()
|
||||||
@ -297,6 +248,67 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewState.observe(this@ConversationsListView, Observer { value ->
|
||||||
|
when (value) {
|
||||||
|
LOADING -> {
|
||||||
|
view?.swipeRefreshLayoutView?.isEnabled = false
|
||||||
|
view?.loadingStateView?.visibility = View.VISIBLE
|
||||||
|
view?.stateWithMessageView?.visibility = View.GONE
|
||||||
|
view?.dataStateView?.visibility = View.GONE
|
||||||
|
view?.floatingActionButton?.visibility = View.GONE
|
||||||
|
searchItem?.isVisible = false
|
||||||
|
}
|
||||||
|
LOADED -> {
|
||||||
|
view?.swipeRefreshLayoutView?.isEnabled = true
|
||||||
|
view?.swipeRefreshLayoutView?.post {
|
||||||
|
view?.swipeRefreshLayoutView?.isRefreshing = false
|
||||||
|
}
|
||||||
|
view?.loadingStateView?.visibility = View.GONE
|
||||||
|
view?.stateWithMessageView?.visibility = View.GONE
|
||||||
|
view?.dataStateView?.visibility = View.VISIBLE
|
||||||
|
view?.floatingActionButton?.visibility = View.VISIBLE
|
||||||
|
searchItem?.isVisible = true
|
||||||
|
}
|
||||||
|
LOADED_EMPTY, FAILED -> {
|
||||||
|
view?.swipeRefreshLayoutView?.post {
|
||||||
|
view?.swipeRefreshLayoutView?.isRefreshing = false
|
||||||
|
}
|
||||||
|
view?.swipeRefreshLayoutView?.isEnabled = true
|
||||||
|
view?.loadingStateView?.visibility = View.GONE
|
||||||
|
view?.dataStateView?.visibility = View.GONE
|
||||||
|
searchItem?.isVisible = false
|
||||||
|
|
||||||
|
if (value.equals(FAILED)) {
|
||||||
|
view?.stateWithMessageView?.errorStateTextView?.text = viewModel.messageData
|
||||||
|
if (viewModel.messageData.equals(
|
||||||
|
context.resources.getString(R.string.nc_no_connection_error)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
view?.stateWithMessageView?.errorStateImageView?.setImageResource(
|
||||||
|
drawable.ic_signal_wifi_off_white_24dp
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
view?.stateWithMessageView?.errorStateImageView?.setImageResource(
|
||||||
|
drawable.ic_announcement_white_24dp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
view?.floatingActionButton?.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
view?.floatingActionButton?.visibility = View.VISIBLE
|
||||||
|
view?.stateWithMessageView?.errorStateTextView?.text =
|
||||||
|
resources?.getText(R.string.nc_conversations_empty)
|
||||||
|
view?.stateWithMessageView?.errorStateImageView?.setImageResource(drawable.ic_logo)
|
||||||
|
}
|
||||||
|
|
||||||
|
view?.stateWithMessageView?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// We should not be here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
return super.onCreateView(inflater, container)
|
return super.onCreateView(inflater, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +323,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
|
|||||||
|
|
||||||
@OnClick(R.id.stateWithMessageView)
|
@OnClick(R.id.stateWithMessageView)
|
||||||
fun onStateWithMessageViewClick() {
|
fun onStateWithMessageViewClick() {
|
||||||
if (viewModel.viewState.equals(LOADED_EMPTY)) {
|
if (viewState.value!! == LOADED_EMPTY) {
|
||||||
openNewConversationScreen()
|
openNewConversationScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ 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.features.conversationsList.ConversationsListViewState.LOADING
|
|
||||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
import com.nextcloud.talk.utils.ShareUtils
|
import com.nextcloud.talk.utils.ShareUtils
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -57,14 +56,11 @@ class ConversationsListViewModel constructor(
|
|||||||
usersRepository: UsersRepository
|
usersRepository: UsersRepository
|
||||||
) : BaseViewModel<ConversationsListView>(application) {
|
) : BaseViewModel<ConversationsListView>(application) {
|
||||||
|
|
||||||
val viewState = MutableLiveData(LOADING)
|
|
||||||
var messageData: String? = null
|
var messageData: String? = null
|
||||||
val searchQuery = MutableLiveData<String>()
|
val searchQuery = MutableLiveData<String>()
|
||||||
val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
|
val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
|
||||||
val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
|
val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
|
||||||
if (viewState.value != LOADING) {
|
loadConversations()
|
||||||
viewState.value = LOADING
|
|
||||||
}
|
|
||||||
conversationsRepository.getConversationsForUser(it.id!!)
|
conversationsRepository.getConversationsForUser(it.id!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
package com.nextcloud.talk.newarch.features.conversationsList
|
package com.nextcloud.talk.newarch.features.conversationsList
|
||||||
|
|
||||||
enum class ConversationsListViewState {
|
enum class ConversationsListViewState {
|
||||||
|
INITIAL_LOAD,
|
||||||
LOADING,
|
LOADING,
|
||||||
LOADED_EMPTY,
|
LOADED_EMPTY,
|
||||||
LOADED,
|
LOADED,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.newarch.local.models
|
package com.nextcloud.talk.newarch.local.models
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import androidx.room.ForeignKey.CASCADE
|
import androidx.room.ForeignKey.CASCADE
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
@ -42,7 +43,7 @@ import java.util.*
|
|||||||
)
|
)
|
||||||
data class ConversationEntity(
|
data class ConversationEntity(
|
||||||
@PrimaryKey @ColumnInfo(name = "id") var id: String,
|
@PrimaryKey @ColumnInfo(name = "id") var id: String,
|
||||||
@ColumnInfo(name = "user_id") var user: Long? = null,
|
@ColumnInfo(name = "user_id") var userId: Long? = null,
|
||||||
@ColumnInfo(name = "conversation_id") var conversationId: String? = null,
|
@ColumnInfo(name = "conversation_id") var conversationId: String? = null,
|
||||||
@ColumnInfo(name = "token") var token: String? = null,
|
@ColumnInfo(name = "token") var token: String? = null,
|
||||||
@ColumnInfo(name = "name") var name: String? = null,
|
@ColumnInfo(name = "name") var name: String? = null,
|
||||||
@ -74,11 +75,52 @@ data class ConversationEntity(
|
|||||||
@ColumnInfo(name = "last_read_message") var lastReadMessageId: Long = 0,
|
@ColumnInfo(name = "last_read_message") var lastReadMessageId: Long = 0,
|
||||||
@ColumnInfo(name = "modified_at") var modifiedAt: Long? = null,
|
@ColumnInfo(name = "modified_at") var modifiedAt: Long? = null,
|
||||||
@ColumnInfo(name = "changing") var changing: Boolean = false
|
@ColumnInfo(name = "changing") var changing: Boolean = false
|
||||||
)
|
) {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as ConversationEntity
|
||||||
|
|
||||||
|
if (id != other.id) return false
|
||||||
|
if (userId != other.userId) return false
|
||||||
|
if (conversationId != other.conversationId) return false
|
||||||
|
if (token != other.token) return false
|
||||||
|
if (name != other.name) return false
|
||||||
|
if (displayName != other.displayName) return false
|
||||||
|
if (type != other.type) return false
|
||||||
|
if (count != other.count) return false
|
||||||
|
if (numberOfGuests != other.numberOfGuests) return false
|
||||||
|
if (participantsCount != other.participantsCount) return false
|
||||||
|
if (participantType != other.participantType) return false
|
||||||
|
if (hasPassword != other.hasPassword) return false
|
||||||
|
if (sessionId != other.sessionId) return false
|
||||||
|
if (favorite != other.favorite) return false
|
||||||
|
if (lastActivity != other.lastActivity) return false
|
||||||
|
if (unreadMessages != other.unreadMessages) return false
|
||||||
|
if (unreadMention != other.unreadMention) return false
|
||||||
|
if (lastMessage?.internalMessageId != other.lastMessage?.internalMessageId) return false
|
||||||
|
if (objectType != other.objectType) return false
|
||||||
|
if (notificationLevel != other.notificationLevel) return false
|
||||||
|
if (conversationReadOnlyState != other.conversationReadOnlyState) return false
|
||||||
|
if (lobbyState != other.lobbyState) return false
|
||||||
|
if (lobbyTimer != other.lobbyTimer) return false
|
||||||
|
if (lastReadMessageId != other.lastReadMessageId) return false
|
||||||
|
if (changing != other.changing) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = userId?.hashCode() ?: 0
|
||||||
|
result = 31 * result + (token?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun ConversationEntity.toConversation(): Conversation {
|
fun ConversationEntity.toConversation(): Conversation {
|
||||||
val conversation = Conversation()
|
val conversation = Conversation()
|
||||||
conversation.internalUserId = this.user
|
conversation.internalUserId = this.userId
|
||||||
conversation.conversationId = this.conversationId
|
conversation.conversationId = this.conversationId
|
||||||
conversation.type = this.type
|
conversation.type = this.type
|
||||||
conversation.token = this.token
|
conversation.token = this.token
|
||||||
@ -111,7 +153,7 @@ fun ConversationEntity.toConversation(): Conversation {
|
|||||||
|
|
||||||
fun Conversation.toConversationEntity(): ConversationEntity {
|
fun Conversation.toConversationEntity(): ConversationEntity {
|
||||||
val conversationEntity = ConversationEntity(this.internalUserId.toString() + "@" + this.token)
|
val conversationEntity = ConversationEntity(this.internalUserId.toString() + "@" + this.token)
|
||||||
conversationEntity.user = this.internalUserId
|
conversationEntity.userId = this.internalUserId
|
||||||
conversationEntity.conversationId = this.conversationId
|
conversationEntity.conversationId = this.conversationId
|
||||||
conversationEntity.token = this.token
|
conversationEntity.token = this.token
|
||||||
conversationEntity.name = this.name
|
conversationEntity.name = this.name
|
||||||
|
@ -39,7 +39,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType
|
|||||||
)
|
)
|
||||||
data class MessageEntity(
|
data class MessageEntity(
|
||||||
@PrimaryKey @ColumnInfo(name = "id") var id: String,
|
@PrimaryKey @ColumnInfo(name = "id") var id: String,
|
||||||
@ColumnInfo(name = "conversation_id") var conversation: String,
|
@ColumnInfo(name = "conversation_id") var conversationId: String,
|
||||||
@ColumnInfo(name = "message_id") var messageId: Long = 0,
|
@ColumnInfo(name = "message_id") var messageId: Long = 0,
|
||||||
@ColumnInfo(name = "actor_id") var actorId: String? = null,
|
@ColumnInfo(name = "actor_id") var actorId: String? = null,
|
||||||
@ColumnInfo(name = "actor_type") var actorType: String? = null,
|
@ColumnInfo(name = "actor_type") var actorType: String? = null,
|
||||||
@ -56,7 +56,7 @@ data class MessageEntity(
|
|||||||
fun MessageEntity.toChatMessage(): ChatMessage {
|
fun MessageEntity.toChatMessage(): ChatMessage {
|
||||||
val chatMessage = ChatMessage()
|
val chatMessage = ChatMessage()
|
||||||
chatMessage.internalMessageId = this.id
|
chatMessage.internalMessageId = this.id
|
||||||
chatMessage.internalConversationId = this.conversation
|
chatMessage.internalConversationId = this.conversationId
|
||||||
chatMessage.jsonMessageId = this.messageId
|
chatMessage.jsonMessageId = this.messageId
|
||||||
chatMessage.actorType = this.actorType
|
chatMessage.actorType = this.actorType
|
||||||
chatMessage.actorId = this.actorId
|
chatMessage.actorId = this.actorId
|
||||||
|
@ -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.utils
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||||
|
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetConversationUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.JoinConversationUseCase
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import org.koin.core.KoinComponent
|
||||||
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import java.net.CookieManager
|
||||||
|
|
||||||
|
class ConversationsManager constructor(usersRepository: UsersRepository,
|
||||||
|
cookieManager: CookieManager,
|
||||||
|
okHttpClient: OkHttpClient,
|
||||||
|
private val conversationsRepository: ConversationsRepository,
|
||||||
|
private val joinConversationUseCase: JoinConversationUseCase,
|
||||||
|
private val getConversationUseCase: GetConversationUseCase): KoinComponent {
|
||||||
|
private val applicationScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
private val previousUser: UserNgEntity? = null
|
||||||
|
private val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
|
||||||
|
private var currentConversation: Conversation? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
currentUserLiveData.observeForever { user ->
|
||||||
|
cookieManager.cookieStore.removeAll()
|
||||||
|
okHttpClient.dispatcher().cancelAll()
|
||||||
|
currentConversation = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getConversation(conversationToken: String) {
|
||||||
|
val currentUser = currentUserLiveData.value
|
||||||
|
getConversationUseCase.invoke(applicationScope, parametersOf(
|
||||||
|
currentUser,
|
||||||
|
conversationToken
|
||||||
|
),
|
||||||
|
object : UseCaseResponse<RoomOverall> {
|
||||||
|
override suspend fun onSuccess(result: RoomOverall) {
|
||||||
|
currentUser?.let {
|
||||||
|
conversationsRepository.saveConversationsForUser(it.id!!, listOf(result.ocs.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
// what do we do on error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun joinConversation(conversationToken: String, conversationPassword: String?, conversationsManagerInterface: ConversationsManagerInterface) {
|
||||||
|
val currentUser = currentUserLiveData.value
|
||||||
|
joinConversationUseCase.invoke(applicationScope, parametersOf(
|
||||||
|
currentUser,
|
||||||
|
conversationToken,
|
||||||
|
conversationPassword
|
||||||
|
),
|
||||||
|
object : UseCaseResponse<RoomOverall> {
|
||||||
|
override suspend fun onSuccess(result: RoomOverall) {
|
||||||
|
currentUser?.let {
|
||||||
|
conversationsRepository.saveConversationsForUser(it.id!!, listOf(result.ocs.data))
|
||||||
|
currentConversation = conversationsRepository.getConversationForUserWithToken(it.id!!, result.ocs!!.data!!.token!!)
|
||||||
|
conversationsManagerInterface.joinedConversationForUser(it, currentConversation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(errorModel: ErrorModel?) {
|
||||||
|
// what do we do on error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils
|
||||||
|
|
||||||
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
|
|
||||||
|
interface ConversationsManagerInterface {
|
||||||
|
fun joinedConversationForUser(userNgEntity: UserNgEntity, conversation: Conversation?)
|
||||||
|
}
|
@ -51,9 +51,8 @@ class Images {
|
|||||||
target(target)
|
target(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userEntity != null && url.startsWith(userEntity.baseUrl) && url.contains(
|
if (userEntity != null && url.startsWith(userEntity.baseUrl) && (url.contains(
|
||||||
"index.php/core/preview?fileId="
|
"index.php/core/preview?fileId=") || url.contains("index.php/avatar/"))
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
addHeader("Authorization", userEntity.getCredentials())
|
addHeader("Authorization", userEntity.getCredentials())
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.nextcloud.talk.newarch.utils
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.MainThread
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MediatorLiveData
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class LiveDataTransformations {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new [LiveData] object that does not emit a value until the source LiveData
|
||||||
|
* value has been changed. The value is considered changed if `equals()` yields
|
||||||
|
* `false`.
|
||||||
|
*
|
||||||
|
* @param source the input [LiveData]
|
||||||
|
* @param <X> the generic type parameter of `source`
|
||||||
|
* @return a new [LiveData] of type `X`
|
||||||
|
</X> */
|
||||||
|
@MainThread
|
||||||
|
fun <X> distinctUntilChangedForArray(source: LiveData<X>): LiveData<X> {
|
||||||
|
val outputLiveData = MediatorLiveData<X>()
|
||||||
|
outputLiveData.addSource(source, object : Observer<X> {
|
||||||
|
|
||||||
|
var mFirstTime = true
|
||||||
|
|
||||||
|
override fun onChanged(currentValue: X?) {
|
||||||
|
val previousValue = outputLiveData.value
|
||||||
|
if (mFirstTime && currentValue != null
|
||||||
|
|| (previousValue == null && currentValue != null)) {
|
||||||
|
mFirstTime = false
|
||||||
|
outputLiveData.value = currentValue
|
||||||
|
} else if (previousValue != null) {
|
||||||
|
if (currentValue == null) {
|
||||||
|
outputLiveData.value = currentValue
|
||||||
|
} else {
|
||||||
|
val previousArray: Array<X> = (previousValue as ArrayList<X>).toArray() as Array<X>
|
||||||
|
val currentArray: Array<X> = (currentValue as ArrayList<X>).toArray() as Array<X>
|
||||||
|
|
||||||
|
if (previousArray.size != currentArray.size) {
|
||||||
|
outputLiveData.value = currentValue
|
||||||
|
} else {
|
||||||
|
var counter = 0
|
||||||
|
for(element in previousArray) {
|
||||||
|
if (!element!!.equals(currentArray[counter])) {
|
||||||
|
outputLiveData.value = currentValue
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return outputLiveData
|
||||||
|
}
|
||||||
|
}
|
@ -262,7 +262,7 @@ object DisplayUtils {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val request = Images().getRequestForUrl(Coil.loader(), context, url, null, target, null, CircleCropTransformation())
|
val request = Images().getRequestForUrl(Coil.loader(), context, url, conversationUser, target, null, CircleCropTransformation())
|
||||||
Coil.loader().load(request)
|
Coil.loader().load(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user