Initial new group conversation view

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2020-01-30 21:21:30 +01:00
parent 8fef0c314b
commit e3451342f3
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
19 changed files with 393 additions and 40 deletions

View File

@ -353,7 +353,7 @@ class CallController(args: Bundle) : BaseController() {
}
override fun onNext(roomsOverall: RoomsOverall) {
for (conversation in roomsOverall?.ocs?.data!!) {
for (conversation in roomsOverall.ocs?.data!!) {
if (roomId == conversation.conversationId) {
roomToken = conversation.token.toString()
break

View File

@ -241,7 +241,7 @@ class CallNotificationController(private val originalBundle: Bundle) : BaseContr
override fun onSubscribe(d: Disposable) {}
override fun onNext(roomsOverall: RoomsOverall) {
for (conversation in roomsOverall.ocs.data!!) {
for (conversation in roomsOverall.ocs.data) {
if (roomId == conversation.conversationId) {
currentConversation = conversation
runAllThings()

View File

@ -260,7 +260,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
}
override fun onNext(roomsOverall: RoomsOverall) {
for (conversation in roomsOverall.ocs.data!!) {
for (conversation in roomsOverall.ocs.data) {
if (roomId == conversation.conversationId) {
roomToken = conversation.token
currentConversation = conversation

View File

@ -31,6 +31,7 @@ import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ProgressBar
import androidx.annotation.RequiresApi
import androidx.appcompat.app.ActionBar
import androidx.core.view.isVisible
@ -87,6 +88,17 @@ abstract class BaseController : ButterKnifeController(), ComponentCallbacks {
return view
}
protected val toolbarProgressBar: View?
get() {
var view: ProgressBar? = null
activity?.let {
if (it is MainActivity) {
view = it.toolbarProgressBar
}
}
return view
}
protected val floatingActionButton: FloatingActionButton?
get() {
@ -127,6 +139,7 @@ abstract class BaseController : ButterKnifeController(), ComponentCallbacks {
actionBar?.setIcon(null)
setOptionsMenuHidden(true)
if (changeType == ControllerChangeType.POP_EXIT || changeType == ControllerChangeType.PUSH_EXIT) {
toolbarProgressBar?.isVisible = false
activity?.inputEditText?.text = null
searchLayout?.searchProgressBar?.isVisible = false
floatingActionButton?.isVisible = false

View File

@ -158,8 +158,8 @@ class ChatMessage : IMessage, MessageContentType, MessageContentType.Image {
}
return ApiUtils.getUrlForFilePreviewWithFileId(activeUser!!.baseUrl,
individualHashMap["id"], sharedApplication
!!.resources
!!.getDimensionPixelSize(R.dimen.maximum_file_preview_size))
!!.resources
!!.getDimensionPixelSize(R.dimen.maximum_file_preview_size))
}
}
}
@ -197,27 +197,27 @@ class ChatMessage : IMessage, MessageContentType, MessageContentType.Image {
sharedApplication!!.getString(R.string.nc_sent_a_gif_you)
} else {
String.format(sharedApplication
!!.getResources()
!!.resources
.getString(R.string.nc_sent_a_gif),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication
!!.getString(R.string.nc_guest))
!!.getString(R.string.nc_guest))
}
} else if (messageType == MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
return if (actorId.equals(activeUser!!.userId)) {
sharedApplication!!.resources.getString(R.string.nc_sent_an_attachment_you)
} else {
String.format(sharedApplication
!!.resources
!!.resources
.getString(R.string.nc_sent_an_attachment),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication
!!.getString(R.string.nc_guest))
!!.getString(R.string.nc_guest))
}
} else if (messageType == MessageType.SINGLE_LINK_MESSAGE) {
return if (actorId.equals(activeUser!!.userId)) {
sharedApplication!!.resources.getString(R.string.nc_sent_a_link_you)
} else {
String.format(sharedApplication
!! .getResources()
!!.resources
.getString(R.string.nc_sent_a_link),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication!!.getString(R.string.nc_guest))
}
@ -226,30 +226,30 @@ class ChatMessage : IMessage, MessageContentType, MessageContentType.Image {
sharedApplication!!.resources.getString(R.string.nc_sent_an_audio_you)
} else {
String.format(sharedApplication
!!.getResources()
!!.resources
.getString(R.string.nc_sent_an_audio),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication
!!.getString(R.string.nc_guest))
!!.getString(R.string.nc_guest))
}
} else if (messageType == MessageType.SINGLE_LINK_VIDEO_MESSAGE) {
return if (actorId.equals(activeUser!!.userId)) {
sharedApplication!!.resources.getString(R.string.nc_sent_a_video_you)
} else {
String.format(sharedApplication
!!.resources
!!.resources
.getString(R.string.nc_sent_a_video),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication
!!.getString(R.string.nc_guest))
!!.getString(R.string.nc_guest))
}
} else if (messageType == MessageType.SINGLE_LINK_IMAGE_MESSAGE) {
return if (actorId.equals(activeUser!!.userId)) {
sharedApplication!!.getString(R.string.nc_sent_an_image_you)
} else {
String.format(sharedApplication
!!.getResources()
!!.resources
.getString(R.string.nc_sent_an_image),
if (!TextUtils.isEmpty(actorDisplayName)) actorDisplayName else sharedApplication
!!.getString(R.string.nc_guest))
!!.getString(R.string.nc_guest))
}
}
}

View File

@ -93,6 +93,10 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
}
}
override suspend fun setPasswordForConversation(user: UserNgEntity, conversationToken: String, password: String): GenericOverall {
return apiService.setPasswordForConversation(user.getCredentials(), ApiUtils.getUrlForPassword(user.baseUrl, conversationToken), password)
}
override suspend fun addParticipantToConversation(user: UserNgEntity, conversationToken: String, participantId: String, source: String): AddParticipantOverall {
return apiService.addParticipant(user.getCredentials(), ApiUtils.getUrlForParticipants(user.baseUrl, conversationToken), participantId, source)
}
@ -102,7 +106,7 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
}
override suspend fun getContactsForUser(user: UserNgEntity, groupConversation: Boolean, searchQuery: String?, conversationToken: String?): List<Participant> {
return apiService.getContacts(authorization = user.getCredentials(), url = ApiUtils.getUrlForContactsSearch(user.baseUrl), shareTypes = ApiUtils.getShareTypesForContactsSearch(groupConversation), options = ApiUtils.getQueryMapForContactsSearch(searchQuery, conversationToken)).ocs.data.map {
return apiService.getContacts(authorization = user.getCredentials(), url = ApiUtils.getUrlForContactsSearch(user.baseUrl), shareTypes = ApiUtils.getShareTypesForContactsSearch(user, groupConversation), options = ApiUtils.getQueryMapForContactsSearch(searchQuery, conversationToken)).ocs.data.map {
val participant = Participant()
participant.userId = it.id
participant.displayName = it.label

View File

@ -34,6 +34,12 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
import retrofit2.http.*
interface ApiService {
@FormUrlEncoded
@PUT
suspend fun setPasswordForConversation(@Header("Authorization") authorization: String,
@Url url: String?,
@Field("password") password: String): GenericOverall
@POST
suspend fun addParticipant(@Header("Authorization") authorization: String,
@Url url: String,

View File

@ -50,9 +50,15 @@ val UseCasesModule = module {
single { createGetContactsUseCase(get(), get()) }
single { createCreateConversationUseCase(get(), get()) }
single { createAddParticipantToConversationUseCase(get(), get()) }
single { setConversationPasswordUseCase(get(), get()) }
factory { createChatViewModelFactory(get(), get(), get(), get(), get(), get()) }
}
fun setConversationPasswordUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler): SetConversationPasswordUseCase {
return SetConversationPasswordUseCase(nextcloudTalkRepository, apiErrorHandler)
}
fun createAddParticipantToConversationUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
apiErrorHandler: ApiErrorHandler): AddParticipantToConversationUseCase {
return AddParticipantToConversationUseCase(nextcloudTalkRepository, apiErrorHandler)

View File

@ -34,6 +34,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
import com.nextcloud.talk.newarch.local.models.UserNgEntity
interface NextcloudTalkRepository {
suspend fun setPasswordForConversation(user: UserNgEntity, conversationToken: String, password: String): GenericOverall
suspend fun addParticipantToConversation(user: UserNgEntity, conversationToken: String, participantId: String, source: String): AddParticipantOverall
suspend fun createConversationForUser(user: UserNgEntity, conversationType: Int, invite: String?, source: String?, conversationName: String?): ConversationOverall
suspend fun getContactsForUser(user: UserNgEntity, groupConversation: Boolean, searchQuery: String?, conversationToken: String?): List<Participant>

View File

@ -0,0 +1,44 @@
/*
*
* * Nextcloud Talk application
* *
* * @author Mario Danic
* * Copyright (C) 2017-2020 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 SetConversationPasswordUseCase 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.setPasswordForConversation(
definitionParameters[0],
definitionParameters[1],
definitionParameters[2]
)
}
}

View File

@ -20,7 +20,7 @@
*
*/
package com.nextcloud.talk.newarch.features.contactsflow.contacts
package com.nextcloud.talk.newarch.features.contactsflow
import kotlinx.serialization.Serializable
@ -28,7 +28,9 @@ enum class ContactsViewOperationState {
WAITING,
PROCESSING,
OK,
CONVERSATION_CREATION_FAILED
CONVERSATION_CREATION_FAILED,
CONVERSATION_CREATED_WITH_MISSING_TOKEN,
CONVERSATION_PASSWORD_NOT_SET
}
@Serializable

View File

@ -37,6 +37,8 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.nextcloud.talk.R
import com.nextcloud.talk.controllers.ChatController
import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationState
import com.nextcloud.talk.newarch.features.contactsflow.groupconversation.GroupConversationView
import com.nextcloud.talk.newarch.features.contactsflow.source.FixedListSource
import com.nextcloud.talk.newarch.features.search.DebouncingTextWatcher
import com.nextcloud.talk.newarch.mvvm.BaseView
@ -224,7 +226,9 @@ class ContactsView(private val bundle: Bundle? = null) : BaseView() {
}
}
} else if (element.type == ParticipantElementType.PARTICIPANT_NEW_GROUP.ordinal) {
router.replaceTopController(RouterTransaction.with(GroupConversationView())
.popChangeHandler(HorizontalChangeHandler())
.pushChangeHandler(HorizontalChangeHandler()))
} else if (element.type == ParticipantElementType.PARTICIPANT_JOIN_VIA_LINK.ordinal) {
}

View File

@ -37,6 +37,8 @@ import com.nextcloud.talk.newarch.domain.usecases.AddParticipantToConversationUs
import com.nextcloud.talk.newarch.domain.usecases.CreateConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetContactsUseCase
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationState
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationStateWrapper
import com.nextcloud.talk.newarch.features.conversationslist.ConversationsListView
import com.nextcloud.talk.newarch.services.GlobalService
import kotlinx.coroutines.runBlocking

View File

@ -26,7 +26,9 @@ import android.app.Application
import com.nextcloud.talk.newarch.domain.usecases.AddParticipantToConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.CreateConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.GetContactsUseCase
import com.nextcloud.talk.newarch.domain.usecases.SetConversationPasswordUseCase
import com.nextcloud.talk.newarch.features.contactsflow.contacts.ContactsViewModelFactory
import com.nextcloud.talk.newarch.features.contactsflow.groupconversation.GroupConversationViewModelFactory
import com.nextcloud.talk.newarch.services.GlobalService
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.module
@ -37,6 +39,20 @@ val ContactsFlowModule = module {
androidApplication(), get(), get(), get(), get()
)
}
factory {
createGroupConversationViewModelFactory(
androidApplication(), get(), get(), get()
)
}
}
fun createGroupConversationViewModelFactory(
application: Application,
createConversationUseCase: CreateConversationUseCase,
setConversationPasswordUseCase: SetConversationPasswordUseCase,
globalService: GlobalService
): GroupConversationViewModelFactory {
return GroupConversationViewModelFactory(application, createConversationUseCase, setConversationPasswordUseCase, globalService)
}
fun createContactsViewModelFactory(

View File

@ -0,0 +1,117 @@
/*
*
* * Nextcloud Talk application
* *
* * @author Mario Danic
* * Copyright (C) 2017-2020 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.features.contactsflow.groupconversation
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.Observer
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.nextcloud.talk.R
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationState
import com.nextcloud.talk.newarch.features.contactsflow.contacts.ContactsView
import com.nextcloud.talk.newarch.mvvm.BaseView
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.uber.autodispose.lifecycle.LifecycleScopeProvider
import kotlinx.android.synthetic.main.new_group_conversation_view.view.*
import org.koin.android.ext.android.inject
class GroupConversationView : BaseView() {
override val scopeProvider: LifecycleScopeProvider<*> = ControllerScopeProvider.from(this)
private lateinit var viewModel: GroupConversationViewModel
val factory: GroupConversationViewModelFactory by inject()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
setHasOptionsMenu(true)
viewModel = viewModelProvider(factory).get(GroupConversationViewModel::class.java)
val view = super.onCreateView(inflater, container)
view.apply {
conversationNameInputEditText.doOnTextChanged { text, start, count, after ->
floatingActionButton?.isVisible = !text.isNullOrBlank()
}
allowGuestsSwitchMaterial.setOnCheckedChangeListener { buttonView, isChecked ->
passwordTextInputLayout.isVisible = isChecked
}
}
viewModel.operationState.observe(this, Observer { operationState ->
when (operationState.operationState) {
ContactsViewOperationState.WAITING -> {
// do nothing, just sit there and wait
}
ContactsViewOperationState.PROCESSING -> {
view.passwordInputEditText.isEnabled = false
view.conversationNameInputEditText.isEnabled = false
view.allowGuestsSwitchMaterial.isEnabled = false
toolbarProgressBar?.isVisible = true
}
ContactsViewOperationState.OK -> {
val bundle = Bundle()
bundle.putString(BundleKeys.KEY_CONVERSATION_TOKEN, operationState.conversationToken)
bundle.putBoolean(BundleKeys.KEY_NEW_GROUP_CONVERSATION, true)
router.replaceTopController(RouterTransaction.with(ContactsView(bundle))
.popChangeHandler(HorizontalChangeHandler())
.pushChangeHandler(HorizontalChangeHandler()))
}
else -> {
// we should do something else as well, but this will do for now
// we failed, I'm afraid :(
toolbarProgressBar?.isVisible = false
view.passwordInputEditText.isEnabled = true
view.conversationNameInputEditText.isEnabled = true
view.allowGuestsSwitchMaterial.isEnabled = true
}
}
})
return view
}
override fun getLayoutId(): Int {
return R.layout.new_group_conversation_view
}
override fun getTitle(): String? {
return context.getString(R.string.nc_new_group)
}
override fun onFloatingActionButtonClick() {
view?.conversationNameInputEditText?.text?.let { conversationName ->
val conversationType = if (view?.allowGuestsSwitchMaterial?.isChecked == true) 2 else 3
viewModel.createConversation(conversationType, conversationName.toString(), view?.passwordInputEditText?.text?.toString())
}
}
override fun getFloatingActionButtonDrawableRes(): Int {
return R.drawable.ic_arrow_forward_white_24px
}
}

View File

@ -0,0 +1,84 @@
/*
*
* * Nextcloud Talk application
* *
* * @author Mario Danic
* * Copyright (C) 2017-2020 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.features.contactsflow.groupconversation
import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.models.json.conversations.ConversationOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.conversationsList.mvp.BaseViewModel
import com.nextcloud.talk.newarch.data.model.ErrorModel
import com.nextcloud.talk.newarch.domain.usecases.CreateConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.SetConversationPasswordUseCase
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationState
import com.nextcloud.talk.newarch.features.contactsflow.ContactsViewOperationStateWrapper
import com.nextcloud.talk.newarch.features.conversationslist.ConversationsListView
import com.nextcloud.talk.newarch.services.GlobalService
import org.koin.core.parameter.parametersOf
class GroupConversationViewModel constructor(
application: Application,
private val createConversationUseCase: CreateConversationUseCase,
private val setPasswordUseCase: SetConversationPasswordUseCase,
val globalService: GlobalService
) : BaseViewModel<ConversationsListView>(application) {
private val _operationState = MutableLiveData(ContactsViewOperationStateWrapper(ContactsViewOperationState.WAITING, null, null))
val operationState: LiveData<ContactsViewOperationStateWrapper> = _operationState.distinctUntilChanged()
fun createConversation(conversationType: Int, conversationName: String, conversationPassword: String? = null) {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.PROCESSING, null, null))
createConversationUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, conversationType, null, null, conversationName), object : UseCaseResponse<ConversationOverall> {
override suspend fun onSuccess(result: ConversationOverall) {
result.ocs.data.token?.let { token ->
if (conversationPassword != null) {
setPasswordForConversation(token, conversationPassword)
} else {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.OK, null, token))
}
} ?: run {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.CONVERSATION_CREATED_WITH_MISSING_TOKEN, null, null))
}
}
override suspend fun onError(errorModel: ErrorModel?) {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.CONVERSATION_CREATION_FAILED, errorModel?.getErrorMessage(), null))
}
})
}
private fun setPasswordForConversation(conversationToken: String, conversationPassword: String) {
setPasswordUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, conversationToken, conversationPassword), object : UseCaseResponse<GenericOverall> {
override suspend fun onSuccess(result: GenericOverall) {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.OK, null, conversationToken))
}
override suspend fun onError(errorModel: ErrorModel?) {
_operationState.postValue(ContactsViewOperationStateWrapper(ContactsViewOperationState.CONVERSATION_PASSWORD_NOT_SET, errorModel?.getErrorMessage(), conversationToken))
}
})
}
}

View File

@ -0,0 +1,41 @@
/*
*
* * Nextcloud Talk application
* *
* * @author Mario Danic
* * Copyright (C) 2017-2020 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.features.contactsflow.groupconversation
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.nextcloud.talk.newarch.domain.usecases.CreateConversationUseCase
import com.nextcloud.talk.newarch.domain.usecases.SetConversationPasswordUseCase
import com.nextcloud.talk.newarch.services.GlobalService
class GroupConversationViewModelFactory constructor(
private val application: Application,
private val createConversationUseCase: CreateConversationUseCase,
private val setConversationPasswordUseCase: SetConversationPasswordUseCase,
private val globalService: GlobalService
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return GroupConversationViewModel(application, createConversationUseCase, setConversationPasswordUseCase, globalService) as T
}
}

View File

@ -27,7 +27,6 @@
android:animateLayoutChanges="true"
tools:context=".activities.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
@ -49,7 +48,18 @@
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
app:contentInsetStartWithNavigation="0dp"
app:layout_scrollFlags="enterAlwaysCollapsed|noScroll"
app:popupTheme="@style/appActionBarPopupMenu" />
app:popupTheme="@style/appActionBarPopupMenu">
<ProgressBar
android:id="@+id/toolbarProgressBar"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="8dp"
android:indeterminateTint="@color/hwSecurityRed"
android:scaleType="fitCenter" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
@ -58,7 +68,7 @@
android:id="@+id/controller_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ /*
~ * Nextcloud Talk application
~ *
@ -23,45 +22,49 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:animateLayoutChanges="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/conversationNameTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/nc_call_name"
android:id="@+id/conversationNameTextInputLayout">
android:hint="@string/nc_call_name">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/conversationNameInputEditText"
android:layout_width="match_parent"
android:layout_margin="8dp"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
android:layout_margin="8dp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.switchmaterial.SwitchMaterial
android:layout_width="match_parent"
android:layout_below="@id/conversationNameTextInputLayout"
android:layout_height="wrap_content"
android:id="@+id/allowGuestsSwitchMaterial"
android:text="@string/nc_allow_guests"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/conversationNameTextInputLayout"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="8dp">
</com.google.android.material.switchmaterial.SwitchMaterial>
android:layout_marginBottom="8dp"
android:text="@string/nc_allow_guests"></com.google.android.material.switchmaterial.SwitchMaterial>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/nc_password_optional"
android:layout_below="@id/allowGuestsSwitchMaterial"
android:id="@+id/passwordTextInputLayout">
android:visibility="gone"
android:hint="@string/nc_password_optional">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordInputEditText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="8dp"
android:layout_height="match_parent"/>
android:layout_marginBottom="8dp" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
</ScrollView>