Commit 7435abb5 authored by aniket's avatar aniket

completes basic implementation of adding users to a new channel

parent 11b54eda
......@@ -544,7 +544,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onEmojiAdded(emoji: Emoji) {
val cursorPosition = text_message.selectionStart
if (cursorPosition > -1) {
text_message.text.insert(cursorPosition, EmojiParser.parse(emoji.shortname))
text_message.text?.insert(cursorPosition, EmojiParser.parse(emoji.shortname))
text_message.setSelection(cursorPosition + emoji.unicode.length)
}
}
......@@ -552,7 +552,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onNonEmojiKeyPressed(keyCode: Int) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> with(text_message) {
if (selectionStart > 0) text.delete(selectionStart - 1, selectionStart)
if (selectionStart > 0) text!!.delete(selectionStart - 1, selectionStart)
}
else -> throw IllegalArgumentException("pressed key not expected")
}
......
......@@ -4,8 +4,6 @@ import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.createChannel.addMembers.presentation.AddMembersView
import chat.rocket.android.createChannel.addMembers.ui.AddMembersActivity
import chat.rocket.android.createChannel.presentation.CreateNewChannelView
import chat.rocket.android.createChannel.ui.CreateNewChannelActivity
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
......@@ -20,7 +18,7 @@ class AddMembersModule {
@Provides
@PerActivity
fun addMembersView(activity: AddMembersActivity): AddMembersView{
fun addMembersView(activity: AddMembersActivity): AddMembersView {
return activity
}
......
......@@ -7,5 +7,5 @@ import dagger.android.ContributesAndroidInjector
@Module
abstract class AddMembersProvider {
@ContributesAndroidInjector(modules = [AddMembersModule::class])
abstract fun provideNewChannelActivity(): AddMembersActivity
abstract fun provideAddMembersActivity(): AddMembersActivity
}
\ No newline at end of file
package chat.rocket.android.createChannel.addMembers.presentation
import chat.rocket.android.core.behaviours.showMessage
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.members.viewmodel.MemberViewModelMapper
import chat.rocket.android.server.domain.GetCurrentServerInteractor
......@@ -7,7 +8,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.launchUI
import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatException
import chat.rocket.core.RocketChatClient
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.queryUsers
import javax.inject.Inject
......@@ -23,14 +24,22 @@ class AddMembersPresenter @Inject constructor(
fun queryUsersFromRegex(queryParam: String) {
if (client != null) {
view.showLoading()
launchUI(strategy) {
try {
val allMembers = retryIO("queryUsers($queryParam)") {
client.queryUsers(queryParam)
}
val memberViewModelMapper = mapper.mapToViewModelList(allMembers.result)
view.showMembers(memberViewModelMapper, allMembers.total)
} catch (ex: RocketChatException) {
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
......
......@@ -2,6 +2,13 @@ package chat.rocket.android.createChannel.addMembers.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.members.viewmodel.MemberViewModel
interface AddMembersView : LoadingView, MessageView {
/**
* Show members on the basis of query
* @param dataSet The list of members
* @param total The number of members returned
*/
fun showMembers(dataSet: List<MemberViewModel>, total: Long)
}
\ No newline at end of file
package chat.rocket.android.createChannel.addMembers.ui
import android.os.Bundle
import android.support.design.chip.Chip
import android.support.v7.app.AppCompatActivity
import android.widget.SearchView
import android.support.v7.widget.LinearLayoutManager
import android.widget.EditText
import android.widget.Toast
import chat.rocket.android.R
import chat.rocket.android.createChannel.addMembers.presentation.AddMembersPresenter
import chat.rocket.android.createChannel.addMembers.presentation.AddMembersView
import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.viewmodel.MemberViewModel
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.widget.DividerItemDecoration
import com.jakewharton.rxbinding2.widget.RxTextView
import dagger.android.AndroidInjection
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.BehaviorSubject
import kotlinx.android.synthetic.main.activity_add_members.*
import kotlinx.android.synthetic.main.activity_create_new_channel.*
import kotlinx.android.synthetic.main.layout_toolbar.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class AddMembersActivity : AppCompatActivity(), AddMembersView {
override fun showLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun hideLoading() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showMessage(resId: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showMessage(message: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun showGenericErrorMessage() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@Inject
lateinit var presenter: AddMembersPresenter
private var membersToAdd: ArrayList<String> = ArrayList()
private val adapter: MembersAdapter = MembersAdapter { memberViewModel ->
addNewChip(memberViewModel)
updateToolBar()
search_view.setText("")
}
private var linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_members)
setUpToolBar()
setUpRecyclerView()
observableFromSearchView(search_view)
.debounce(300, TimeUnit.MILLISECONDS)
.filter { item -> item.length > 1 }
.observeOn(AndroidSchedulers.mainThread())
.subscribe { query ->
{
//search for elements on the basis of query obtained and also add a function in
// login presenter
run {
adapter.reAllocateArrayList()
presenter.queryUsersFromRegex(query)
}
}
}
private fun addNewChip(memberViewModel: MemberViewModel) {
val memberChip = Chip(this)
memberChip.chipText = memberViewModel.username
memberChip.isCloseIconEnabled = true
memberChip.setChipBackgroundColorResource(R.color.icon_grey)
memberChip.setOnCloseIconClickListener { view ->
members_chips.removeView(view)
membersToAdd.remove((view as Chip).chipText.toString())
updateToolBar()
}
members_chips.addView(memberChip)
memberViewModel.username?.let { membersToAdd.add(it) }
Toast.makeText(this, membersToAdd.size.toString(), Toast.LENGTH_SHORT).show()
}
private fun updateToolBar() {
toolbar_title.text = getString(R.string.title_add_members, membersToAdd.size)
}
override fun showMembers(dataSet: List<MemberViewModel>, total: Long) {
if (adapter.itemCount == 0) {
adapter.prependData(dataSet)
// if (dataSet.size >= 59) { // TODO Check why the API retorns the specified count -1
// search_results.addOnScrollListener(object :
// EndlessRecyclerViewScrollListener(linearLayoutManager) {
// override fun onLoadMore(
// page: Int,
// totalItemsCount: Int,
// recyclerView: RecyclerView?
// ) {
// presenter.loadChatRoomsMembers(chatRoomId, chatRoomType, page * 60L)
// }
// })
// }
} else {
adapter.appendData(dataSet)
}
}
override fun showLoading() {
progress_bar.setVisible(true)
}
override fun hideLoading() {
progress_bar.setVisible(false)
}
override fun showMessage(resId: Int) {
showToast(resId)
}
override fun showMessage(message: String) {
showToast(message)
}
override fun showGenericErrorMessage() {
showMessage(getString(R.string.msg_generic_error))
}
private fun setUpToolBar() {
toolbar_title.text = getString(R.string.title_add_members)
setSupportActionBar(toolbar)
toolbar_title.text = getString(R.string.title_add_members, 0)
toolbar_action_text.text = getString(R.string.action_select_members)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
RxTextView.textChanges(channel_name_edit_text).subscribe { text ->
toolbar_action_text.isEnabled = text.isNotEmpty()
if (text.isEmpty())
toolbar_action_text.alpha = 0.8f
else
toolbar_action_text.alpha = 1.0f
}
}
private fun observableFromSearchView(searchView: SearchView): Observable<String> {
val observableSubject: BehaviorSubject<String> = BehaviorSubject.create()
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
private fun setUpRecyclerView() {
search_results.layoutManager = linearLayoutManager
search_results.adapter = adapter
search_results.addItemDecoration(DividerItemDecoration(this))
override fun onQueryTextSubmit(query: String): Boolean {
observableSubject.onComplete()
return true
}
}
override fun onQueryTextChange(newText: String): Boolean {
if (!newText.isEmpty()) {
observableSubject.onNext(newText)
}
return true
private fun observableFromSearchView(searchView: EditText): Observable<String> {
val observableSubject: BehaviorSubject<String> = BehaviorSubject.create()
RxTextView.textChanges(searchView).subscribe { text ->
if (text.isNotBlank()) {
observableSubject.onNext(text.toString())
}
})
}
return observableSubject
}
}
\ No newline at end of file
package chat.rocket.android.createChannel.ui
import android.content.Intent
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.MenuItem
import chat.rocket.android.R
import chat.rocket.android.createChannel.addMembers.ui.AddMembersActivity
import chat.rocket.android.createChannel.presentation.CreateNewChannelPresenter
import chat.rocket.android.createChannel.presentation.CreateNewChannelView
import chat.rocket.android.util.extensions.setVisible
......@@ -18,6 +20,10 @@ import javax.inject.Inject
class CreateNewChannelActivity : AppCompatActivity(), CreateNewChannelView {
@Inject
lateinit var presenter: CreateNewChannelPresenter
private var channelType: String = "public"
override fun showLoading() {
view_loading.setVisible(true)
layout_container.alpha = 0.5f
......@@ -46,10 +52,6 @@ class CreateNewChannelActivity : AppCompatActivity(), CreateNewChannelView {
showMessage(getString(R.string.msg_generic_error))
}
@Inject
lateinit var presenter: CreateNewChannelPresenter
private var channelType: String = "public"
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
android.R.id.home -> {
......@@ -94,7 +96,11 @@ class CreateNewChannelActivity : AppCompatActivity(), CreateNewChannelView {
placeholder.setImageDrawable(getDrawable(R.drawable.ic_hashtag_black))
(getDrawable(R.drawable.button_border) as GradientDrawable).setColor(resources.getColor(R.color.colorLightTheme))
(getDrawable(R.drawable.button_border) as GradientDrawable).setColor(
resources.getColor(
R.color.colorLightTheme
)
)
(getDrawable(R.drawable.button_solid) as GradientDrawable).setColor(resources.getColor(R.color.red))
private_channel.background = getDrawable(R.drawable.button_border)
......@@ -112,9 +118,16 @@ class CreateNewChannelActivity : AppCompatActivity(), CreateNewChannelView {
placeholder.setImageDrawable(getDrawable(R.drawable.ic_room_lock))
(getDrawable(R.drawable.button_border) as GradientDrawable).setColor(resources.getColor(R.color.red))
(getDrawable(R.drawable.button_border) as GradientDrawable).setColor(
resources.getColor(
R.color.red
)
)
(getDrawable(R.drawable.button_solid) as GradientDrawable).setColor(resources.getColor(R.color.colorLightTheme))
(getDrawable(R.drawable.button_solid) as GradientDrawable).setStroke(1, resources.getColor(R.color.red))
(getDrawable(R.drawable.button_solid) as GradientDrawable).setStroke(
1,
resources.getColor(R.color.red)
)
private_channel.background = getDrawable(R.drawable.button_border)
public_channel.background = getDrawable(R.drawable.button_solid)
......@@ -125,8 +138,17 @@ class CreateNewChannelActivity : AppCompatActivity(), CreateNewChannelView {
toolbar_action_text.setOnClickListener {
if (toolbar_action_text.isEnabled) {
presenter.createNewChannel(roomTypeOf(channelType), channel_name_edit_text.text.toString(), listOf("aniket03"), false)
presenter.createNewChannel(
roomTypeOf(channelType),
channel_name_edit_text.text.toString(),
listOf("aniket03"),
false
)
}
}
add_members_view.setOnClickListener {
startActivity(Intent(this, AddMembersActivity::class.java))
}
}
}
\ No newline at end of file
......@@ -14,6 +14,8 @@ import chat.rocket.android.chatroom.di.FavoriteMessagesFragmentProvider
import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import chat.rocket.android.createChannel.addMembers.di.AddMembersModule
import chat.rocket.android.createChannel.addMembers.ui.AddMembersActivity
import chat.rocket.android.createChannel.di.CreateNewChannelModule
import chat.rocket.android.createChannel.di.CreateNewChannelProvider
import chat.rocket.android.createChannel.ui.CreateNewChannelActivity
......@@ -74,4 +76,8 @@ abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = [CreateNewChannelModule::class])
abstract fun bindCreateNewChannelActivity(): CreateNewChannelActivity
@PerActivity
@ContributesAndroidInjector(modules = [AddMembersModule::class])
abstract fun bindAddMembersActivity(): AddMembersActivity
}
\ No newline at end of file
......@@ -45,7 +45,7 @@ abstract class EndlessRecyclerViewScrollListener : RecyclerView.OnScrollListener
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
override fun onScrolled(view: RecyclerView?, dx: Int, dy: Int) {
override fun onScrolled(view: RecyclerView, dx: Int, dy: Int) {
var lastVisibleItemPosition = 0
val totalItemCount = layoutManager.itemCount
......
......@@ -19,6 +19,10 @@ class MembersAdapter(private val listener: (MemberViewModel) -> Unit) : Recycler
override fun getItemCount(): Int = dataSet.size
fun reAllocateArrayList(){
this.dataSet = ArrayList()
}
fun prependData(dataSet: List<MemberViewModel>) {
this.dataSet = dataSet
notifyItemRangeInserted(0, dataSet.size)
......
......@@ -13,7 +13,7 @@ internal class PopupRecyclerView : RecyclerView {
private var displayWidth: Int = 0
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context!!, attrs, defStyle) {
val wm = context!!.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val display = wm.defaultDisplay
val size = DisplayMetrics()
......
......@@ -24,18 +24,37 @@
android:id="@+id/members_chips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:chipSpacing="2dp"
>
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="8dp"
app:chipSpacing="3dp"
style="@style/Widget.MaterialComponents.Chip.Entry">
</android.support.design.chip.ChipGroup>
<SearchView
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:indicatorColor="@color/colorPrimary"
app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/members_chips"
android:layout_margin="8dp"
android:backgroundTint="@color/colorLightTheme"
android:hint="@string/msg_search"/>
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:backgroundTint="@color/default_background"
android:hint="@string/msg_search"
app:layout_constraintTop_toBottomOf="@id/members_chips" />
<View
android:id="@+id/separator_1"
......
......@@ -146,7 +146,8 @@
android:id="@+id/add_members_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="?attr/selectableItemBackground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
......@@ -177,7 +178,6 @@
android:id="@+id/separator_3"
android:layout_width="0dp"
android:layout_height="0.5dp"
android:layout_marginTop="8dp"
android:background="@color/colorDividerMessageComposer"
app:layout_constraintTop_toBottomOf="@id/add_members_view" />
......
......@@ -16,7 +16,7 @@
<string name="title_password">Change Password</string>
<string name="title_update_profile">Update profile</string>
<string name="title_create_new_channel">Create New Channel</string>
<string name="title_add_members">Invite Members</string>
<string name="title_add_members">Invite Members (%d)</string>
<string name="title_about">About</string>
<!-- Actions -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment