Add footer to contacts view

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2020-01-22 23:20:02 +01:00
parent 91f40d0b7f
commit df1e65e238
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
35 changed files with 138 additions and 73 deletions

View File

@ -177,7 +177,7 @@ class MainActivity : BaseActivity(), ActionBarProvider {
private fun openNewConversationScreen() { private fun openNewConversationScreen() {
router?.pushController( router?.pushController(
RouterTransaction.with(ContactsView()) RouterTransaction.with(ContactsView<Any>())
.pushChangeHandler(HorizontalChangeHandler()) .pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler()) .popChangeHandler(HorizontalChangeHandler())
) )

View File

@ -21,9 +21,6 @@
package com.nextcloud.talk.adapters.items package com.nextcloud.talk.adapters.items
import android.content.Context import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView

View File

@ -44,7 +44,6 @@ import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.TextMatchers import com.nextcloud.talk.utils.TextMatchers
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
import com.stfalcon.chatkit.messages.MessageHolders import com.stfalcon.chatkit.messages.MessageHolders
import com.stfalcon.chatkit.utils.DateFormatter
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject

View File

@ -41,7 +41,6 @@ import com.nextcloud.talk.utils.DisplayUtils.getMessageSelector
import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan
import com.nextcloud.talk.utils.TextMatchers import com.nextcloud.talk.utils.TextMatchers
import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder
import com.stfalcon.chatkit.utils.DateFormatter
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
import java.util.* import java.util.*

View File

@ -43,7 +43,10 @@ import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.capabilities.Capabilities import com.nextcloud.talk.models.json.capabilities.Capabilities
import com.nextcloud.talk.models.json.push.PushConfiguration import com.nextcloud.talk.models.json.push.PushConfiguration
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettings import com.nextcloud.talk.models.json.signaling.settings.SignalingSettings
import com.nextcloud.talk.newarch.di.module.* import com.nextcloud.talk.newarch.di.module.CommunicationModule
import com.nextcloud.talk.newarch.di.module.NetworkModule
import com.nextcloud.talk.newarch.di.module.ServiceModule
import com.nextcloud.talk.newarch.di.module.StorageModule
import com.nextcloud.talk.newarch.domain.di.module.UseCasesModule import com.nextcloud.talk.newarch.domain.di.module.UseCasesModule
import com.nextcloud.talk.newarch.features.account.di.module.AccountModule import com.nextcloud.talk.newarch.features.account.di.module.AccountModule
import com.nextcloud.talk.newarch.features.contactsflow.di.module.ContactsFlowModule import com.nextcloud.talk.newarch.features.contactsflow.di.module.ContactsFlowModule

View File

@ -27,7 +27,6 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
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 android.widget.ProgressBar import android.widget.ProgressBar
@ -45,7 +44,6 @@ import butterknife.OnClick
import butterknife.Optional import butterknife.Optional
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
import com.bluelinelabs.logansquare.LoganSquare
import com.kennyc.bottomsheet.BottomSheet import com.kennyc.bottomsheet.BottomSheet
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.MagicCallActivity import com.nextcloud.talk.activities.MagicCallActivity
@ -57,8 +55,6 @@ import com.nextcloud.talk.controllers.bottomsheet.EntryMenuController
import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController import com.nextcloud.talk.controllers.bottomsheet.OperationsMenuController
import com.nextcloud.talk.events.BottomSheetLockEvent import com.nextcloud.talk.events.BottomSheetLockEvent
import com.nextcloud.talk.jobs.AddParticipantsToConversation import com.nextcloud.talk.jobs.AddParticipantsToConversation
import com.nextcloud.talk.models.RetrofitBucket
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
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.conversations.RoomOverall
@ -82,15 +78,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.ResponseBody
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
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.*
import java.util.HashMap
import java.util.HashSet
import kotlin.Comparator
import kotlin.String import kotlin.String
class ContactsController : BaseController, class ContactsController : BaseController,

View File

@ -32,8 +32,6 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import butterknife.BindView import butterknife.BindView
import com.bluelinelabs.conductor.RouterTransaction
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

View File

@ -33,23 +33,19 @@ import android.view.inputmethod.InputMethodManager
import android.widget.EditText import android.widget.EditText
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.ActionBar import androidx.appcompat.app.ActionBar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.MainActivity import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.controllers.SwitchAccountController import com.nextcloud.talk.controllers.SwitchAccountController
import com.nextcloud.talk.controllers.base.providers.ActionBarProvider import com.nextcloud.talk.controllers.base.providers.ActionBarProvider
import com.nextcloud.talk.utils.animations.FABAwareScrollingViewBehavior
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
import com.uber.autodispose.lifecycle.LifecycleScopeProvider import com.uber.autodispose.lifecycle.LifecycleScopeProvider
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.search_layout.* import kotlinx.android.synthetic.main.search_layout.*
import kotlinx.android.synthetic.main.search_layout.view.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import java.util.* import java.util.*

View File

@ -29,8 +29,8 @@ import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
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.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers

View File

@ -29,8 +29,8 @@ import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
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.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers

View File

@ -84,6 +84,7 @@ import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationWith
import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel
import com.nextcloud.talk.utils.NotificationUtils.findNotificationForRoom import com.nextcloud.talk.utils.NotificationUtils.findNotificationForRoom
import com.nextcloud.talk.utils.PushUtils import com.nextcloud.talk.utils.PushUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID
@ -91,7 +92,6 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_SIGNATURE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_SUBJECT import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_SUBJECT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageUtils import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageUtils
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences

View File

@ -27,9 +27,9 @@ import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
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.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_PATHS
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import io.reactivex.Observer import io.reactivex.Observer
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers

View File

@ -25,7 +25,6 @@ import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.webrtc.WebSocketConnectionHelper
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject

View File

@ -28,9 +28,6 @@ import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
import org.parceler.Parcel; import org.parceler.Parcel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import lombok.Data; import lombok.Data;

View File

@ -89,4 +89,4 @@ data class PushConfigurationStateWrapper(
var pushConfigurationState: PushConfigurationState, var pushConfigurationState: PushConfigurationState,
@SerialName("reason") @SerialName("reason")
var reason: Int? var reason: Int?
): Parcelable ) : Parcelable

View File

@ -20,7 +20,6 @@
package com.nextcloud.talk.newarch.data.repository.online package com.nextcloud.talk.newarch.data.repository.online
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
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.conversations.RoomOverall

View File

@ -52,32 +52,32 @@ val UseCasesModule = module {
} }
fun createGetContactsUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createGetContactsUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): GetContactsUseCase { ): GetContactsUseCase {
return GetContactsUseCase(nextcloudTalkRepository, apiErrorHandler) return GetContactsUseCase(nextcloudTalkRepository, apiErrorHandler)
} }
fun createUnregisterPushWithServerUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createUnregisterPushWithServerUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): UnregisterPushWithServerUseCase { ): UnregisterPushWithServerUseCase {
return UnregisterPushWithServerUseCase(nextcloudTalkRepository, apiErrorHandler) return UnregisterPushWithServerUseCase(nextcloudTalkRepository, apiErrorHandler)
} }
fun createUnregisterPushWithProxyUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createUnregisterPushWithProxyUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): UnregisterPushWithProxyUseCase { ): UnregisterPushWithProxyUseCase {
return UnregisterPushWithProxyUseCase(nextcloudTalkRepository, apiErrorHandler) return UnregisterPushWithProxyUseCase(nextcloudTalkRepository, apiErrorHandler)
} }
fun createRegisterPushWithServerUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createRegisterPushWithServerUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): RegisterPushWithServerUseCase { ): RegisterPushWithServerUseCase {
return RegisterPushWithServerUseCase(nextcloudTalkRepository, apiErrorHandler) return RegisterPushWithServerUseCase(nextcloudTalkRepository, apiErrorHandler)
} }
fun createRegisterPushWithProxyUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createRegisterPushWithProxyUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): RegisterPushWithProxyUseCase { ): RegisterPushWithProxyUseCase {
return RegisterPushWithProxyUseCase(nextcloudTalkRepository, apiErrorHandler) return RegisterPushWithProxyUseCase(nextcloudTalkRepository, apiErrorHandler)
} }
@ -95,7 +95,7 @@ fun createGetSignalingSettingsUseCase(nextcloudTalkRepository: NextcloudTalkRepo
} }
fun createGetSignalingUseCase(nextcloudTalkRepository: NextcloudTalkRepository, fun createGetSignalingUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler apiErrorHandler: ApiErrorHandler
): GetSignalingSettingsUseCase { ): GetSignalingSettingsUseCase {
return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler) return GetSignalingSettingsUseCase(nextcloudTalkRepository, apiErrorHandler)
} }

View File

@ -20,7 +20,6 @@
package com.nextcloud.talk.newarch.domain.repository.online package com.nextcloud.talk.newarch.domain.repository.online
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
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.conversations.RoomOverall

View File

@ -22,7 +22,6 @@
package com.nextcloud.talk.newarch.domain.usecases package com.nextcloud.talk.newarch.domain.usecases
import com.nextcloud.talk.models.json.push.PushRegistrationOverall
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.online.NextcloudTalkRepository import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkRepository
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase import com.nextcloud.talk.newarch.domain.usecases.base.UseCase

View File

@ -98,7 +98,6 @@ class LoginEntryView(val bundle: Bundle) : BaseView() {
}) })
val baseUrl = bundle.get(BundleKeys.KEY_BASE_URL) val baseUrl = bundle.get(BundleKeys.KEY_BASE_URL)
val headers: MutableMap<String, String> = hashMapOf() val headers: MutableMap<String, String> = hashMapOf()
headers["OCS-APIRequest"] = "true" headers["OCS-APIRequest"] = "true"

View File

@ -2,7 +2,6 @@ package com.nextcloud.talk.newarch.features.account.loginentry
import android.app.Application import android.app.Application
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.models.LoginData import com.nextcloud.talk.models.LoginData
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
import com.nextcloud.talk.models.json.push.PushConfiguration import com.nextcloud.talk.models.json.push.PushConfiguration

View File

@ -1,7 +1,6 @@
package com.nextcloud.talk.newarch.features.contactsflow package com.nextcloud.talk.newarch.features.contactsflow
import android.content.Context import android.content.Context
import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import coil.api.load import coil.api.load
@ -15,8 +14,10 @@ import com.nextcloud.talk.utils.ApiUtils
import com.otaliastudios.elements.Element import com.otaliastudios.elements.Element
import com.otaliastudios.elements.Page import com.otaliastudios.elements.Page
import com.otaliastudios.elements.Presenter import com.otaliastudios.elements.Presenter
import com.otaliastudios.elements.extensions.FooterSource
import com.otaliastudios.elements.extensions.HeaderSource import com.otaliastudios.elements.extensions.HeaderSource
import kotlinx.android.synthetic.main.rv_item_contact.view.* import kotlinx.android.synthetic.main.rv_item_contact.view.*
import kotlinx.android.synthetic.main.rv_item_participant_rv_footer.view.*
import kotlinx.android.synthetic.main.rv_item_title_header.view.* import kotlinx.android.synthetic.main.rv_item_title_header.view.*
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
@ -25,13 +26,19 @@ open class ContactPresenter<T : Any>(context: Context, onElementClick: ((Page, H
private val globalService: GlobalService by inject() private val globalService: GlobalService by inject()
override val elementTypes: Collection<Int> override val elementTypes: Collection<Int>
get() = listOf(ParticipantElementType.PARTICIPANT.ordinal, ParticipantElementType.PARTICIPANT_HEADER.ordinal) get() = listOf(ParticipantElementType.PARTICIPANT.ordinal, ParticipantElementType.PARTICIPANT_HEADER.ordinal, ParticipantElementType.PARTICIPANT_FOOTER.ordinal)
override fun onCreate(parent: ViewGroup, elementType: Int): Holder { override fun onCreate(parent: ViewGroup, elementType: Int): Holder {
return if (elementType == ParticipantElementType.PARTICIPANT.ordinal) { return when (elementType) {
Holder(getLayoutInflater().inflate(R.layout.rv_item_contact, parent, false)) ParticipantElementType.PARTICIPANT.ordinal -> {
} else { Holder(getLayoutInflater().inflate(R.layout.rv_item_contact, parent, false))
Holder(getLayoutInflater().inflate(R.layout.rv_item_title_header, parent, false)) }
ParticipantElementType.PARTICIPANT_HEADER.ordinal -> {
Holder(getLayoutInflater().inflate(R.layout.rv_item_title_header, parent, false))
}
else -> {
Holder(getLayoutInflater().inflate(R.layout.rv_item_participant_rv_footer, parent, false))
}
} }
} }
@ -76,8 +83,10 @@ open class ContactPresenter<T : Any>(context: Context, onElementClick: ((Page, H
} }
} }
} }
} else { } else if (element.type == ParticipantElementType.PARTICIPANT_HEADER.ordinal) {
holder.itemView.titleTextView.text = (element.data as HeaderSource.Data<*, *>).header.toString() holder.itemView.titleTextView.text = (element.data as HeaderSource.Data<*, *>).header.toString()
} else {
holder.itemView.messageTextView.text = (element.data as FooterSource.Data<*, *>).footer.toString()
} }
} }
} }

View File

@ -0,0 +1,39 @@
package com.nextcloud.talk.newarch.features.contactsflow
import android.content.Context
import com.nextcloud.talk.R
import com.nextcloud.talk.models.json.participants.Participant
import com.otaliastudios.elements.Page
import com.otaliastudios.elements.Source
import com.otaliastudios.elements.extensions.FooterSource
class ContactsFooterSource(private val context: Context, private val elementType: Int) : FooterSource<Participant, String>() {
private var lastAnchor: Participant? = null
override fun dependsOn(source: Source<*>): Boolean {
return source is ContactsViewSource
}
override fun areItemsTheSame(first: Data<Participant, String>, second: Data<Participant, String>): Boolean {
return first == second
}
override fun getElementType(data: Data<Participant, String>) = elementType
override fun computeFooters(page: Page, list: List<Participant>): List<Data<Participant, String>> {
val results = arrayListOf<Data<Participant, String>>()
lastAnchor = if (list.isNotEmpty()) {
val participant = list.takeLast(1)[0]
if (lastAnchor == null || lastAnchor != participant) {
results.add(Data(participant, context.getString(R.string.nc_search_for_more)))
}
participant
} else {
null
}
return results
}
}

View File

@ -2,5 +2,6 @@ package com.nextcloud.talk.newarch.features.contactsflow
enum class ParticipantElementType { enum class ParticipantElementType {
PARTICIPANT, PARTICIPANT,
PARTICIPANT_HEADER PARTICIPANT_HEADER,
PARTICIPANT_FOOTER
} }

View File

@ -22,7 +22,7 @@ import kotlinx.android.synthetic.main.conversations_list_view.view.*
import kotlinx.android.synthetic.main.message_state.view.* import kotlinx.android.synthetic.main.message_state.view.*
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
class ContactsView(private val bundle: Bundle? = null) : BaseView() { class ContactsView<T : Any>(private val bundle: Bundle? = null) : BaseView() {
override val scopeProvider: LifecycleScopeProvider<*> = ControllerScopeProvider.from(this) override val scopeProvider: LifecycleScopeProvider<*> = ControllerScopeProvider.from(this)
private lateinit var viewModel: ContactsViewModel private lateinit var viewModel: ContactsViewModel
@ -47,6 +47,7 @@ class ContactsView(private val bundle: Bundle? = null) : BaseView() {
adapter = Adapter.builder(this) adapter = Adapter.builder(this)
.addSource(ContactsViewSource(viewModel.contactsLiveData, ParticipantElementType.PARTICIPANT.ordinal)) .addSource(ContactsViewSource(viewModel.contactsLiveData, ParticipantElementType.PARTICIPANT.ordinal))
.addSource(ContactsHeaderSource(activity as Context, ParticipantElementType.PARTICIPANT_HEADER.ordinal)) .addSource(ContactsHeaderSource(activity as Context, ParticipantElementType.PARTICIPANT_HEADER.ordinal))
.addSource(ContactsFooterSource(activity as Context, ParticipantElementType.PARTICIPANT_FOOTER.ordinal))
.addPresenter(ContactPresenter(activity as Context, ::onElementClick)) .addPresenter(ContactPresenter(activity as Context, ::onElementClick))
.addPresenter(Presenter.forLoadingIndicator(activity as Context, R.layout.loading_state)) .addPresenter(Presenter.forLoadingIndicator(activity as Context, R.layout.loading_state))
.addPresenter(Presenter.forEmptyIndicator(activity as Context, R.layout.message_state)) .addPresenter(Presenter.forEmptyIndicator(activity as Context, R.layout.message_state))
@ -66,10 +67,13 @@ class ContactsView(private val bundle: Bundle? = null) : BaseView() {
return view return view
} }
private fun onElementClick(page: Page, holder: Presenter.Holder, element: Element<Participant>) { private fun onElementClick(page: Page, holder: Presenter.Holder, element: Element<T>) {
val isElementSelected = element.data?.selected == true if (element.data is Participant?) {
element.data?.selected = !isElementSelected val participant = element.data as Participant?
adapter.notifyItemChanged(holder.adapterPosition, ElementPayload.SELECTION_TOGGLE) val isElementSelected = participant?.selected == true
participant?.selected = !isElementSelected
adapter.notifyItemChanged(holder.adapterPosition, ElementPayload.SELECTION_TOGGLE)
}
} }
override fun getTitle(): String? { override fun getTitle(): String? {

View File

@ -7,7 +7,7 @@ import com.otaliastudios.elements.Page
import com.otaliastudios.elements.Source import com.otaliastudios.elements.Source
import com.otaliastudios.elements.extensions.HeaderSource import com.otaliastudios.elements.extensions.HeaderSource
class ContactsHeaderSource(private val context: Context, private val elementType: Int): HeaderSource<Participant, String>() { class ContactsHeaderSource(private val context: Context, private val elementType: Int) : HeaderSource<Participant, String>() {
// Store the last header that was added, even if it belongs to a previous page. // Store the last header that was added, even if it belongs to a previous page.
private var lastHeader: String = "" private var lastHeader: String = ""

View File

@ -1,8 +1,6 @@
package com.nextcloud.talk.newarch.features.contactsflow package com.nextcloud.talk.newarch.features.contactsflow
import android.app.Application import android.app.Application
import android.os.Build
import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant
@ -13,8 +11,6 @@ import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.features.conversationslist.ConversationsListView import com.nextcloud.talk.newarch.features.conversationslist.ConversationsListView
import com.nextcloud.talk.newarch.services.GlobalService import com.nextcloud.talk.newarch.services.GlobalService
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
import java.util.*
import kotlin.Comparator
class ContactsViewModel constructor( class ContactsViewModel constructor(
application: Application, application: Application,
@ -22,14 +18,19 @@ class ContactsViewModel constructor(
val globalService: GlobalService val globalService: GlobalService
) : BaseViewModel<ConversationsListView>(application) { ) : BaseViewModel<ConversationsListView>(application) {
val contactsLiveData = MutableLiveData<List<Participant>>() val contactsLiveData = MutableLiveData<List<Participant>>()
val searchQuery = MutableLiveData<String?>(null) private var searchQuery: String? = null
var conversationToken: String? = null var conversationToken: String? = null
fun setSearchQuery(query: String?) {
searchQuery = query
loadContacts()
}
fun loadContacts() { fun loadContacts() {
getContactsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, searchQuery.value, conversationToken), object : getContactsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, searchQuery, conversationToken), object :
UseCaseResponse<List<Participant>> { UseCaseResponse<List<Participant>> {
override suspend fun onSuccess(result: List<Participant>) { override suspend fun onSuccess(result: List<Participant>) {
val sortPriority = mapOf("users" to 0, "groups" to 1, "emails" to 2, "circles" to 3) val sortPriority = mapOf("users" to 0, "groups" to 1, "emails" to 2, "circles" to 0)
val typeComparator = Comparator<Participant> { o1, o2 -> val typeComparator = Comparator<Participant> { o1, o2 ->
sortPriority[o2.source]?.let { sortPriority[o1.source]?.compareTo(it) } sortPriority[o2.source]?.let { sortPriority[o1.source]?.compareTo(it) }
0 0
@ -38,7 +39,7 @@ class ContactsViewModel constructor(
val sortedList = result.sortedWith(compareBy({ val sortedList = result.sortedWith(compareBy({
sortPriority[it.source] sortPriority[it.source]
}, { }, {
it.displayName.toLowerCase(Locale.getDefault()) it.displayName.toLowerCase()
})) }))
contactsLiveData.postValue(sortedList) contactsLiveData.postValue(sortedList)

View File

@ -23,7 +23,6 @@
package com.nextcloud.talk.newarch.features.contactsflow package com.nextcloud.talk.newarch.features.contactsflow
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant
import com.otaliastudios.elements.Element import com.otaliastudios.elements.Element
import com.otaliastudios.elements.Page import com.otaliastudios.elements.Page

View File

@ -22,11 +22,13 @@ package com.nextcloud.talk.newarch.features.conversationslist
import android.app.Application import android.app.Application
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.lifecycle.* import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import coil.Coil import coil.Coil
import coil.api.get import coil.api.get
import coil.transform.CircleCropTransformation import coil.transform.CircleCropTransformation
import com.nextcloud.talk.R
import com.nextcloud.talk.models.json.conversations.Conversation 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
@ -40,7 +42,6 @@ import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.local.models.getCredentials import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.newarch.services.GlobalService import com.nextcloud.talk.newarch.services.GlobalService
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock

View File

@ -21,7 +21,6 @@
package com.nextcloud.talk.newarch.local.converters package com.nextcloud.talk.newarch.local.converters
import androidx.room.TypeConverter import androidx.room.TypeConverter
import com.bluelinelabs.logansquare.LoganSquare
import com.nextcloud.talk.models.json.push.PushConfiguration import com.nextcloud.talk.models.json.push.PushConfiguration
import com.nextcloud.talk.newarch.utils.MagicJson import com.nextcloud.talk.newarch.utils.MagicJson
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json

View File

@ -40,7 +40,6 @@ import java.security.*
import java.security.spec.InvalidKeySpecException import java.security.spec.InvalidKeySpecException
import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec import java.security.spec.X509EncodedKeySpec
import java.util.HashMap
class PushUtils(val usersRepository: UsersRepository) : KoinComponent { class PushUtils(val usersRepository: UsersRepository) : KoinComponent {
val appPreferences: AppPreferences by inject() val appPreferences: AppPreferences by inject()
@ -65,7 +64,7 @@ class PushUtils(val usersRepository: UsersRepository) : KoinComponent {
return options return options
} }
fun getMapForPushRegistrationWithServer(context: Context, token: String) : Map<String, String> { fun getMapForPushRegistrationWithServer(context: Context, token: String): Map<String, String> {
val options = mutableMapOf<String, String>() val options = mutableMapOf<String, String>()
// Let's generate a keypair if we don't have it // Let's generate a keypair if we don't have it

View File

@ -20,7 +20,6 @@ import android.util.AttributeSet;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;

View File

@ -34,8 +34,8 @@ import com.nextcloud.talk.models.json.websocket.*
import com.nextcloud.talk.newarch.local.models.UserNgEntity import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.utils.LoggingUtils.writeLogEntryToFile import com.nextcloud.talk.utils.LoggingUtils.writeLogEntryToFile
import com.nextcloud.talk.utils.MagicMap import com.nextcloud.talk.utils.MagicMap
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request.Builder import okhttp3.Request.Builder
import okhttp3.Response import okhttp3.Response

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ @author Andy Scherzinger
~ Copyright (C) 2017-2020 Mario Danic
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/rv_item_view_height"
android:layout_margin="@dimen/margin_between_elements"
android:orientation="vertical">
<androidx.emoji.widget.EmojiTextView
android:id="@+id/messageTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:ellipsize="end"
tools:text="Contact item text" />
</RelativeLayout>

View File

@ -338,4 +338,5 @@
<string name="path_password_strike_through" translatable="false" <string name="path_password_strike_through" translatable="false"
tools:override="true">M3.27,4.27L19.74,20.74</string> tools:override="true">M3.27,4.27L19.74,20.74</string>
<string name="nc_search_for_more">Search for more participants</string>
</resources> </resources>