mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +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.
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ internal class DefaultCreateRoomTask(private val roomAPI: RoomAPI,
|
|||
handlerThread.start()
|
||||
val handler = Handler(handlerThread.looper)
|
||||
|
||||
// TODO Maybe do the same code for join room request ?
|
||||
handler.post {
|
||||
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()
|
||||
|
||||
publicRoomsCreateNewRoom.setOnClickListener {
|
||||
// TODO homeActivityViewModel.createRoom()
|
||||
|
||||
vectorBaseActivity.notImplemented()
|
||||
// TODO Not the best navigation pattern
|
||||
(vectorBaseActivity as? RoomDirectoryActivity)?.gotoCreateRoom()
|
||||
}
|
||||
|
||||
viewModel.joinRoomErrorLiveData.observe(this, Observer {
|
||||
|
|
|
@ -19,7 +19,9 @@ package im.vector.riotredesign.features.roomdirectory
|
|||
import android.os.Bundle
|
||||
import im.vector.riotredesign.R
|
||||
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.features.roomdirectory.createroom.CreateRoomFragment
|
||||
import org.koin.android.scope.ext.android.bindScope
|
||||
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
|
||||
|
||||
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.RoomDirectoryPickerController
|
||||
import org.koin.dsl.module.module
|
||||
|
||||
// TODO Ganfra: When do we create a new module?
|
||||
class RoomDirectoryModule {
|
||||
|
||||
companion object {
|
||||
|
@ -41,5 +41,14 @@ class RoomDirectoryModule {
|
|||
scope(ROOM_DIRECTORY_SCOPE) {
|
||||
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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.matrix.vector.activity.VectorRoomCreationActivity">
|
||||
tools:context=".features.roomdirectory.RoomDirectoryActivity">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_create_room"
|
||||
android:icon="@drawable/ic_material_done_white"
|
||||
android:orderInCategory="0"
|
||||
android:title="@string/room_participants_create"
|
||||
android:title="@string/create_room_action_create"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -27,4 +27,7 @@
|
|||
<dimen name="pill_min_height">20dp</dimen>
|
||||
<dimen name="pill_text_padding">4dp</dimen>
|
||||
|
||||
|
||||
<dimen name="item_form_min_height">76dp</dimen>
|
||||
|
||||
</resources>
|
|
@ -42,4 +42,13 @@
|
|||
<string name="fab_menu_create_room">"Rooms"</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>
|
Loading…
Reference in a new issue