mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 17:35:54 +03:00
Create room screen - WIP TODO: screen rotation - navigate to created room
This commit is contained in:
parent
ed18a504e4
commit
4c5bffe0f5
18 changed files with 698 additions and 9 deletions
|
@ -100,7 +100,7 @@ class CreateRoomParams {
|
||||||
* private_chat => join_rules is set to invite. history_visibility is set to shared.
|
* private_chat => join_rules is set to invite. history_visibility is set to shared.
|
||||||
* trusted_private_chat => join_rules is set to invite. history_visibility is set to shared. All invitees are given the same power level as the
|
* trusted_private_chat => join_rules is set to invite. history_visibility is set to shared. All invitees are given the same power level as the
|
||||||
* room creator.
|
* room creator.
|
||||||
* public_chat: => join_rules is set to public. history_visibility is set to shared. One of: ["private_chat", "public_chat", "trusted_private_chat"]
|
* public_chat: => join_rules is set to public. history_visibility is set to shared.
|
||||||
*/
|
*/
|
||||||
var preset: CreateRoomPreset? = null
|
var preset: CreateRoomPreset? = null
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ internal class DefaultCreateRoomTask(private val roomAPI: RoomAPI,
|
||||||
handlerThread.start()
|
handlerThread.start()
|
||||||
val handler = Handler(handlerThread.looper)
|
val handler = Handler(handlerThread.looper)
|
||||||
|
|
||||||
|
// TODO Maybe do the same code for join room request ?
|
||||||
handler.post {
|
handler.post {
|
||||||
val realm = Realm.getInstance(realmConfiguration)
|
val realm = Realm.getInstance(realmConfiguration)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.form
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
||||||
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.riotredesign.core.platform.SimpleTextWatcher
|
||||||
|
|
||||||
|
@EpoxyModelClass(layout = R.layout.item_form_text_input)
|
||||||
|
abstract class FormEditTextItem : VectorEpoxyModel<FormEditTextItem.Holder>() {
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var hint: String? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var value: String? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var enabled: Boolean = true
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var onTextChange: ((String) -> Unit)? = null
|
||||||
|
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
holder.textInputLayout.isEnabled = enabled
|
||||||
|
holder.textInputLayout.hint = hint
|
||||||
|
|
||||||
|
// Update only if text is different
|
||||||
|
if (holder.textInputEditText.text.toString() != value) {
|
||||||
|
holder.textInputEditText.setText(value)
|
||||||
|
}
|
||||||
|
holder.textInputEditText.isEnabled = enabled
|
||||||
|
|
||||||
|
holder.textInputEditText.addTextChangedListener(object : SimpleTextWatcher() {
|
||||||
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
onTextChange?.invoke(s.toString())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldSaveViewState(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unbind(holder: Holder) {
|
||||||
|
super.unbind(holder)
|
||||||
|
|
||||||
|
// TODO Remove onTextChanged?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val textInputLayout by bind<TextInputLayout>(R.id.formTextInputTextInputLayout)
|
||||||
|
val textInputEditText by bind<TextInputEditText>(R.id.formTextInputTextInputEditText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.form
|
||||||
|
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
||||||
|
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.riotredesign.core.extensions.setTextOrHide
|
||||||
|
|
||||||
|
@EpoxyModelClass(layout = R.layout.item_form_switch)
|
||||||
|
abstract class FormSwitchItem : VectorEpoxyModel<FormSwitchItem.Holder>() {
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var listener: ((Boolean) -> Unit)? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var enabled: Boolean = true
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var switchChecked: Boolean = false
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var title: String? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var summary: String? = null
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
holder.titleView.text = title
|
||||||
|
holder.summaryView.setTextOrHide(summary)
|
||||||
|
|
||||||
|
holder.switchView.isEnabled = enabled
|
||||||
|
|
||||||
|
holder.switchView.isChecked = switchChecked
|
||||||
|
|
||||||
|
holder.switchView.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
listener?.invoke(isChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldSaveViewState(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unbind(holder: Holder) {
|
||||||
|
super.unbind(holder)
|
||||||
|
|
||||||
|
holder.switchView.setOnCheckedChangeListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
val titleView by bind<TextView>(R.id.formSwitchTitle)
|
||||||
|
val summaryView by bind<TextView>(R.id.formSwitchSummary)
|
||||||
|
val switchView by bind<SwitchMaterial>(R.id.formSwitchSwitch)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -76,9 +76,8 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback
|
||||||
.disposeOnDestroy()
|
.disposeOnDestroy()
|
||||||
|
|
||||||
publicRoomsCreateNewRoom.setOnClickListener {
|
publicRoomsCreateNewRoom.setOnClickListener {
|
||||||
// TODO homeActivityViewModel.createRoom()
|
// TODO Not the best navigation pattern
|
||||||
|
(vectorBaseActivity as? RoomDirectoryActivity)?.gotoCreateRoom()
|
||||||
vectorBaseActivity.notImplemented()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.joinRoomErrorLiveData.observe(this, Observer {
|
viewModel.joinRoomErrorLiveData.observe(this, Observer {
|
||||||
|
|
|
@ -19,7 +19,9 @@ package im.vector.riotredesign.features.roomdirectory
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.extensions.addFragment
|
import im.vector.riotredesign.core.extensions.addFragment
|
||||||
|
import im.vector.riotredesign.core.extensions.addFragmentToBackstack
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomFragment
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
import org.koin.android.scope.ext.android.getOrCreateScope
|
||||||
|
|
||||||
|
@ -40,4 +42,8 @@ class RoomDirectoryActivity : VectorBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun gotoCreateRoom() {
|
||||||
|
addFragmentToBackstack(CreateRoomFragment(), R.id.simpleFragmentContainer)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -17,11 +17,11 @@
|
||||||
package im.vector.riotredesign.features.roomdirectory
|
package im.vector.riotredesign.features.roomdirectory
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.createroom.CreateRoomController
|
||||||
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryListCreator
|
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryListCreator
|
||||||
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerController
|
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerController
|
||||||
import org.koin.dsl.module.module
|
import org.koin.dsl.module.module
|
||||||
|
|
||||||
// TODO Ganfra: When do we create a new module?
|
|
||||||
class RoomDirectoryModule {
|
class RoomDirectoryModule {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -41,5 +41,14 @@ class RoomDirectoryModule {
|
||||||
scope(ROOM_DIRECTORY_SCOPE) {
|
scope(ROOM_DIRECTORY_SCOPE) {
|
||||||
PublicRoomsController(get(), get())
|
PublicRoomsController(get(), get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================================
|
||||||
|
* Create room
|
||||||
|
* ========================================================================================== */
|
||||||
|
|
||||||
|
scope(ROOM_DIRECTORY_SCOPE) {
|
||||||
|
CreateRoomController(get(), get())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.roomdirectory.createroom
|
||||||
|
|
||||||
|
import com.airbnb.epoxy.TypedEpoxyController
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.epoxy.errorWithRetryItem
|
||||||
|
import im.vector.riotredesign.core.epoxy.loadingItem
|
||||||
|
import im.vector.riotredesign.core.error.ErrorFormatter
|
||||||
|
import im.vector.riotredesign.core.resources.StringProvider
|
||||||
|
import im.vector.riotredesign.features.form.formEditTextItem
|
||||||
|
import im.vector.riotredesign.features.form.formSwitchItem
|
||||||
|
|
||||||
|
class CreateRoomController(private val stringProvider: StringProvider,
|
||||||
|
private val errorFormatter: ErrorFormatter
|
||||||
|
) : TypedEpoxyController<CreateRoomViewState>() {
|
||||||
|
|
||||||
|
var listener: Listener? = null
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
|
||||||
|
override fun buildModels(viewState: CreateRoomViewState) {
|
||||||
|
val asyncCreateRoom = viewState.asyncCreateRoomRequest
|
||||||
|
|
||||||
|
when (asyncCreateRoom) {
|
||||||
|
is Success -> {
|
||||||
|
// Nothing to display, the screen will be closed
|
||||||
|
}
|
||||||
|
is Loading -> {
|
||||||
|
// display the form
|
||||||
|
buildForm(viewState, false)
|
||||||
|
loadingItem {
|
||||||
|
id("loading")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Uninitialized -> {
|
||||||
|
// display the form
|
||||||
|
buildForm(viewState, true)
|
||||||
|
}
|
||||||
|
is Fail -> {
|
||||||
|
// display the form
|
||||||
|
buildForm(viewState, true)
|
||||||
|
errorWithRetryItem {
|
||||||
|
id("error")
|
||||||
|
text(errorFormatter.toHumanReadable(asyncCreateRoom.error))
|
||||||
|
listener { listener?.retry() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildForm(viewState: CreateRoomViewState, enableFormElement: Boolean) {
|
||||||
|
formEditTextItem {
|
||||||
|
id("name")
|
||||||
|
enabled(enableFormElement)
|
||||||
|
value(viewState.roomName)
|
||||||
|
hint(stringProvider.getString(R.string.create_room_name_hint))
|
||||||
|
|
||||||
|
onTextChange { text ->
|
||||||
|
listener?.onNameChange(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formSwitchItem {
|
||||||
|
id("public")
|
||||||
|
enabled(enableFormElement)
|
||||||
|
title(stringProvider.getString(R.string.create_room_public_title))
|
||||||
|
summary(stringProvider.getString(R.string.create_room_public_description))
|
||||||
|
switchChecked(viewState.isPublic)
|
||||||
|
|
||||||
|
listener { value ->
|
||||||
|
listener?.setIsPublic(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formSwitchItem {
|
||||||
|
id("directory")
|
||||||
|
enabled(enableFormElement)
|
||||||
|
title(stringProvider.getString(R.string.create_room_directory_title))
|
||||||
|
summary(stringProvider.getString(R.string.create_room_directory_description))
|
||||||
|
switchChecked(viewState.isInRoomDirectory)
|
||||||
|
|
||||||
|
listener { value ->
|
||||||
|
listener?.setIsInRoomDirectory(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Listener {
|
||||||
|
fun onNameChange(newName: String)
|
||||||
|
fun setIsPublic(isPublic: Boolean)
|
||||||
|
fun setIsInRoomDirectory(isInRoomDirectory: Boolean)
|
||||||
|
fun retry()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.roomdirectory.createroom
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.MenuItem
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryModule
|
||||||
|
import kotlinx.android.synthetic.main.fragment_create_room.*
|
||||||
|
import org.koin.android.ext.android.inject
|
||||||
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
|
import org.koin.android.scope.ext.android.getOrCreateScope
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class CreateRoomFragment : VectorBaseFragment(), CreateRoomController.Listener {
|
||||||
|
|
||||||
|
private val viewModel: CreateRoomViewModel by fragmentViewModel()
|
||||||
|
private val createRoomController: CreateRoomController by inject()
|
||||||
|
|
||||||
|
override fun getLayoutResId() = R.layout.fragment_create_room
|
||||||
|
|
||||||
|
override fun getMenuRes() = R.menu.vector_room_creation
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
bindScope(getOrCreateScope(RoomDirectoryModule.ROOM_DIRECTORY_SCOPE))
|
||||||
|
|
||||||
|
vectorBaseActivity.setSupportActionBar(createRoomToolbar)
|
||||||
|
|
||||||
|
setupRecyclerView()
|
||||||
|
|
||||||
|
createRoomClose.setOnClickListener {
|
||||||
|
// TODO Not the best way to manage Fragment Backstack...
|
||||||
|
vectorBaseActivity.onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
R.id.action_create_room -> {
|
||||||
|
viewModel.doCreateRoom()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerView() {
|
||||||
|
val layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
|
createRoomForm.layoutManager = layoutManager
|
||||||
|
createRoomController.listener = this
|
||||||
|
|
||||||
|
createRoomForm.setController(createRoomController)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNameChange(newName: String) {
|
||||||
|
viewModel.setName(newName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setIsPublic(isPublic: Boolean) {
|
||||||
|
viewModel.setIsPublic(isPublic)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setIsInRoomDirectory(isInRoomDirectory: Boolean) {
|
||||||
|
viewModel.setIsInRoomDirectory(isInRoomDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun retry() {
|
||||||
|
Timber.v("Retry")
|
||||||
|
viewModel.doCreateRoom()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
if (state.asyncCreateRoomRequest is Success) {
|
||||||
|
vectorBaseActivity.notImplemented("navigate to freshly created room")
|
||||||
|
} else {
|
||||||
|
// Populate list with Epoxy
|
||||||
|
createRoomController.setData(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.roomdirectory.createroom
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.*
|
||||||
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility
|
||||||
|
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||||
|
import im.vector.matrix.android.api.session.room.model.create.CreateRoomPreset
|
||||||
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
|
import org.koin.android.ext.android.get
|
||||||
|
|
||||||
|
class CreateRoomViewModel(initialState: CreateRoomViewState,
|
||||||
|
private val session: Session) : VectorViewModel<CreateRoomViewState>(initialState) {
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<CreateRoomViewModel, CreateRoomViewState> {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: CreateRoomViewState): CreateRoomViewModel? {
|
||||||
|
val currentSession = viewModelContext.activity.get<Session>()
|
||||||
|
|
||||||
|
return CreateRoomViewModel(state, currentSession)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setName(newName: String) = setState { copy(roomName = newName) }
|
||||||
|
|
||||||
|
fun setIsPublic(value: Boolean) = setState { copy(isPublic = value) }
|
||||||
|
|
||||||
|
fun setIsInRoomDirectory(isInRoomDirectory: Boolean) = setState { copy(isInRoomDirectory = isInRoomDirectory) }
|
||||||
|
|
||||||
|
fun doCreateRoom() = withState { state ->
|
||||||
|
if (state.asyncCreateRoomRequest is Loading || state.asyncCreateRoomRequest is Success) {
|
||||||
|
return@withState
|
||||||
|
}
|
||||||
|
|
||||||
|
setState {
|
||||||
|
copy(asyncCreateRoomRequest = Loading())
|
||||||
|
}
|
||||||
|
|
||||||
|
val createRoomParams = CreateRoomParams().apply {
|
||||||
|
name = state.roomName.takeIf { it.isNotBlank() }
|
||||||
|
|
||||||
|
// Directory visibility
|
||||||
|
visibility = if (state.isInRoomDirectory) RoomDirectoryVisibility.PUBLIC else RoomDirectoryVisibility.PRIVATE
|
||||||
|
|
||||||
|
preset = if (state.isPublic) CreateRoomPreset.PRESET_PUBLIC_CHAT else CreateRoomPreset.PRESET_PRIVATE_CHAT
|
||||||
|
}
|
||||||
|
|
||||||
|
session.createRoom(createRoomParams, object : MatrixCallback<String> {
|
||||||
|
override fun onSuccess(data: String) {
|
||||||
|
setState {
|
||||||
|
copy(asyncCreateRoomRequest = Success(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(failure: Throwable) {
|
||||||
|
setState {
|
||||||
|
copy(asyncCreateRoomRequest = Fail(failure))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.riotredesign.features.roomdirectory.createroom
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
|
||||||
|
data class CreateRoomViewState(
|
||||||
|
val roomName: String = "",
|
||||||
|
val isPublic: Boolean = false,
|
||||||
|
val isInRoomDirectory: Boolean = false,
|
||||||
|
val asyncCreateRoomRequest: Async<String> = Uninitialized
|
||||||
|
) : MvRxState
|
14
vector/src/main/res/drawable/ic_x_18dp.xml
Normal file
14
vector/src/main/res/drawable/ic_x_18dp.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="18dp"
|
||||||
|
android:height="18dp"
|
||||||
|
android:viewportWidth="18"
|
||||||
|
android:viewportHeight="18">
|
||||||
|
<path
|
||||||
|
android:pathData="M16,2L2,16M2,2l14,14"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2.333"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:strokeColor="#03B381"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
71
vector/src/main/res/layout/fragment_create_room.xml
Normal file
71
vector/src/main/res/layout/fragment_create_room.xml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/createRoomToolbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="?actionBarSize"
|
||||||
|
android:elevation="4dp"
|
||||||
|
app:contentInsetStartWithNavigation="0dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/createRoomClose"
|
||||||
|
android:layout_width="@dimen/layout_touch_size"
|
||||||
|
android:layout_height="@dimen/layout_touch_size"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_x_18dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/createRoomTitle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="@string/create_room_title"
|
||||||
|
android:textColor="?riotx_text_primary"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/createRoomClose"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.Toolbar>
|
||||||
|
|
||||||
|
<com.airbnb.epoxy.EpoxyRecyclerView
|
||||||
|
android:id="@+id/createRoomForm"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/createRoomToolbar"
|
||||||
|
tools:listitem="@layout/item_form_switch" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
62
vector/src/main/res/layout/item_form_switch.xml
Normal file
62
vector/src/main/res/layout/item_form_switch.xml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?riotx_background"
|
||||||
|
android:minHeight="@dimen/item_form_min_height">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/formSwitchTitle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||||
|
android:layout_marginLeft="@dimen/layout_horizontal_margin"
|
||||||
|
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||||
|
android:layout_marginRight="@dimen/layout_horizontal_margin"
|
||||||
|
android:duplicateParentState="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?riotx_text_primary"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/formSwitchSummary"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/formSwitchSwitch"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
tools:text="@string/create_room_public_title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/formSwitchSummary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:textColor="?riotx_text_secondary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/formSwitchDivider"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/formSwitchTitle"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/formSwitchTitle"
|
||||||
|
tools:text="@string/create_room_public_description" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/formSwitchSwitch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="19dp"
|
||||||
|
android:layout_marginRight="19dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/formSwitchDivider"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/formSwitchDivider"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?riotx_header_panel_border_mobile"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
39
vector/src/main/res/layout/item_form_text_input.xml
Normal file
39
vector/src/main/res/layout/item_form_text_input.xml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?riotx_background"
|
||||||
|
android:minHeight="@dimen/item_form_min_height">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/formTextInputTextInputLayout"
|
||||||
|
style="@style/VectorTextInputLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||||
|
android:layout_marginEnd="@dimen/layout_horizontal_margin"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/formTextInputDivider"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/formTextInputTextInputEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:hint="@string/create_room_name_hint" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/formTextInputDivider"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?riotx_header_panel_border_mobile"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -2,13 +2,11 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="org.matrix.vector.activity.VectorRoomCreationActivity">
|
tools:context=".features.roomdirectory.RoomDirectoryActivity">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_create_room"
|
android:id="@+id/action_create_room"
|
||||||
android:icon="@drawable/ic_material_done_white"
|
android:title="@string/create_room_action_create"
|
||||||
android:orderInCategory="0"
|
|
||||||
android:title="@string/room_participants_create"
|
|
||||||
app:showAsAction="always" />
|
app:showAsAction="always" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -27,4 +27,7 @@
|
||||||
<dimen name="pill_min_height">20dp</dimen>
|
<dimen name="pill_min_height">20dp</dimen>
|
||||||
<dimen name="pill_text_padding">4dp</dimen>
|
<dimen name="pill_text_padding">4dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
|
<dimen name="item_form_min_height">76dp</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -42,4 +42,13 @@
|
||||||
<string name="fab_menu_create_room">"Rooms"</string>
|
<string name="fab_menu_create_room">"Rooms"</string>
|
||||||
<string name="fab_menu_create_chat">"Direct Messages"</string>
|
<string name="fab_menu_create_chat">"Direct Messages"</string>
|
||||||
|
|
||||||
|
<!-- Create room screen -->
|
||||||
|
<string name="create_room_title">"New Room"</string>
|
||||||
|
<string name="create_room_action_create">"CREATE"</string>
|
||||||
|
<string name="create_room_name_hint">"Room name"</string>
|
||||||
|
<string name="create_room_public_title">"Public"</string>
|
||||||
|
<string name="create_room_public_description">"Anyone will be able to join this room"</string>
|
||||||
|
<string name="create_room_directory_title">"Room Directory"</string>
|
||||||
|
<string name="create_room_directory_description">"Publish this room in the room directory"</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue