wip: Poll view model work

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey 2022-06-07 17:21:10 +02:00 committed by Andy Scherzinger (Rebase PR Action)
parent 01f18d7eca
commit 42324419cd
17 changed files with 388 additions and 117 deletions

View File

@ -40,7 +40,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding import com.nextcloud.talk.databinding.ItemCustomIncomingPollMessageBinding
import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.polls.ui.PollVoteDialogFragment import com.nextcloud.talk.polls.ui.PollMainDialogFragment
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
@ -100,14 +100,14 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
} }
private fun setPollPreview(message: ChatMessage) { private fun setPollPreview(message: ChatMessage) {
var pollId: Int? = null var pollId: String? = null
var pollName: String? = null var pollName: String? = null
if (message.messageParameters != null && message.messageParameters!!.size > 0) { if (message.messageParameters != null && message.messageParameters!!.size > 0) {
for (key in message.messageParameters!!.keys) { for (key in message.messageParameters!!.keys) {
val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!! val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!!
if (individualHashMap["type"] == "talk-poll") { if (individualHashMap["type"] == "talk-poll") {
pollId = Integer.parseInt(individualHashMap["id"]) pollId = individualHashMap["id"]
pollName = individualHashMap["name"].toString() pollName = individualHashMap["name"].toString()
} }
} }
@ -120,7 +120,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
val roomToken = "???????????????????????????" val roomToken = "???????????????????????????"
binding.bubble.setOnClickListener { binding.bubble.setOnClickListener {
val pollVoteDialog = PollVoteDialogFragment.newInstance( val pollVoteDialog = PollMainDialogFragment.newInstance(
message.activeUser!!, roomToken, pollId, message.activeUser!!, roomToken, pollId,
pollName pollName
) )
@ -130,6 +130,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
) )
} }
// TODO get poll from api
// wait for https://github.com/nextcloud/spreed/pull/7306#issuecomment-1145819317 // wait for https://github.com/nextcloud/spreed/pull/7306#issuecomment-1145819317
// val credentials = ApiUtils.getCredentials(message.activeUser?.username, message.activeUser?.token) // val credentials = ApiUtils.getCredentials(message.activeUser?.username, message.activeUser?.token)

View File

@ -24,6 +24,8 @@
package com.nextcloud.talk.dagger.modules package com.nextcloud.talk.dagger.modules
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.polls.repositories.PollRepository
import com.nextcloud.talk.polls.repositories.PollRepositoryImpl
import com.nextcloud.talk.data.source.local.TalkDatabase import com.nextcloud.talk.data.source.local.TalkDatabase
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepository import com.nextcloud.talk.data.storage.ArbitraryStoragesRepository
import com.nextcloud.talk.data.storage.ArbitraryStoragesRepositoryImpl import com.nextcloud.talk.data.storage.ArbitraryStoragesRepositoryImpl
@ -52,6 +54,11 @@ class RepositoryModule {
return UnifiedSearchRepositoryImpl(ncApi, userProvider) return UnifiedSearchRepositoryImpl(ncApi, userProvider)
} }
@Provides
fun provideDialogPollRepository(ncApi: NcApi, userProvider: CurrentUserProvider): PollRepository {
return PollRepositoryImpl(ncApi, userProvider)
}
@Provides @Provides
fun provideRemoteFileBrowserItemsRepository(okHttpClient: OkHttpClient, userProvider: CurrentUserProvider): fun provideRemoteFileBrowserItemsRepository(okHttpClient: OkHttpClient, userProvider: CurrentUserProvider):
RemoteFileBrowserItemsRepository { RemoteFileBrowserItemsRepository {

View File

@ -25,6 +25,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel
import com.nextcloud.talk.messagesearch.MessageSearchViewModel import com.nextcloud.talk.messagesearch.MessageSearchViewModel
import com.nextcloud.talk.polls.viewmodels.PollViewModel
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel
import dagger.Binds import dagger.Binds
import dagger.MapKey import dagger.MapKey
@ -61,6 +63,16 @@ abstract class ViewModelModule {
@ViewModelKey(MessageSearchViewModel::class) @ViewModelKey(MessageSearchViewModel::class)
abstract fun messageSearchViewModel(viewModel: MessageSearchViewModel): ViewModel abstract fun messageSearchViewModel(viewModel: MessageSearchViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(PollViewModel::class)
abstract fun pollViewModel(viewModel: PollViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(PollVoteViewModel::class)
abstract fun pollVoteViewModel(viewModel: PollVoteViewModel): ViewModel
@Binds @Binds
@IntoMap @IntoMap
@ViewModelKey(RemoteFileBrowserItemsViewModel::class) @ViewModelKey(RemoteFileBrowserItemsViewModel::class)

View File

@ -0,0 +1,20 @@
package com.nextcloud.talk.polls.model
import com.nextcloud.talk.polls.repositories.model.PollDetails
data class Poll(
val id: String,
val question: String?,
val options: List<String>?,
val votes: List<Int>?,
val actorType: String?,
val actorId: String?,
val actorDisplayName: String?,
val status: Int,
val resultMode: Int,
val maxVotes: Int,
val votedSelf: List<Int>?,
val numVoters: Int,
// TODO PollDetails needs own model class
val details: List<PollDetails>?
)

View File

@ -1,4 +0,0 @@
package com.nextcloud.talk.polls.model
class PollModel {
}

View File

@ -1,12 +0,0 @@
package com.nextcloud.talk.polls.repositories
interface DialogPollRepository {
data class Parameters(
val userName: String,
val userToken: String,
val baseUrl: String,
val roomToken: String,
val pollId: Int
)
}

View File

@ -0,0 +1,9 @@
package com.nextcloud.talk.polls.repositories
import com.nextcloud.talk.polls.model.Poll
import io.reactivex.Observable
interface PollRepository {
fun getPoll(roomToken: String, pollId: String): Observable<Poll>
}

View File

@ -0,0 +1,52 @@
/*
* Nextcloud Talk application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.polls.repositories
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.polls.model.Poll
import com.nextcloud.talk.utils.database.user.CurrentUserProvider
import io.reactivex.Observable
class PollRepositoryImpl(private val api: NcApi, private val currentUserProvider: CurrentUserProvider) :
PollRepository {
override fun getPoll(roomToken: String, pollId: String): Observable<Poll> {
// TODO actual api call
return Observable.just(
Poll(
id = "aaa",
question = "what if?",
options = listOf("yes", "no", "maybe", "I don't know"),
votes = listOf(0, 0, 0, 0),
actorType = "",
actorId = "",
actorDisplayName = "",
status = 0,
resultMode = 0,
maxVotes = 1,
votedSelf = listOf(0, 0, 0, 0),
numVoters = 0,
details = emptyList()
)
)
}
}

View File

@ -20,7 +20,7 @@ data class PollDetails(
@JsonField(name = ["optionId"]) @JsonField(name = ["optionId"])
var optionId: Int? = 0, var optionId: Int? = 0,
) : Parcelable { ) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null, null, null, 0) constructor() : this(null, null, null, 0)
} }

View File

@ -28,7 +28,7 @@ import kotlinx.android.parcel.Parcelize
@JsonObject @JsonObject
data class PollOCS( data class PollOCS(
@JsonField(name = ["data"]) @JsonField(name = ["data"])
var data: Poll? var data: PollResponse?
) : Parcelable { ) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(null) constructor() : this(null)

View File

@ -26,7 +26,7 @@ import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
@JsonObject @JsonObject
data class Poll( data class PollResponse(
@JsonField(name = ["id"]) @JsonField(name = ["id"])
var id: Int = 0, var id: Int = 0,
@ -66,7 +66,7 @@ data class Poll(
@JsonField(name = ["details"]) @JsonField(name = ["details"])
var details: ArrayList<PollDetails>? = null, var details: ArrayList<PollDetails>? = null,
) : Parcelable { ) : Parcelable {
// This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject'
constructor() : this(0, null, null, null, null, null, null, 0, 0, 0, null) constructor() : this(0, null, null, null, null, null, null, 0, 0, 0, null)
} }

View File

@ -8,54 +8,68 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.databinding.DialogPollVoteBinding import com.nextcloud.talk.databinding.DialogPollMainBinding
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.polls.viewmodels.PollViewModel import com.nextcloud.talk.polls.viewmodels.PollViewModel
import javax.inject.Inject
var user: UserEntity? = null
var pollId: Int? = null
var roomToken: String? = null
var pollTitle: String? = null
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class PollVoteDialogFragment : DialogFragment() { class PollMainDialogFragment(
private val pollId: String,
private val roomToken: String,
private val pollTitle: String
) : DialogFragment() {
private lateinit var binding: DialogPollVoteBinding @Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var binding: DialogPollMainBinding
private lateinit var viewModel: PollViewModel private lateinit var viewModel: PollViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
viewModel = ViewModelProvider(this, viewModelFactory)[PollViewModel::class.java]
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
binding = DialogPollVoteBinding.inflate(LayoutInflater.from(context)) binding = DialogPollMainBinding.inflate(LayoutInflater.from(context))
return AlertDialog.Builder(requireContext()) val dialog = AlertDialog.Builder(requireContext())
.setView(binding.root) .setView(binding.root)
.create() .create()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return binding.root
}
@SuppressLint("DefaultLocale")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.messagePollTitle.text = pollTitle binding.messagePollTitle.text = pollTitle
viewModel.viewState.observe(this) { state -> return dialog
// when (state) {
// }
} }
viewModel.initialize(user!!, roomToken!!, pollId!!) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.viewState.observe(viewLifecycleOwner) { state ->
when (state) {
PollViewModel.InitialState -> {}
is PollViewModel.PollClosedState -> TODO()
is PollViewModel.PollOpenState -> {
val contentFragment = PollVoteFragment(viewModel)
val transaction = childFragmentManager.beginTransaction()
transaction.replace(binding.messagePollContentFragment.id, contentFragment)
transaction.commit()
}
}
}
viewModel.initialize(roomToken, pollId)
} }
/** /**
@ -66,16 +80,8 @@ class PollVoteDialogFragment : DialogFragment() {
fun newInstance( fun newInstance(
userEntity: UserEntity, userEntity: UserEntity,
roomTokenParam: String, roomTokenParam: String,
id: Int, pollId: String,
name: String name: String
): PollVoteDialogFragment { ): PollMainDialogFragment = PollMainDialogFragment(pollId, roomTokenParam, name)
user = userEntity // TODO replace with "putParcelable" like in SetStatusDialogFragment???
roomToken = roomTokenParam
pollId = id
pollTitle = name
val dialogFragment = PollVoteDialogFragment()
return dialogFragment
}
} }
} }

View File

@ -0,0 +1,95 @@
/*
* Nextcloud Talk application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.polls.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RadioButton
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.databinding.DialogPollVoteBinding
import com.nextcloud.talk.polls.viewmodels.PollViewModel
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class PollVoteFragment(private val parentViewModel: PollViewModel) : Fragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
lateinit var viewModel: PollVoteViewModel
var _binding: DialogPollVoteBinding? = null
val binding: DialogPollVoteBinding
get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
viewModel = ViewModelProvider(this, viewModelFactory)[PollVoteViewModel::class.java]
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DialogPollVoteBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
if (state is PollViewModel.PollOpenState) {
val poll = state.poll
binding.radioGroup.removeAllViews()
poll.options?.map { option ->
RadioButton(context)
.apply { text = option }
.also {
it.setOnClickListener {
// todo
}
}
}?.forEach {
binding.radioGroup.addView(it)
}
}
}
binding.radioGroup.setOnCheckedChangeListener { group, checkedId ->
// todo set selected in viewmodel
}
// todo observe viewmodel checked, set view checked with it
// todo listen to button click, submit
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -3,32 +3,58 @@ package com.nextcloud.talk.polls.viewmodels
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.polls.model.Poll
import com.nextcloud.talk.polls.model.PollModel import com.nextcloud.talk.polls.repositories.PollRepository
import com.nextcloud.talk.polls.repositories.DialogPollRepository import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject import javax.inject.Inject
class PollViewModel @Inject constructor(private val repository: DialogPollRepository) : ViewModel() { /**
* @startuml
* hide empty description
* [*] --> InitialState
* InitialState --> PollOpenState
* note left
* Open second viewmodel for child fragment
* end note
* InitialState --> PollClosedState
* @enduml
*/
class PollViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
private lateinit var repositoryParameters: DialogPollRepository.Parameters private lateinit var roomToken: String
private lateinit var pollId: String
sealed interface ViewState sealed interface ViewState
object InitialState : ViewState object InitialState : ViewState
open class PollOpenState(val poll: PollModel) : ViewState open class PollOpenState(val poll: Poll) : ViewState
open class PollClosedState(val poll: PollModel) : ViewState open class PollClosedState(val poll: Poll) : ViewState
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState) private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
val viewState: LiveData<ViewState> val viewState: LiveData<ViewState>
get() = _viewState get() = _viewState
fun initialize(userEntity: UserEntity, roomToken: String, pollId: Int) { private var disposable: Disposable? = null
repositoryParameters = DialogPollRepository.Parameters(
userEntity.userId, fun initialize(roomToken: String, pollId: String) {
userEntity.token, this.roomToken = roomToken
userEntity.baseUrl, this.pollId = pollId
roomToken,
pollId loadPoll()
) }
// loadAvailableTypes()
private fun loadPoll() {
disposable = repository.getPoll(roomToken, pollId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { poll ->
_viewState.value = PollOpenState(poll)
}
}
override fun onCleared() {
super.onCleared()
disposable?.dispose()
} }
} }

View File

@ -0,0 +1,37 @@
/*
* Nextcloud Talk application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.polls.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import javax.inject.Inject
class PollVoteViewModel @Inject constructor() : ViewModel() {
private val _selectedOptions: MutableLiveData<List<String>> = MutableLiveData(emptyList())
val selectedOptions: LiveData<List<String>>
get() = _selectedOptions
fun selectOption(option: String) {
_selectedOptions.value = listOf(option)
}
}

View File

@ -0,0 +1,58 @@
<!--
Nextcloud Android client application
@author Marcel Hibbe
Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2,
as published by the Free Software Foundation.
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/>.
-->
<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"
tools:background="@color/white">
<ImageView
android:id="@+id/message_poll_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:contentDescription="@null"
android:src="@drawable/ic_baseline_bar_chart_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/high_emphasis_menu_icon" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/message_poll_title"
android:layout_width="257dp"
android:layout_height="55dp"
android:layout_marginStart="8dp"
android:textAlignment="viewStart"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@id/message_poll_icon"
app:layout_constraintTop_toTopOf="@+id/message_poll_icon"
tools:text="This is the poll title?" />
<FrameLayout
android:id="@+id/message_poll_content_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/message_poll_title"
tools:layout_height="400dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -20,51 +20,15 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools"
tools:background="@color/white">
<ImageView
android:id="@+id/message_poll_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:contentDescription="@null"
android:src="@drawable/ic_baseline_bar_chart_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/high_emphasis_menu_icon" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/message_poll_title"
android:layout_width="257dp"
android:layout_height="55dp"
android:layout_marginStart="8dp"
android:textAlignment="viewStart"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@id/message_poll_icon"
app:layout_constraintTop_toTopOf="@+id/message_poll_icon"
tools:text="This is the poll title?" />
<RadioGroup <RadioGroup
android:id="@+id/radioGroup" android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="203dp"
app:layout_constraintStart_toStartOf="@+id/message_poll_icon"
app:layout_constraintTop_toBottomOf="@+id/message_poll_title">
<RadioButton
android:id="@+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:checked="false" app:layout_constraintStart_toStartOf="parent"
android:text="yes" />
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent">
android:checked="false"
android:text="no" />
</RadioGroup> </RadioGroup>
@ -72,10 +36,10 @@
android:id="@+id/setStatus" android:id="@+id/setStatus"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:cornerRadius="@dimen/button_corner_radius"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/nc_common_submit" android:text="@string/nc_common_submit"
android:theme="@style/Button.Primary" android:theme="@style/Button.Primary"
app:cornerRadius="@dimen/button_corner_radius"
app:layout_constraintEnd_toEndOf="@+id/message_poll_title"
app:layout_constraintTop_toBottomOf="@+id/radioGroup" /> app:layout_constraintTop_toBottomOf="@+id/radioGroup" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>