mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 19:49:33 +01:00
wip: create poll. show outgoing polls
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
0388f3e3f6
commit
af427f8300
@ -24,27 +24,35 @@ package com.nextcloud.talk.adapters.messages
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.os.Handler
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import autodagger.AutoInjector
|
import autodagger.AutoInjector
|
||||||
import coil.load
|
import coil.load
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
|
import com.nextcloud.talk.activities.MainActivity
|
||||||
|
import com.nextcloud.talk.api.NcApi
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
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.ItemCustomOutcomingPollMessageBinding
|
import com.nextcloud.talk.databinding.ItemCustomOutcomingPollMessageBinding
|
||||||
import com.nextcloud.talk.models.json.chat.ChatMessage
|
import com.nextcloud.talk.models.json.chat.ChatMessage
|
||||||
import com.nextcloud.talk.models.json.chat.ReadStatus
|
import com.nextcloud.talk.models.json.chat.ReadStatus
|
||||||
|
import com.nextcloud.talk.polls.repositories.model.PollOverall
|
||||||
|
import com.nextcloud.talk.polls.ui.PollMainDialogFragment
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import com.stfalcon.chatkit.messages.MessageHolders
|
import com.stfalcon.chatkit.messages.MessageHolders
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class OutcomingPollMessageViewHolder(outcomingView: View) : MessageHolders
|
class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : MessageHolders
|
||||||
.OutcomingTextMessageViewHolder<ChatMessage>(outcomingView) {
|
.OutcomingTextMessageViewHolder<ChatMessage>(outcomingView, payload) {
|
||||||
|
|
||||||
private val binding: ItemCustomOutcomingPollMessageBinding =
|
private val binding: ItemCustomOutcomingPollMessageBinding =
|
||||||
ItemCustomOutcomingPollMessageBinding.bind(itemView)
|
ItemCustomOutcomingPollMessageBinding.bind(itemView)
|
||||||
@ -57,9 +65,11 @@ class OutcomingPollMessageViewHolder(outcomingView: View) : MessageHolders
|
|||||||
@Inject
|
@Inject
|
||||||
var appPreferences: AppPreferences? = null
|
var appPreferences: AppPreferences? = null
|
||||||
|
|
||||||
lateinit var message: ChatMessage
|
@Inject
|
||||||
|
@JvmField
|
||||||
|
var ncApi: NcApi? = null
|
||||||
|
|
||||||
lateinit var handler: Handler
|
lateinit var message: ChatMessage
|
||||||
|
|
||||||
lateinit var reactionsInterface: ReactionsInterface
|
lateinit var reactionsInterface: ReactionsInterface
|
||||||
|
|
||||||
@ -98,6 +108,8 @@ class OutcomingPollMessageViewHolder(outcomingView: View) : MessageHolders
|
|||||||
|
|
||||||
binding.checkMark.setContentDescription(readStatusContentDescriptionString)
|
binding.checkMark.setContentDescription(readStatusContentDescriptionString)
|
||||||
|
|
||||||
|
setPollPreview(message)
|
||||||
|
|
||||||
Reaction().showReactions(message, binding.reactions, binding.messageTime.context, true)
|
Reaction().showReactions(message, binding.reactions, binding.messageTime.context, true)
|
||||||
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
||||||
reactionsInterface.onClickReactions(message)
|
reactionsInterface.onClickReactions(message)
|
||||||
@ -108,6 +120,73 @@ class OutcomingPollMessageViewHolder(outcomingView: View) : MessageHolders
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setPollPreview(message: ChatMessage) {
|
||||||
|
var pollId: String? = null
|
||||||
|
var pollName: String? = null
|
||||||
|
|
||||||
|
if (message.messageParameters != null && message.messageParameters!!.size > 0) {
|
||||||
|
for (key in message.messageParameters!!.keys) {
|
||||||
|
val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!!
|
||||||
|
if (individualHashMap["type"] == "talk-poll") {
|
||||||
|
pollId = individualHashMap["id"]
|
||||||
|
pollName = individualHashMap["name"].toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pollId != null && pollName != null) {
|
||||||
|
binding.messagePollTitle.text = pollName
|
||||||
|
|
||||||
|
val roomToken = (payload as? MessagePayload)!!.roomToken
|
||||||
|
|
||||||
|
binding.bubble.setOnClickListener {
|
||||||
|
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
||||||
|
roomToken,
|
||||||
|
pollId,
|
||||||
|
pollName
|
||||||
|
)
|
||||||
|
pollVoteDialog.show(
|
||||||
|
(binding.messagePollIcon.context as MainActivity).supportFragmentManager,
|
||||||
|
TAG
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val credentials = ApiUtils.getCredentials(message.activeUser?.username, message.activeUser?.token)
|
||||||
|
ncApi!!.getPoll(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForPoll(
|
||||||
|
message.activeUser?.baseUrl,
|
||||||
|
roomToken,
|
||||||
|
pollId
|
||||||
|
)
|
||||||
|
).subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(object : Observer<PollOverall> {
|
||||||
|
override fun onSubscribe(d: Disposable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNext(pollOverall: PollOverall) {
|
||||||
|
if (pollOverall.ocs!!.data!!.status == 0) {
|
||||||
|
binding.messagePollSubtitle.text =
|
||||||
|
context?.resources?.getString(R.string.message_poll_tap_to_vote)
|
||||||
|
} else {
|
||||||
|
binding.messagePollSubtitle.text =
|
||||||
|
context?.resources?.getString(R.string.message_poll_tap_see_results)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.e(TAG, "Error while fetching poll", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
||||||
if (!message.isDeleted && message.parentMessage != null) {
|
if (!message.isDeleted && message.parentMessage != null) {
|
||||||
val parentChatMessage = message.parentMessage
|
val parentChatMessage = message.parentMessage
|
||||||
|
@ -532,9 +532,14 @@ public interface NcApi {
|
|||||||
Observable<PollOverall> getPoll(@Header("Authorization") String authorization,
|
Observable<PollOverall> getPoll(@Header("Authorization") String authorization,
|
||||||
@Url String url);
|
@Url String url);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
@POST
|
@POST
|
||||||
Observable<PollOverall> createPoll(@Header("Authorization") String authorization,
|
Observable<PollOverall> createPoll(@Header("Authorization") String authorization,
|
||||||
@Url String url);
|
@Url String url,
|
||||||
|
@Query("question") String question,
|
||||||
|
@Field("options[]") List<String> options,
|
||||||
|
@Query("resultMode") Integer resultMode,
|
||||||
|
@Query("maxVotes") Integer maxVotes);
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST
|
@POST
|
||||||
|
@ -142,6 +142,7 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall
|
|||||||
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
import com.nextcloud.talk.models.json.conversations.RoomsOverall
|
||||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||||
import com.nextcloud.talk.models.json.mention.Mention
|
import com.nextcloud.talk.models.json.mention.Mention
|
||||||
|
import com.nextcloud.talk.polls.ui.PollCreateDialogFragment
|
||||||
import com.nextcloud.talk.presenters.MentionAutocompletePresenter
|
import com.nextcloud.talk.presenters.MentionAutocompletePresenter
|
||||||
import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity
|
import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity
|
||||||
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
|
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
|
||||||
@ -3138,6 +3139,16 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createPoll() {
|
||||||
|
val pollVoteDialog = PollCreateDialogFragment.newInstance(
|
||||||
|
roomToken!!
|
||||||
|
)
|
||||||
|
pollVoteDialog.show(
|
||||||
|
(activity as MainActivity?)!!.supportFragmentManager,
|
||||||
|
TAG
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "ChatController"
|
private const val TAG = "ChatController"
|
||||||
private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 1
|
private const val CONTENT_TYPE_SYSTEM_MESSAGE: Byte = 1
|
||||||
|
@ -25,8 +25,9 @@ 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.PollCreateViewModel
|
||||||
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollViewModel
|
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
|
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
|
||||||
@ -66,8 +67,8 @@ abstract class ViewModelModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@ViewModelKey(PollViewModel::class)
|
@ViewModelKey(PollMainViewModel::class)
|
||||||
abstract fun pollViewModel(viewModel: PollViewModel): ViewModel
|
abstract fun pollViewModel(viewModel: PollMainViewModel): ViewModel
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@ -79,6 +80,11 @@ abstract class ViewModelModule {
|
|||||||
@ViewModelKey(PollResultsViewModel::class)
|
@ViewModelKey(PollResultsViewModel::class)
|
||||||
abstract fun pollResultsViewModel(viewModel: PollResultsViewModel): ViewModel
|
abstract fun pollResultsViewModel(viewModel: PollResultsViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@ViewModelKey(PollCreateViewModel::class)
|
||||||
|
abstract fun pollCreateViewModel(viewModel: PollCreateViewModel): ViewModel
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@ViewModelKey(RemoteFileBrowserItemsViewModel::class)
|
@ViewModelKey(RemoteFileBrowserItemsViewModel::class)
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
class PollCreateOptionItem(
|
||||||
|
var pollOption: String
|
||||||
|
)
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding
|
||||||
|
|
||||||
|
class PollCreateOptionViewHolder(
|
||||||
|
private val binding: PollCreateOptionsItemBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
fun bind(
|
||||||
|
pollCreateOptionItem: PollCreateOptionItem,
|
||||||
|
clickListener: PollCreateOptionsItemClickListener,
|
||||||
|
position: Int
|
||||||
|
) {
|
||||||
|
// binding.root.setOnClickListener { }
|
||||||
|
|
||||||
|
binding.pollOptionDelete.setOnClickListener {
|
||||||
|
clickListener.onDeleteClick(pollCreateOptionItem, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
// binding.pollOptionText.addTextChangedListener(object : TextWatcher {
|
||||||
|
// override fun afterTextChanged(s: Editable) {
|
||||||
|
// // unused atm
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
|
// // unused atm
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onTextChanged(option: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
// pollCreateOptionItem.pollOption = option.toString()
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
// fun onBind(item: SharedItem) {
|
||||||
|
// Log.d("","bbbb")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun onLongClick(view: View?): Boolean {
|
||||||
|
// // moviesList.remove(getAdapterPosition())
|
||||||
|
// // notifyItemRemoved(getAdapterPosition())
|
||||||
|
//
|
||||||
|
// Log.d("", "dfdrg")
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onClick(v: View?) {
|
||||||
|
// Log.d("", "dfdrg")
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding
|
||||||
|
|
||||||
|
class PollCreateOptionsAdapter(
|
||||||
|
private val clickListener: PollCreateOptionsItemClickListener
|
||||||
|
) : RecyclerView.Adapter<PollCreateOptionViewHolder>() {
|
||||||
|
|
||||||
|
internal var list: MutableList<PollCreateOptionItem> = ArrayList<PollCreateOptionItem>()
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollCreateOptionViewHolder {
|
||||||
|
val itemBinding = PollCreateOptionsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
|
||||||
|
return PollCreateOptionViewHolder(itemBinding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: PollCreateOptionViewHolder, position: Int) {
|
||||||
|
holder.bind(list[position], clickListener, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return list.size
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
interface PollCreateOptionsItemClickListener {
|
||||||
|
fun onDeleteClick(pollCreateOptionItem: PollCreateOptionItem, position: Int)
|
||||||
|
}
|
@ -8,4 +8,12 @@ interface PollRepository {
|
|||||||
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
||||||
|
|
||||||
fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>?
|
fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>?
|
||||||
|
|
||||||
|
fun createPoll(
|
||||||
|
roomToken: String,
|
||||||
|
question: String,
|
||||||
|
options: List<String>,
|
||||||
|
resultMode: Int,
|
||||||
|
maxVotes: Int
|
||||||
|
): Observable<Poll>?
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,24 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
|||||||
currentUserProvider.currentUser?.token
|
currentUserProvider.currentUser?.token
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override fun createPoll(
|
||||||
|
roomToken: String, question: String, options: List<String>, resultMode: Int, maxVotes:
|
||||||
|
Int
|
||||||
|
):
|
||||||
|
Observable<Poll>? {
|
||||||
|
return ncApi.createPoll(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForPoll(
|
||||||
|
currentUserProvider.currentUser?.baseUrl,
|
||||||
|
roomToken
|
||||||
|
),
|
||||||
|
question,
|
||||||
|
options,
|
||||||
|
resultMode,
|
||||||
|
maxVotes
|
||||||
|
).map { mapToPoll(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun getPoll(roomToken: String, pollId: String): Observable<Poll> {
|
override fun getPoll(roomToken: String, pollId: String): Observable<Poll> {
|
||||||
|
|
||||||
return ncApi.getPoll(
|
return ncApi.getPoll(
|
||||||
|
@ -0,0 +1,155 @@
|
|||||||
|
package com.nextcloud.talk.polls.ui
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import autodagger.AutoInjector
|
||||||
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
|
import com.nextcloud.talk.databinding.DialogPollCreateBinding
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollCreateOptionItem
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollCreateOptionsAdapter
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollCreateOptionsItemClickListener
|
||||||
|
import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
|
class PollCreateDialogFragment(
|
||||||
|
private val roomToken: String
|
||||||
|
) : DialogFragment(), PollCreateOptionsItemClickListener {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
|
private lateinit var binding: DialogPollCreateBinding
|
||||||
|
private lateinit var viewModel: PollCreateViewModel
|
||||||
|
|
||||||
|
private var adapter: PollCreateOptionsAdapter? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this, viewModelFactory)[PollCreateViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("InflateParams")
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
binding = DialogPollCreateBinding.inflate(LayoutInflater.from(context))
|
||||||
|
|
||||||
|
val dialog = AlertDialog.Builder(requireContext())
|
||||||
|
.setView(binding.root)
|
||||||
|
.create()
|
||||||
|
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
adapter = PollCreateOptionsAdapter(this)
|
||||||
|
binding?.pollCreateOptionsList?.adapter = adapter
|
||||||
|
binding?.pollCreateOptionsList?.layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
|
viewModel.initialize(roomToken)
|
||||||
|
|
||||||
|
for (i in 1..3) {
|
||||||
|
val item = PollCreateOptionItem("a")
|
||||||
|
adapter?.list?.add(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pollAddOption.setOnClickListener {
|
||||||
|
val item = PollCreateOptionItem("a")
|
||||||
|
adapter?.list?.add(item)
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pollDismiss.setOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
binding.pollCreateQuestion.addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun afterTextChanged(s: Editable) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
|
// unused atm
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(question: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
viewModel.question = question.toString()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// binding.option1.addTextChangedListener(object : TextWatcher {
|
||||||
|
// override fun afterTextChanged(s: Editable) {
|
||||||
|
// // unused atm
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||||
|
// // unused atm
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun onTextChanged(option: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
// viewModel.options = listOf(option.toString())
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
binding.pollPrivatePollCheckbox.setOnClickListener {
|
||||||
|
viewModel.multipleAnswer = binding.pollMultipleAnswersCheckbox.isChecked
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pollMultipleAnswersCheckbox.setOnClickListener {
|
||||||
|
viewModel.multipleAnswer = binding.pollMultipleAnswersCheckbox.isChecked
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pollCreateButton.setOnClickListener {
|
||||||
|
viewModel.createPoll()
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
|
when (state) {
|
||||||
|
PollCreateViewModel.InitialState -> {}
|
||||||
|
|
||||||
|
is PollCreateViewModel.PollCreatedState -> {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.initialize(roomToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDeleteClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) {
|
||||||
|
adapter?.list?.remove(pollCreateOptionItem)
|
||||||
|
adapter?.notifyItemRemoved(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment creator
|
||||||
|
*/
|
||||||
|
companion object {
|
||||||
|
private val TAG = PollCreateDialogFragment::class.java.simpleName
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun newInstance(
|
||||||
|
roomTokenParam: String
|
||||||
|
): PollCreateDialogFragment = PollCreateDialogFragment(roomTokenParam)
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ import autodagger.AutoInjector
|
|||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
||||||
import com.nextcloud.talk.polls.model.Poll
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
@ -27,13 +27,13 @@ class PollMainDialogFragment(
|
|||||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
private lateinit var binding: DialogPollMainBinding
|
private lateinit var binding: DialogPollMainBinding
|
||||||
private lateinit var viewModel: PollViewModel
|
private lateinit var viewModel: PollMainViewModel
|
||||||
|
|
||||||
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]
|
viewModel = ViewModelProvider(this, viewModelFactory)[PollMainViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
@ -58,9 +58,9 @@ class PollMainDialogFragment(
|
|||||||
|
|
||||||
viewModel.viewState.observe(viewLifecycleOwner) { state ->
|
viewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
PollViewModel.InitialState -> {}
|
PollMainViewModel.InitialState -> {}
|
||||||
|
|
||||||
is PollViewModel.PollVotedState -> {
|
is PollMainViewModel.PollVotedState -> {
|
||||||
if (state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
if (state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
||||||
showVoteFragment()
|
showVoteFragment()
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +68,7 @@ class PollMainDialogFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is PollViewModel.PollUnvotedState -> {
|
is PollMainViewModel.PollUnvotedState -> {
|
||||||
if (state.poll.status == Poll.STATUS_CLOSED) {
|
if (state.poll.status == Poll.STATUS_CLOSED) {
|
||||||
showResultsFragment()
|
showResultsFragment()
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,13 +37,13 @@ import com.nextcloud.talk.polls.adapters.PollResultItem
|
|||||||
import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
||||||
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
||||||
import com.nextcloud.talk.polls.model.Poll
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollViewModel
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class PollResultsFragment(
|
class PollResultsFragment(
|
||||||
private val parentViewModel: PollViewModel,
|
private val parentViewModel: PollMainViewModel,
|
||||||
private val roomToken: String,
|
private val roomToken: String,
|
||||||
private val pollId: String
|
private val pollId: String
|
||||||
) : Fragment(), PollResultItemClickListener {
|
) : Fragment(), PollResultItemClickListener {
|
||||||
@ -82,14 +82,14 @@ class PollResultsFragment(
|
|||||||
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollViewModel.PollVotedState &&
|
if (state is PollMainViewModel.PollVotedState &&
|
||||||
state.poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
state.poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||||
) {
|
) {
|
||||||
|
|
||||||
initPollResults(state.poll)
|
initPollResults(state.poll)
|
||||||
initAmountVotersInfo(state)
|
initAmountVotersInfo(state)
|
||||||
initEditButton(state)
|
initEditButton(state)
|
||||||
} else if (state is PollViewModel.PollUnvotedState &&
|
} else if (state is PollMainViewModel.PollUnvotedState &&
|
||||||
state.poll.status == Poll.STATUS_CLOSED
|
state.poll.status == Poll.STATUS_CLOSED
|
||||||
) {
|
) {
|
||||||
Log.d(TAG, "show results also if self never voted")
|
Log.d(TAG, "show results also if self never voted")
|
||||||
@ -129,14 +129,14 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initAmountVotersInfo(state: PollViewModel.PollVotedState) {
|
private fun initAmountVotersInfo(state: PollMainViewModel.PollVotedState) {
|
||||||
_binding?.pollAmountVoters?.text = String.format(
|
_binding?.pollAmountVoters?.text = String.format(
|
||||||
resources.getString(R.string.polls_amount_voters),
|
resources.getString(R.string.polls_amount_voters),
|
||||||
state.poll.numVoters
|
state.poll.numVoters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initEditButton(state: PollViewModel.PollVotedState) {
|
private fun initEditButton(state: PollMainViewModel.PollVotedState) {
|
||||||
if (state.poll.status == Poll.STATUS_OPEN && state.poll.resultMode == Poll.RESULT_MODE_PUBLIC) {
|
if (state.poll.status == Poll.STATUS_OPEN && state.poll.resultMode == Poll.RESULT_MODE_PUBLIC) {
|
||||||
_binding?.editVoteButton?.visibility = View.VISIBLE
|
_binding?.editVoteButton?.visibility = View.VISIBLE
|
||||||
_binding?.editVoteButton?.setOnClickListener {
|
_binding?.editVoteButton?.setOnClickListener {
|
||||||
@ -147,6 +147,10 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onClick(pollResultItem: PollResultItem) {
|
||||||
|
Log.d(TAG, "click..")
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
_binding = null
|
||||||
@ -155,8 +159,4 @@ class PollResultsFragment(
|
|||||||
companion object {
|
companion object {
|
||||||
private val TAG = PollResultsFragment::class.java.simpleName
|
private val TAG = PollResultsFragment::class.java.simpleName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(pollResultItem: PollResultItem) {
|
|
||||||
Log.d(TAG, "click..")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,13 @@ 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.DialogPollVoteBinding
|
||||||
import com.nextcloud.talk.polls.model.Poll
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class PollVoteFragment(
|
class PollVoteFragment(
|
||||||
private val parentViewModel: PollViewModel,
|
private val parentViewModel: PollMainViewModel,
|
||||||
private val roomToken: String,
|
private val roomToken: String,
|
||||||
private val pollId: String
|
private val pollId: String
|
||||||
) : Fragment() {
|
) : Fragment() {
|
||||||
@ -71,7 +71,7 @@ class PollVoteFragment(
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollViewModel.PollUnvotedState) {
|
if (state is PollMainViewModel.PollUnvotedState) {
|
||||||
val poll = state.poll
|
val poll = state.poll
|
||||||
binding.radioGroup.removeAllViews()
|
binding.radioGroup.removeAllViews()
|
||||||
poll.options?.map { option ->
|
poll.options?.map { option ->
|
||||||
@ -80,7 +80,7 @@ class PollVoteFragment(
|
|||||||
radioButton.id = index
|
radioButton.id = index
|
||||||
binding.radioGroup.addView(radioButton)
|
binding.radioGroup.addView(radioButton)
|
||||||
}
|
}
|
||||||
} else if (state is PollViewModel.PollVotedState && state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
} else if (state is PollMainViewModel.PollVotedState && state.poll.resultMode == Poll.RESULT_MODE_HIDDEN) {
|
||||||
Log.d(TAG, "show vote screen also for resultMode hidden poll when already voted")
|
Log.d(TAG, "show vote screen also for resultMode hidden poll when already voted")
|
||||||
// TODO: other text for submit button
|
// TODO: other text for submit button
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.nextcloud.talk.polls.viewmodels
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
|
import com.nextcloud.talk.polls.repositories.PollRepository
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class PollCreateViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
||||||
|
|
||||||
|
private lateinit var roomToken: String
|
||||||
|
|
||||||
|
lateinit var question: String
|
||||||
|
lateinit var options: List<String>
|
||||||
|
var privatePoll: Boolean = false
|
||||||
|
var multipleAnswer: Boolean = false
|
||||||
|
|
||||||
|
sealed interface ViewState
|
||||||
|
object InitialState : ViewState
|
||||||
|
open class PollCreatingState() : ViewState
|
||||||
|
open class PollCreatedState() : ViewState
|
||||||
|
open class PollCreationFailedState() : ViewState
|
||||||
|
|
||||||
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
|
val viewState: LiveData<ViewState>
|
||||||
|
get() = _viewState
|
||||||
|
|
||||||
|
private var disposable: Disposable? = null
|
||||||
|
|
||||||
|
fun initialize(roomToken: String) {
|
||||||
|
this.roomToken = roomToken
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
disposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createPoll() {
|
||||||
|
var maxVotes = 1
|
||||||
|
if (multipleAnswer) {
|
||||||
|
maxVotes = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultMode = 0
|
||||||
|
if (privatePoll) {
|
||||||
|
resultMode = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
repository.createPoll(roomToken, question, options, resultMode, maxVotes)
|
||||||
|
?.doOnSubscribe { disposable = it }
|
||||||
|
?.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(PollObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class PollObserver : Observer<Poll> {
|
||||||
|
|
||||||
|
lateinit var poll: Poll
|
||||||
|
|
||||||
|
override fun onSubscribe(d: Disposable) = Unit
|
||||||
|
|
||||||
|
override fun onNext(response: Poll) {
|
||||||
|
poll = response
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
_viewState.value = PollCreationFailedState()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
_viewState.value = PollCreatedState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = PollCreateViewModel::class.java.simpleName
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@ import javax.inject.Inject
|
|||||||
* InitialState --> PollClosedState
|
* InitialState --> PollClosedState
|
||||||
* @enduml
|
* @enduml
|
||||||
*/
|
*/
|
||||||
class PollViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
class PollMainViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
||||||
|
|
||||||
private lateinit var roomToken: String
|
private lateinit var roomToken: String
|
||||||
private lateinit var pollId: String
|
private lateinit var pollId: String
|
||||||
@ -97,6 +97,6 @@ class PollViewModel @Inject constructor(private val repository: PollRepository)
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = PollViewModel::class.java.simpleName
|
private val TAG = PollMainViewModel::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -74,6 +74,11 @@ class AttachmentDialog(val activity: Activity, var chatController: ChatControlle
|
|||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogAttachmentBinding.menuAttachPoll.setOnClickListener {
|
||||||
|
chatController.createPoll()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
dialogAttachmentBinding.menuAttachFileFromCloud.setOnClickListener {
|
dialogAttachmentBinding.menuAttachFileFromCloud.setOnClickListener {
|
||||||
chatController.showBrowserScreen()
|
chatController.showBrowserScreen()
|
||||||
dismiss()
|
dismiss()
|
||||||
|
10
app/src/main/res/drawable/ic_baseline_close_24.xml
Normal file
10
app/src/main/res/drawable/ic_baseline_close_24.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector android:height="24dp"
|
||||||
|
android:tint="#000000"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:width="24dp"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
|
||||||
|
</vector>
|
@ -39,6 +39,39 @@
|
|||||||
android:textColor="@color/medium_emphasis_text"
|
android:textColor="@color/medium_emphasis_text"
|
||||||
android:textSize="@dimen/bottom_sheet_text_size" />
|
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/menu_attach_poll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_sheet_item_height"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="@dimen/standard_padding"
|
||||||
|
android:paddingEnd="@dimen/standard_padding"
|
||||||
|
tools:ignore="UseCompoundDrawables">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/menu_icon_attach_poll"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_baseline_bar_chart_24"
|
||||||
|
app:tint="@color/high_emphasis_menu_icon" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/txt_attach_poll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="start|center_vertical"
|
||||||
|
android:paddingStart="@dimen/standard_double_padding"
|
||||||
|
android:paddingEnd="@dimen/zero"
|
||||||
|
android:text="@string/nc_create_poll"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textColor="@color/high_emphasis_text"
|
||||||
|
android:textSize="@dimen/bottom_sheet_text_size" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/menu_attach_contact"
|
android:id="@+id/menu_attach_contact"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
133
app/src/main/res/layout/dialog_poll_create.xml
Normal file
133
app/src/main/res/layout/dialog_poll_create.xml
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<!--
|
||||||
|
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/>.
|
||||||
|
-->
|
||||||
|
<LinearLayout 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"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/standard_padding"
|
||||||
|
tools:background="@color/white">
|
||||||
|
|
||||||
|
<!-- <androidx.emoji.widget.EmojiTextView-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:text="@string/nc_create_poll"-->
|
||||||
|
<!-- android:textStyle="bold"-->
|
||||||
|
<!-- android:layout_marginBottom="@dimen/standard_half_margin"/>-->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="Question" />
|
||||||
|
|
||||||
|
<com.nextcloud.talk.utils.EmojiTextInputEditText
|
||||||
|
android:id="@+id/poll_create_question"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginTop="@dimen/standard_margin"
|
||||||
|
android:text="Options" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/poll_create_options_list_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/poll_create_options_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:listitem="@layout/poll_create_options_item" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/poll_add_option"
|
||||||
|
style="@style/OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/standard_half_margin"
|
||||||
|
app:icon="@drawable/ic_add_grey600_24px"
|
||||||
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:text="@string/polls_add_option" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginTop="@dimen/standard_margin"
|
||||||
|
android:layout_marginBottom="@dimen/standard_half_margin"
|
||||||
|
|
||||||
|
android:text="Settings" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/poll_private_poll_checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Private poll" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/poll_multiple_answers_checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Multiple answers" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="@dimen/standard_margin"
|
||||||
|
|
||||||
|
android:gravity="end">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/poll_dismiss"
|
||||||
|
style="@style/OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/standard_half_margin"
|
||||||
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:text="@string/nc_common_dismiss" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/poll_create_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/standard_half_margin"
|
||||||
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:text="@string/nc_create_poll"
|
||||||
|
android:theme="@style/Button.Primary" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -47,11 +47,36 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:gravity="center_vertical"
|
||||||
android:gravity="center_vertical">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/message_poll_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_baseline_bar_chart_24"
|
||||||
|
app:tint="@color/nc_outcoming_text_default" />
|
||||||
|
|
||||||
|
<androidx.emoji.widget.EmojiTextView
|
||||||
|
android:id="@+id/message_poll_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/nc_outcoming_text_default"
|
||||||
|
tools:text="This is the poll title?" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/message_poll_subtitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/double_margin_between_elements"
|
||||||
|
android:text="@string/message_poll_tap_to_vote"
|
||||||
|
android:textColor="@color/nc_outcoming_text_default" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@id/messageTime"
|
android:id="@id/messageTime"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -59,6 +84,7 @@
|
|||||||
android:layout_below="@id/messageText"
|
android:layout_below="@id/messageText"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
app:layout_alignSelf="center"
|
app:layout_alignSelf="center"
|
||||||
|
android:textColor="@color/nc_outcoming_text_default"
|
||||||
tools:text="10:35" />
|
tools:text="10:35" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -67,6 +93,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/messageTime"
|
android:layout_below="@id/messageTime"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
android:textColor="@color/nc_outcoming_text_default"
|
||||||
app:layout_alignSelf="center"
|
app:layout_alignSelf="center"
|
||||||
android:contentDescription="@null" />
|
android:contentDescription="@null" />
|
||||||
|
|
||||||
|
27
app/src/main/res/layout/poll_create_options_item.xml
Normal file
27
app/src/main/res/layout/poll_create_options_item.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<LinearLayout 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:orientation="horizontal"
|
||||||
|
tools:background="@color/white">
|
||||||
|
|
||||||
|
<com.nextcloud.talk.utils.EmojiTextInputEditText
|
||||||
|
android:id="@+id/poll_option_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/poll_option_delete"
|
||||||
|
style="@style/Widget.AppTheme.Button.IconButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:contentDescription="@string/nc_action_open_main_menu"
|
||||||
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
app:icon="@drawable/ic_baseline_close_24"
|
||||||
|
app:iconTint="@color/fontAppbar" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -26,6 +26,7 @@
|
|||||||
<string name="nc_no">No</string>
|
<string name="nc_no">No</string>
|
||||||
<string name="nc_common_skip">Skip</string>
|
<string name="nc_common_skip">Skip</string>
|
||||||
<string name="nc_common_set">Set</string>
|
<string name="nc_common_set">Set</string>
|
||||||
|
<string name="nc_common_dismiss">Dismiss</string>
|
||||||
<string name="nc_common_error_sorry">Sorry, something went wrong!</string>
|
<string name="nc_common_error_sorry">Sorry, something went wrong!</string>
|
||||||
<string name="nc_common_submit">Submit</string>
|
<string name="nc_common_submit">Submit</string>
|
||||||
|
|
||||||
@ -404,6 +405,7 @@
|
|||||||
<!-- Upload -->
|
<!-- Upload -->
|
||||||
<string name="nc_add_file">Add to conversation</string>
|
<string name="nc_add_file">Add to conversation</string>
|
||||||
<string name="nc_upload_picture_from_cam">Take photo</string>
|
<string name="nc_upload_picture_from_cam">Take photo</string>
|
||||||
|
<string name="nc_create_poll">Create poll</string>
|
||||||
<string name="nc_upload_from_cloud">Share from %1$s</string>
|
<string name="nc_upload_from_cloud">Share from %1$s</string>
|
||||||
<string name="nc_upload_failed">Sorry, upload failed</string>
|
<string name="nc_upload_failed">Sorry, upload failed</string>
|
||||||
<string name="nc_upload_choose_local_files">Choose files</string>
|
<string name="nc_upload_choose_local_files">Choose files</string>
|
||||||
@ -536,6 +538,7 @@
|
|||||||
|
|
||||||
<!-- Polls -->
|
<!-- Polls -->
|
||||||
<string name="polls_amount_voters">Poll results - %1$s votes</string>
|
<string name="polls_amount_voters">Poll results - %1$s votes</string>
|
||||||
|
<string name="polls_add_option">Add Option</string>
|
||||||
|
|
||||||
<string name="title_attachments">Attachments</string>
|
<string name="title_attachments">Attachments</string>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user