Unverified Commit e2029191 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito Committed by GitHub

Merge branch 'develop' into feature/compress-image

parents dc28b88d 796f6c26
...@@ -239,8 +239,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -239,8 +239,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
} }
override suspend fun updateChatRooms(newDataSet: List<ChatRoom>) { override suspend fun updateChatRooms(newDataSet: List<ChatRoom>) {}
}
override fun showNoChatRoomsToDisplay() { override fun showNoChatRoomsToDisplay() {
ui { text_no_data_to_display.setVisible(true) } ui { text_no_data_to_display.setVisible(true) }
......
package chat.rocket.android.createchannel.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.createchannel.presentation.CreateChannelView
import chat.rocket.android.createchannel.ui.CreateChannelFragment
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.Provides
@Module
class CreateChannelModule {
@Provides
@PerFragment
fun createChannelView(fragment: CreateChannelFragment): CreateChannelView {
return fragment
}
@Provides
@PerFragment
fun provideLifecycleOwner(fragment: CreateChannelFragment): LifecycleOwner {
return fragment
}
}
\ No newline at end of file
package chat.rocket.android.createchannel.di
import chat.rocket.android.createchannel.ui.CreateChannelFragment
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class CreateChannelProvider {
@ContributesAndroidInjector(modules = [CreateChannelModule::class])
@PerFragment
abstract fun provideCreateChannelFragment(): CreateChannelFragment
}
\ No newline at end of file
package chat.rocket.android.createchannel.presentation
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.main.presentation.MainNavigator
import chat.rocket.android.members.uimodel.MemberUiModelMapper
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.common.model.RoomType
import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.createChannel
import chat.rocket.core.internal.rest.spotlight
import javax.inject.Inject
class CreateChannelPresenter @Inject constructor(
private val view: CreateChannelView,
private val strategy: CancelStrategy,
private val mapper: MemberUiModelMapper,
private val navigator: MainNavigator,
val serverInteractor: GetCurrentServerInteractor,
val factory: RocketChatClientFactory
) {
private val client: RocketChatClient = factory.create(serverInteractor.get()!!)
fun createChannel(
roomType: RoomType,
channelName: String,
usersList: List<String>,
readOnly: Boolean
) {
launchUI(strategy) {
view.showLoading()
view.disableUserInput()
try {
client.createChannel(roomType, channelName, usersList, readOnly)
view.prepareToShowChatList()
view.showChannelCreatedSuccessfullyMessage()
toChatList()
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
view.enableUserInput()
}
}
}
fun searchUser(query: String) {
launchUI(strategy) {
view.showSuggestionViewInProgress()
try {
val users = client.spotlight(query).users
if (users.isEmpty()) {
view.showNoUserSuggestion()
} else {
view.showUserSuggestion(mapper.mapToUiModelList(users))
}
} catch (ex: RocketChatException) {
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideSuggestionViewInProgress()
}
}
}
fun toChatList() = navigator.toChatList()
}
\ No newline at end of file
package chat.rocket.android.createchannel.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.members.uimodel.MemberUiModel
interface CreateChannelView : LoadingView, MessageView {
/**
* Shows the server's users suggestion (on the basis of the user typing - the query).
*
* @param dataSet The list of server's users to show.
*/
fun showUserSuggestion(dataSet: List<MemberUiModel>)
/**
* Shows no server's users suggestion.
*/
fun showNoUserSuggestion()
/**
* Shows the SuggestionView in progress.
*/
fun showSuggestionViewInProgress()
/**
* Hides the progress shown in the SuggestionView.
*/
fun hideSuggestionViewInProgress()
/**
* Shows the navigation drawer with the chat item checked before showing the chat list.
* This function is invoked after successfully created the channel.
*/
fun prepareToShowChatList()
/**
* Shows a message that a channel was successfully created.
*/
fun showChannelCreatedSuccessfullyMessage()
/**
* Enables the user input.
*/
fun enableUserInput()
/**
* Disables the user input.
*/
fun disableUserInput()
}
\ No newline at end of file
package chat.rocket.android.createchannel.ui
import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.core.view.isVisible
import androidx.core.view.postDelayed
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import chat.rocket.android.R
import chat.rocket.android.createchannel.presentation.CreateChannelPresenter
import chat.rocket.android.createchannel.presentation.CreateChannelView
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.util.extensions.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import com.google.android.material.chip.Chip
import dagger.android.support.AndroidSupportInjection
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.fragment_create_channel.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback {
@Inject
lateinit var createChannelPresenter: CreateChannelPresenter
private var actionMode: ActionMode? = null
private val adapter: MembersAdapter = MembersAdapter {
if (it.username != null) {
processSelectedMember(it.username)
}
}
private val compositeDisposable = CompositeDisposable()
private var channelType: String = RoomType.CHANNEL
private var isChannelReadOnly: Boolean = false
private var memberList = arrayListOf<String>()
companion object {
fun newInstance() = CreateChannelFragment()
}
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_create_channel)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolBar()
setupViewListeners()
setupRecyclerView()
subscribeEditTexts()
}
override fun onDestroyView() {
super.onDestroyView()
unsubscribeEditTexts()
}
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.create_channel, menu)
mode.title = getString(R.string.title_create_channel)
return true
}
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = false
override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_create_channel -> {
createChannelPresenter.createChannel(
roomTypeOf(channelType),
text_channel_name.text.toString(),
memberList,
isChannelReadOnly
)
mode.finish()
true
}
else -> {
false
}
}
}
override fun onDestroyActionMode(mode: ActionMode) {
actionMode = null
}
override fun showLoading() {
ui {
view_loading.isVisible = true
}
}
override fun hideLoading() {
ui {
view_loading.isVisible = false
}
}
override fun showMessage(resId: Int) {
ui {
showToast(resId)
}
}
override fun showMessage(message: String) {
ui {
showToast(message)
}
}
override fun showGenericErrorMessage() {
showMessage(getString(R.string.msg_generic_error))
}
override fun showUserSuggestion(dataSet: List<MemberUiModel>) {
adapter.clearData()
adapter.prependData(dataSet)
text_member_not_found.isVisible = false
recycler_view.isVisible = true
view_member_suggestion.isVisible = true
}
override fun showNoUserSuggestion() {
recycler_view.isVisible = false
text_member_not_found.isVisible = true
view_member_suggestion.isVisible = true
}
override fun showSuggestionViewInProgress() {
recycler_view.isVisible = false
text_member_not_found.isVisible = false
view_member_suggestion_loading.isVisible = true
view_member_suggestion.isVisible = true
}
override fun hideSuggestionViewInProgress() {
view_member_suggestion_loading.isVisible = false
}
override fun prepareToShowChatList() {
with(activity as MainActivity) {
setCheckedNavDrawerItem(R.id.action_chat_rooms)
openDrawer()
getDrawerLayout().postDelayed(1000) {
closeDrawer()
createChannelPresenter.toChatList()
}
}
}
override fun showChannelCreatedSuccessfullyMessage() {
showMessage(getString(R.string.msg_channel_created_successfully))
}
override fun enableUserInput() {
text_channel_name.isEnabled = true
text_invite_members.isEnabled = true
}
override fun disableUserInput() {
text_channel_name.isEnabled = false
text_invite_members.isEnabled = false
}
private fun setupToolBar() {
(activity as AppCompatActivity?)?.supportActionBar?.title =
getString(R.string.title_create_channel)
}
private fun setupViewListeners() {
switch_channel_type.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
text_channel_type.text = getString(R.string.msg_private_channel)
text_channel_type_description.text =
getString(R.string.msg_private_channel_description)
image_channel_icon.setImageDrawable(
context?.getDrawable(R.drawable.ic_lock_black_12_dp)
)
channelType = RoomType.PRIVATE_GROUP
} else {
text_channel_type.text = getString(R.string.msg_public_channel)
text_channel_type_description.text =
getString(R.string.msg_public_channel_description)
image_channel_icon.setImageDrawable(
context?.getDrawable(R.drawable.ic_hashtag_black_12dp)
)
channelType = RoomType.CHANNEL
}
}
switch_read_only.setOnCheckedChangeListener { _, isChecked ->
isChannelReadOnly = isChecked
}
}
private fun setupRecyclerView() {
ui {
recycler_view.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recycler_view.addItemDecoration(DividerItemDecoration(it))
recycler_view.adapter = adapter
}
}
private fun subscribeEditTexts() {
val channelNameDisposable = text_channel_name.asObservable()
.subscribe {
if (it.isNotBlank()) {
startActionMode()
} else {
finishActionMode()
}
}
val inviteMembersDisposable = text_invite_members.asObservable()
.debounce(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.filter { t -> t.isNotBlank() }
.subscribe {
if (it.length >= 3) {
createChannelPresenter.searchUser(it.toString())
} else {
view_member_suggestion.isVisible = false
}
}
compositeDisposable.addAll(channelNameDisposable, inviteMembersDisposable)
}
private fun unsubscribeEditTexts() {
compositeDisposable.dispose()
}
private fun startActionMode() {
if (actionMode == null) {
actionMode = (activity as AppCompatActivity).startSupportActionMode(this)
}
}
private fun finishActionMode() {
actionMode?.finish()
}
private fun processSelectedMember(username: String) {
if (memberList.contains(username)) {
showMessage(getString(R.string.msg_member_already_added))
} else {
view_member_suggestion.isVisible = false
text_invite_members.setText("")
addMember(username)
addChip(username)
chip_group_member.isVisible = true
}
}
private fun addMember(username: String) {
memberList.add(username)
}
private fun removeMember(username: String) {
memberList.remove(username)
}
private fun addChip(chipText: String) {
val chip = Chip(context)
chip.chipText = chipText
chip.isCloseIconEnabled = true
chip.setChipBackgroundColorResource(R.color.icon_grey)
setupChipOnCloseIconClickListener(chip)
chip_group_member.addView(chip)
}
private fun setupChipOnCloseIconClickListener(chip: Chip) {
chip.setOnCloseIconClickListener {
removeChip(it)
removeMember((it as Chip).chipText.toString())
// whenever we remove a chip we should process the chip group visibility.
processChipGroupVisibility()
}
}
private fun removeChip(chip: View) {
chip_group_member.removeView(chip)
}
private fun processChipGroupVisibility() {
chip_group_member.isVisible = memberList.isNotEmpty()
}
}
\ No newline at end of file
...@@ -13,6 +13,7 @@ import chat.rocket.android.chatroom.di.ChatRoomModule ...@@ -13,6 +13,7 @@ import chat.rocket.android.chatroom.di.ChatRoomModule
import chat.rocket.android.chatroom.di.FavoriteMessagesFragmentProvider import chat.rocket.android.chatroom.di.FavoriteMessagesFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
import chat.rocket.android.createchannel.di.CreateChannelProvider
import chat.rocket.android.dagger.scope.PerActivity import chat.rocket.android.dagger.scope.PerActivity
import chat.rocket.android.files.di.FilesFragmentProvider import chat.rocket.android.files.di.FilesFragmentProvider
import chat.rocket.android.main.di.MainModule import chat.rocket.android.main.di.MainModule
...@@ -22,6 +23,7 @@ import chat.rocket.android.pinnedmessages.di.PinnedMessagesFragmentProvider ...@@ -22,6 +23,7 @@ import chat.rocket.android.pinnedmessages.di.PinnedMessagesFragmentProvider
import chat.rocket.android.profile.di.ProfileFragmentProvider import chat.rocket.android.profile.di.ProfileFragmentProvider
import chat.rocket.android.server.di.ChangeServerModule import chat.rocket.android.server.di.ChangeServerModule
import chat.rocket.android.server.ui.ChangeServerActivity import chat.rocket.android.server.ui.ChangeServerActivity
import chat.rocket.android.settings.di.SettingsFragmentProvider
import chat.rocket.android.settings.password.di.PasswordFragmentProvider import chat.rocket.android.settings.password.di.PasswordFragmentProvider
import chat.rocket.android.settings.password.ui.PasswordActivity import chat.rocket.android.settings.password.ui.PasswordActivity
import dagger.Module import dagger.Module
...@@ -47,7 +49,9 @@ abstract class ActivityBuilder { ...@@ -47,7 +49,9 @@ abstract class ActivityBuilder {
@ContributesAndroidInjector( @ContributesAndroidInjector(
modules = [MainModule::class, modules = [MainModule::class,
ChatRoomsFragmentProvider::class, ChatRoomsFragmentProvider::class,
ProfileFragmentProvider::class CreateChannelProvider::class,
ProfileFragmentProvider::class,
SettingsFragmentProvider::class
] ]
) )
abstract fun bindMainActivity(): MainActivity abstract fun bindMainActivity(): MainActivity
......
...@@ -4,6 +4,7 @@ import chat.rocket.android.R ...@@ -4,6 +4,7 @@ import chat.rocket.android.R
import chat.rocket.android.authentication.ui.newServerIntent import chat.rocket.android.authentication.ui.newServerIntent
import chat.rocket.android.chatroom.ui.chatRoomIntent import chat.rocket.android.chatroom.ui.chatRoomIntent
import chat.rocket.android.chatrooms.ui.ChatRoomsFragment import chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import chat.rocket.android.createchannel.ui.CreateChannelFragment
import chat.rocket.android.main.ui.MainActivity import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.ui.ProfileFragment import chat.rocket.android.profile.ui.ProfileFragment
import chat.rocket.android.server.ui.changeServerIntent import chat.rocket.android.server.ui.changeServerIntent
...@@ -18,6 +19,12 @@ class MainNavigator(internal val activity: MainActivity) { ...@@ -18,6 +19,12 @@ class MainNavigator(internal val activity: MainActivity) {
} }
} }
fun toCreateChannel() {
activity.addFragment("CreateChannelFragment", R.id.fragment_container) {
CreateChannelFragment.newInstance()
}
}
fun toUserProfile() { fun toUserProfile() {
activity.addFragment("ProfileFragment", R.id.fragment_container) { activity.addFragment("ProfileFragment", R.id.fragment_container) {
ProfileFragment.newInstance() ProfileFragment.newInstance()
...@@ -30,15 +37,26 @@ class MainNavigator(internal val activity: MainActivity) { ...@@ -30,15 +37,26 @@ class MainNavigator(internal val activity: MainActivity) {
} }
} }
fun toChatRoom(chatRoomId: String, fun toChatRoom(
chatRoomId: String,
chatRoomName: String, chatRoomName: String,
chatRoomType: String, chatRoomType: String,
isChatRoomReadOnly: Boolean, isChatRoomReadOnly: Boolean,
chatRoomLastSeen: Long, chatRoomLastSeen: Long,
isChatRoomSubscribed: Boolean, isChatRoomSubscribed: Boolean,
isChatRoomCreator: Boolean) { isChatRoomCreator: Boolean
activity.startActivity(activity.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, ) {
isChatRoomReadOnly, chatRoomLastSeen, isChatRoomSubscribed, isChatRoomCreator)) activity.startActivity(
activity.chatRoomIntent(
chatRoomId,
chatRoomName,
chatRoomType,
isChatRoomReadOnly,
chatRoomLastSeen,
isChatRoomSubscribed,
isChatRoomCreator
)
)
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit) activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
} }
......
...@@ -55,6 +55,8 @@ class MainPresenter @Inject constructor( ...@@ -55,6 +55,8 @@ class MainPresenter @Inject constructor(
fun toSettings() = navigator.toSettings() fun toSettings() = navigator.toSettings()
fun toCreateChannel() = navigator.toCreateChannel()
fun loadCurrentInfo() { fun loadCurrentInfo() {
checkServerInfo(currentServer) checkServerInfo(currentServer)
launchUI(strategy) { launchUI(strategy) {
......
...@@ -10,6 +10,8 @@ import androidx.recyclerview.widget.LinearLayoutManager ...@@ -10,6 +10,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Gravity import android.view.Gravity
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import androidx.annotation.IdRes
import androidx.drawerlayout.widget.DrawerLayout
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.main.adapter.AccountsAdapter import chat.rocket.android.main.adapter.AccountsAdapter
...@@ -185,14 +187,14 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, ...@@ -185,14 +187,14 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp) toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp)
toolbar.setNavigationOnClickListener { toolbar.setNavigationOnClickListener {
drawer_layout.openDrawer(Gravity.START) openDrawer()
} }
} }
private fun setupNavigationView() { private fun setupNavigationView() {
view_navigation.setNavigationItemSelectedListener { menuItem -> view_navigation.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true menuItem.isChecked = true
drawer_layout.closeDrawer(Gravity.START) closeDrawer()
onNavDrawerItemSelected(menuItem) onNavDrawerItemSelected(menuItem)
true true
} }
...@@ -206,6 +208,9 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, ...@@ -206,6 +208,9 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
R.id.action_profile -> { R.id.action_profile -> {
presenter.toUserProfile() presenter.toUserProfile()
} }
R.id.action_channel -> {
presenter.toCreateChannel()
}
R.id.action_settings -> { R.id.action_settings -> {
presenter.toSettings() presenter.toSettings()
} }
...@@ -243,9 +248,25 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, ...@@ -243,9 +248,25 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
} }
header.image_avatar.setOnClickListener { header.image_avatar.setOnClickListener {
view_navigation.menu.findItem(R.id.action_profile).isChecked = true view_navigation.menu.findItem(R.id.action_update_profile).isChecked = true
presenter.toUserProfile() presenter.toUserProfile()
drawer_layout.closeDrawer(Gravity.START) drawer_layout.closeDrawer(Gravity.START)
} }
} }
fun getDrawerLayout(): DrawerLayout {
return drawer_layout
}
fun openDrawer() {
drawer_layout.openDrawer(Gravity.START)
}
fun closeDrawer() {
drawer_layout.closeDrawer(Gravity.START)
}
fun setCheckedNavDrawerItem(@IdRes item: Int) {
view_navigation.setCheckedItem(item)
}
} }
\ No newline at end of file
package chat.rocket.android.members.adapter package chat.rocket.android.members.adapter
import androidx.recyclerview.widget.RecyclerView
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.members.uimodel.MemberUiModel import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.util.extensions.content import chat.rocket.android.util.extensions.content
...@@ -10,15 +10,23 @@ import chat.rocket.android.util.extensions.inflate ...@@ -10,15 +10,23 @@ import chat.rocket.android.util.extensions.inflate
import kotlinx.android.synthetic.main.avatar.view.* import kotlinx.android.synthetic.main.avatar.view.*
import kotlinx.android.synthetic.main.item_member.view.* import kotlinx.android.synthetic.main.item_member.view.*
class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : RecyclerView.Adapter<MembersAdapter.ViewHolder>() { class MembersAdapter(private val listener: (MemberUiModel) -> Unit) :
RecyclerView.Adapter<MembersAdapter.ViewHolder>() {
private var dataSet: List<MemberUiModel> = ArrayList() private var dataSet: List<MemberUiModel> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MembersAdapter.ViewHolder = ViewHolder(parent.inflate(R.layout.item_member)) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MembersAdapter.ViewHolder =
ViewHolder(parent.inflate(R.layout.item_member))
override fun onBindViewHolder(holder: MembersAdapter.ViewHolder, position: Int) = holder.bind(dataSet[position], listener) override fun onBindViewHolder(holder: MembersAdapter.ViewHolder, position: Int) =
holder.bind(dataSet[position], listener)
override fun getItemCount(): Int = dataSet.size override fun getItemCount(): Int = dataSet.size
fun clearData() {
dataSet = emptyList()
notifyDataSetChanged()
}
fun prependData(dataSet: List<MemberUiModel>) { fun prependData(dataSet: List<MemberUiModel>) {
this.dataSet = dataSet this.dataSet = dataSet
notifyItemRangeInserted(0, dataSet.size) notifyItemRangeInserted(0, dataSet.size)
...@@ -35,7 +43,6 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : RecyclerVi ...@@ -35,7 +43,6 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : RecyclerVi
fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) { fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) {
image_avatar.setImageURI(memberUiModel.avatarUri) image_avatar.setImageURI(memberUiModel.avatarUri)
text_member.content = memberUiModel.displayName text_member.content = memberUiModel.displayName
setOnClickListener { listener(memberUiModel) } setOnClickListener { listener(memberUiModel) }
} }
} }
......
package chat.rocket.android.members.di package chat.rocket.android.members.di
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.members.ui.MembersFragment import chat.rocket.android.members.ui.MembersFragment
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
...@@ -5,7 +5,11 @@ import chat.rocket.android.util.extensions.avatarUrl ...@@ -5,7 +5,11 @@ import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.common.model.User import chat.rocket.common.model.User
import chat.rocket.core.model.Value import chat.rocket.core.model.Value
class MemberUiModel(private val member: User, private val settings: Map<String, Value<Any>>, private val baseUrl: String?) { class MemberUiModel(
private val member: User,
private val settings: Map<String, Value<Any>>,
private val baseUrl: String?
) {
val avatarUri: String? val avatarUri: String?
val displayName: String val displayName: String
val realName: String? val realName: String?
......
...@@ -13,20 +13,21 @@ import chat.rocket.android.profile.presentation.ProfilePresenter ...@@ -13,20 +13,21 @@ import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.avatar_profile.* import kotlinx.android.synthetic.main.avatar_profile.*
import kotlinx.android.synthetic.main.fragment_profile.* import kotlinx.android.synthetic.main.fragment_profile.*
import javax.inject.Inject import javax.inject.Inject
class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
@Inject lateinit var presenter: ProfilePresenter @Inject
lateinit var presenter: ProfilePresenter
private lateinit var currentName: String private lateinit var currentName: String
private lateinit var currentUsername: String private lateinit var currentUsername: String
private lateinit var currentEmail: String private lateinit var currentEmail: String
private lateinit var currentAvatar: String private lateinit var currentAvatar: String
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val disposables = CompositeDisposable() private lateinit var editTextsDisposable: Disposable
companion object { companion object {
fun newInstance() = ProfileFragment() fun newInstance() = ProfileFragment()
...@@ -37,7 +38,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -37,7 +38,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_profile) override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_profile)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
...@@ -51,8 +56,8 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -51,8 +56,8 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} }
override fun onDestroyView() { override fun onDestroyView() {
disposables.clear()
super.onDestroyView() super.onDestroyView()
unsubscribeEditTexts()
} }
override fun showProfile(avatarUrl: String, name: String, username: String, email: String?) { override fun showProfile(avatarUrl: String, name: String, username: String, email: String?) {
...@@ -71,7 +76,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -71,7 +76,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
profile_container.setVisible(true) profile_container.setVisible(true)
listenToChanges() subscribeEditTexts()
} }
} }
...@@ -119,8 +124,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -119,8 +124,13 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean { override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean {
return when (menuItem.itemId) { return when (menuItem.itemId) {
R.id.action_profile -> { R.id.action_update_profile -> {
presenter.updateUserProfile(text_email.textContent, text_name.textContent, text_username.textContent, text_avatar_url.textContent) presenter.updateUserProfile(
text_email.textContent,
text_name.textContent,
text_username.textContent,
text_avatar_url.textContent
)
mode.finish() mode.finish()
true true
} }
...@@ -135,28 +145,36 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -135,28 +145,36 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_profile) (activity as AppCompatActivity?)?.supportActionBar?.title =
getString(R.string.title_profile)
} }
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
(activity as MainActivity).apply { (activity as MainActivity).apply {
val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_24dp, this) val personDrawable =
DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_24dp, this)
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this) val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this)
val emailDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, this) val emailDrawable =
DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, this)
val linkDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_link_black_24dp, this) val linkDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_link_black_24dp, this)
val drawables = arrayOf(personDrawable, atDrawable, emailDrawable, linkDrawable) val drawables = arrayOf(personDrawable, atDrawable, emailDrawable, linkDrawable)
DrawableHelper.wrapDrawables(drawables) DrawableHelper.wrapDrawables(drawables)
DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey) DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawables(arrayOf(text_name, text_username, text_email, text_avatar_url), drawables) DrawableHelper.compoundDrawables(
arrayOf(text_name, text_username, text_email, text_avatar_url),
drawables
)
} }
} }
private fun listenToChanges() { private fun subscribeEditTexts() {
disposables.add(Observables.combineLatest(text_name.asObservable(), editTextsDisposable = Observables.combineLatest(
text_name.asObservable(),
text_username.asObservable(), text_username.asObservable(),
text_email.asObservable(), text_email.asObservable(),
text_avatar_url.asObservable()) { text_name, text_username, text_email, text_avatar_url -> text_avatar_url.asObservable()
) { text_name, text_username, text_email, text_avatar_url ->
return@combineLatest (text_name.toString() != currentName || return@combineLatest (text_name.toString() != currentName ||
text_username.toString() != currentUsername || text_username.toString() != currentUsername ||
text_email.toString() != currentEmail || text_email.toString() != currentEmail ||
...@@ -167,7 +185,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback { ...@@ -167,7 +185,11 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
} else { } else {
finishActionMode() finishActionMode()
} }
}) }
}
private fun unsubscribeEditTexts() {
editTextsDisposable.dispose()
} }
private fun startActionMode() { private fun startActionMode() {
......
...@@ -11,6 +11,7 @@ import kotlinx.coroutines.experimental.Job ...@@ -11,6 +11,7 @@ import kotlinx.coroutines.experimental.Job
@Module @Module
class SettingsFragmentModule { class SettingsFragmentModule {
@Provides @Provides
@PerFragment @PerFragment
fun settingsView(frag: SettingsFragment): SettingsView { fun settingsView(frag: SettingsFragment): SettingsView {
......
...@@ -6,6 +6,7 @@ import dagger.android.ContributesAndroidInjector ...@@ -6,6 +6,7 @@ import dagger.android.ContributesAndroidInjector
@Module @Module
abstract class SettingsFragmentProvider { abstract class SettingsFragmentProvider {
@ContributesAndroidInjector(modules = [SettingsFragmentModule::class]) @ContributesAndroidInjector(modules = [SettingsFragmentModule::class])
abstract fun provideSettingsFragment(): SettingsFragment abstract fun provideSettingsFragment(): SettingsFragment
} }
\ No newline at end of file
...@@ -16,16 +16,19 @@ import chat.rocket.android.util.extensions.inflate ...@@ -16,16 +16,19 @@ import chat.rocket.android.util.extensions.inflate
import kotlinx.android.synthetic.main.fragment_settings.* import kotlinx.android.synthetic.main.fragment_settings.*
import kotlin.reflect.KClass import kotlin.reflect.KClass
class SettingsFragment: Fragment(), SettingsView, AdapterView.OnItemClickListener { class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListener {
companion object { companion object {
fun newInstance() = SettingsFragment() fun newInstance() = SettingsFragment()
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_settings) override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_settings)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setupToolbar() setupToolbar()
setupListView() setupListView()
} }
...@@ -34,7 +37,8 @@ class SettingsFragment: Fragment(), SettingsView, AdapterView.OnItemClickListene ...@@ -34,7 +37,8 @@ class SettingsFragment: Fragment(), SettingsView, AdapterView.OnItemClickListene
when (parent?.getItemAtPosition(position).toString()) { when (parent?.getItemAtPosition(position).toString()) {
resources.getString(R.string.title_password) -> { resources.getString(R.string.title_password) -> {
startNewActivity(PasswordActivity::class) startNewActivity(PasswordActivity::class)
}resources.getString(R.string.title_about) -> { }
resources.getString(R.string.title_about) -> {
startNewActivity(AboutActivity::class) startNewActivity(AboutActivity::class)
} }
} }
...@@ -45,7 +49,8 @@ class SettingsFragment: Fragment(), SettingsView, AdapterView.OnItemClickListene ...@@ -45,7 +49,8 @@ class SettingsFragment: Fragment(), SettingsView, AdapterView.OnItemClickListene
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_settings) (activity as AppCompatActivity?)?.supportActionBar?.title =
getString(R.string.title_settings)
} }
private fun startNewActivity(classType: KClass<out AppCompatActivity>) { private fun startNewActivity(classType: KClass<out AppCompatActivity>) {
......
...@@ -4,10 +4,10 @@ import android.widget.EditText ...@@ -4,10 +4,10 @@ import android.widget.EditText
import com.jakewharton.rxbinding2.widget.RxTextView import com.jakewharton.rxbinding2.widget.RxTextView
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit import io.reactivex.schedulers.Schedulers
fun EditText.asObservable(): Observable<CharSequence> { fun EditText.asObservable(): Observable<CharSequence> {
return RxTextView.textChanges(this) return RxTextView.textChanges(this)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
} }
\ No newline at end of file
package chat.rocket.android.widget.autocompletion.ui package chat.rocket.android.widget.autocompletion.ui
import android.content.Context import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.util.AttributeSet import android.util.AttributeSet
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.view.WindowManager import android.view.WindowManager
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R import chat.rocket.android.R
internal class PopupRecyclerView : RecyclerView { internal class PopupRecyclerView : RecyclerView {
private var displayWidth: Int = 0 private var displayWidth: Int = 0
constructor(context: Context) : this(context, null) constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) 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(
val wm = context!!.getSystemService(Context.WINDOW_SERVICE) as WindowManager context,
attrs,
defStyle
) {
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val display = wm.defaultDisplay val display = wm.defaultDisplay
val size = DisplayMetrics() val size = DisplayMetrics()
display.getMetrics(size) display.getMetrics(size)
...@@ -23,8 +26,11 @@ internal class PopupRecyclerView : RecyclerView { ...@@ -23,8 +26,11 @@ internal class PopupRecyclerView : RecyclerView {
} }
override fun onMeasure(widthSpec: Int, heightSpec: Int) { override fun onMeasure(widthSpec: Int, heightSpec: Int) {
val hSpec = MeasureSpec.makeMeasureSpec(resources.getDimensionPixelSize( val hSpec = MeasureSpec.makeMeasureSpec(
R.dimen.popup_max_height), MeasureSpec.AT_MOST) resources.getDimensionPixelSize(
R.dimen.popup_max_height
), MeasureSpec.AT_MOST
)
val wSpec = MeasureSpec.makeMeasureSpec(displayWidth, MeasureSpec.EXACTLY) val wSpec = MeasureSpec.makeMeasureSpec(displayWidth, MeasureSpec.EXACTLY)
super.onMeasure(wSpec, hSpec) super.onMeasure(wSpec, hSpec)
} }
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/colorWhite"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"> android:shape="oval">
<solid <solid android:color="@color/colorAccent" />
android:color="@color/colorAccent" />
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="#10000000" /> <solid android:color="#10000000" />
<corners android:radius="5dp" /> <corners android:radius="5dp" />
<size android:height="2dp" /> <size android:height="2dp" />
</shape> </shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/toolbar_layout"
layout="@layout/layout_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="@+id/layout_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_layout">
<android.support.design.chip.ChipGroup
android:id="@+id/members_chips"
style="@style/Widget.MaterialComponents.Chip.Entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:visibility="gone"
app:chipSpacing="3dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.design.chip.ChipGroup>
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
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/text_search_member"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@android:color/transparent"
android:hint="@string/msg_search"
android:paddingBottom="8dp"
android:paddingEnd="8dp"
android:paddingStart="8dp"
app:layout_constraintTop_toBottomOf="@id/members_chips" />
<View
android:id="@+id/separator_1"
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="@color/colorDividerMessageComposer"
app:layout_constraintTop_toBottomOf="@id/text_search_member" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator_1" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -46,14 +46,13 @@ ...@@ -46,14 +46,13 @@
tools:visibility="visible" /> tools:visibility="visible" />
<TextView <TextView
android:id="@+id/text_no_search" android:id="@+id/text_no_result_found"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="56dp" android:layout_marginTop="56dp"
android:text="@string/msg_no_search_found" android:text="@string/msg_no_search_found"
android:textSize="20sp" android:textSize="20sp"
android:layout_centerHorizontal="true"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:focusableInTouchMode="true"
tools:context="createchannel.ui.CreateChannelFragment">
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<TextView
android:id="@+id/text_channel_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_public_channel"
android:textColor="@color/colorPrimaryText"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_channel_type_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_public_channel_description"
android:textColor="@color/colorSecondaryText"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_channel_type" />
<Switch
android:id="@+id/switch_channel_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/text_channel_type_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/text_channel_type" />
<TextView
android:id="@+id/text_read_only"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/msg_ready_only_channel"
android:textColor="@color/colorPrimaryText"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_channel_type_description" />
<TextView
android:id="@+id/text_read_only_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_ready_only_channel_description"
android:textColor="@color/colorSecondaryText"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_read_only" />
<Switch
android:id="@+id/switch_read_only"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/text_read_only_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/text_read_only" />
<ImageView
android:id="@+id/image_channel_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="22dp"
android:src="@drawable/ic_hashtag_black_12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_read_only_description" />
<EditText
android:id="@+id/text_channel_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/colorDim"
android:hint="@string/msg_channel_name"
android:inputType="text"
android:maxLines="1"
android:paddingEnd="10dp"
android:paddingStart="24dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/image_channel_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/image_channel_icon"
app:layout_constraintTop_toTopOf="@+id/image_channel_icon" />
<ImageView
android:id="@+id/image_invite_member"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_marginTop="16dp"
android:src="@drawable/ic_at_black_24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_channel_name" />
<EditText
android:id="@+id/text_invite_members"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="@color/colorDim"
android:hint="@string/msg_invite_members"
android:inputType="text"
android:maxLines="1"
android:paddingEnd="10dp"
android:paddingStart="24dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/image_invite_member"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/image_invite_member"
app:layout_constraintTop_toTopOf="@+id/image_invite_member" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/view_member_suggestion"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:background="@color/colorWhite"
android:elevation="2dp"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/text_invite_members">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_member_suggestion_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_member_not_found"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/msg_member_not_found"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group_member"
style="@style/Widget.MaterialComponents.Chip.Entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone"
app:chipSpacing="3dp"
app:layout_constraintTop_toBottomOf="@+id/text_invite_members" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorLightTheme"
android:textSize="18sp" />
<TextView
android:id="@+id/toolbar_action_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:gravity="end"
android:textSize="14sp" />
</android.support.v7.widget.Toolbar>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_create_channel"
android:icon="@drawable/ic_check_white_24dp"
android:title="@string/action_create" />
</menu>
\ No newline at end of file
...@@ -11,6 +11,16 @@ ...@@ -11,6 +11,16 @@
android:icon="@drawable/ic_chat_bubble_black_24dp" android:icon="@drawable/ic_chat_bubble_black_24dp"
android:title="@string/title_chats" /> android:title="@string/title_chats" />
<item
android:id="@+id/action_channel"
android:icon="@drawable/ic_create_black_24dp"
android:title="@string/action_create_channel" />
</group>
<group
android:id="@+id/menu_section_2"
android:checkableBehavior="single">
<item <item
android:id="@+id/action_profile" android:id="@+id/action_profile"
android:icon="@drawable/ic_person_black_24dp" android:icon="@drawable/ic_person_black_24dp"
...@@ -19,16 +29,16 @@ ...@@ -19,16 +29,16 @@
<item <item
android:id="@+id/action_settings" android:id="@+id/action_settings"
android:icon="@drawable/ic_settings_black_24dp" android:icon="@drawable/ic_settings_black_24dp"
android:title="@string/title_settings"/> android:title="@string/title_settings" />
</group> </group>
<group <group
android:id="@+id/menu_section_2" android:id="@+id/menu_section_3"
android:checkableBehavior="none"> android:checkableBehavior="single">
<item <item
android:id="@+id/action_logout" android:id="@+id/action_logout"
android:icon="@drawable/ic_exit_to_app_black_24dp" android:icon="@drawable/ic_exit_to_app_black_24dp"
android:title="@string/action_logout" /> android:title="@string/action_logout" />
</group> </group>
</menu> </menu>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/action_profile" android:id="@+id/action_update_profile"
android:icon="@drawable/ic_check_white_24dp" android:icon="@drawable/ic_check_white_24dp"
android:title="@string/action_update" /> android:title="@string/action_update" />
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
<string name="title_password">Cambia la contraseña</string> <string name="title_password">Cambia la contraseña</string>
<string name="title_update_profile">Actualización del perfil</string> <string name="title_update_profile">Actualización del perfil</string>
<string name="title_about">Acerca de</string> <string name="title_about">Acerca de</string>
// TODO: Add proper translation.
<string name="title_create_channel">Create Channel</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Conectar</string> <string name="action_connect">Conectar</string>
...@@ -25,6 +27,9 @@ ...@@ -25,6 +27,9 @@
<string name="action_search">Buscar</string> <string name="action_search">Buscar</string>
<string name="action_update">Actualizar</string> <string name="action_update">Actualizar</string>
<string name="action_settings">Configuraciones</string> <string name="action_settings">Configuraciones</string>
// TODO: Add proper translation.
<string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string>
<string name="action_logout">Cerrar sesión</string> <string name="action_logout">Cerrar sesión</string>
<string name="action_files">Archivos</string> <string name="action_files">Archivos</string>
<string name="action_confirm_password">Confirmar cambio de contraseña</string> <string name="action_confirm_password">Confirmar cambio de contraseña</string>
...@@ -37,7 +42,6 @@ ...@@ -37,7 +42,6 @@
// TODO: Add proper translation. // TODO: Add proper translation.
<string name="action_save_to_gallery">Save to gallery</string> <string name="action_save_to_gallery">Save to gallery</string>
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
<item name="item_password">Cambia la contraseña</item> <item name="item_password">Cambia la contraseña</item>
...@@ -123,8 +127,26 @@ ...@@ -123,8 +127,26 @@
// TODO: Add proper translation. // TODO: Add proper translation.
<string name="msg_several_users_are_typing">Several users are typing…</string> <string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">No se han encontrado resultados</string> <string name="msg_no_search_found">No se han encontrado resultados</string>
// TODO: Add proper translation.
<string name="msg_channel_name">Channel name</string>
// TODO: Add proper translation.
<string name="msg_search">Search</string>
<string name="msg_message_copied">Mensaje copiado</string> <string name="msg_message_copied">Mensaje copiado</string>
<!-- Create channel messages -->
// TODO: Add proper translation.
<string name="msg_private_channel">Private</string>
<string name="msg_public_channel">Public</string>
<string name="msg_private_channel_description">Only you and invited members can access this channel</string>
<string name="msg_public_channel_description">Everyone can access this channel</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Only admin can write new messages</string>
<string name="msg_invite_members">Invite members to channel</string>
<string name="msg_member_already_added">You have already selected this user</string>
<string name="msg_member_not_found">Member not found</string>
<string name="msg_channel_created_successfully">Channel created successfully</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nombre de la sala cambiado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nombre de la sala cambiado para: %1$s por %2$s</string>
<string name="message_user_added_by">Usuario %1$s añadido por %2$s</string> <string name="message_user_added_by">Usuario %1$s añadido por %2$s</string>
...@@ -141,7 +163,6 @@ ...@@ -141,7 +163,6 @@
// TODO:Add proper translation. // TODO:Add proper translation.
<string name="message_credentials_saved_successfully">Credentials saved successfully</string> <string name="message_credentials_saved_successfully">Credentials saved successfully</string>
<!-- Message actions --> <!-- Message actions -->
<string name="action_msg_reply">Respuesta</string> <string name="action_msg_reply">Respuesta</string>
<string name="action_msg_edit">Editar</string> <string name="action_msg_edit">Editar</string>
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
<string name="title_password">Changer le mot de passe</string> <string name="title_password">Changer le mot de passe</string>
<string name="title_update_profile">Update profile</string> <string name="title_update_profile">Update profile</string>
<string name="title_about">Sur</string> <string name="title_about">Sur</string>
// TODO: Add proper translation.
<string name="title_create_channel">Create Channel</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Se connecter</string> <string name="action_connect">Se connecter</string>
...@@ -25,6 +27,9 @@ ...@@ -25,6 +27,9 @@
<string name="action_search">Chercher</string> <string name="action_search">Chercher</string>
<string name="action_update">Mettre à jour</string> <string name="action_update">Mettre à jour</string>
<string name="action_settings">Paramètres</string> <string name="action_settings">Paramètres</string>
// TODO: Add proper translation.
<string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string>
<string name="action_logout">Se déconnecter</string> <string name="action_logout">Se déconnecter</string>
<string name="action_files">Fichiers</string> <string name="action_files">Fichiers</string>
<string name="action_confirm_password">Confirmer le mot de passe</string> <string name="action_confirm_password">Confirmer le mot de passe</string>
...@@ -122,8 +127,25 @@ ...@@ -122,8 +127,25 @@
// TODO: Add proper translation. // TODO: Add proper translation.
<string name="msg_several_users_are_typing">Several users are typing…</string> <string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">Aucun résultat trouvé</string> <string name="msg_no_search_found">Aucun résultat trouvé</string>
// TODO: Add proper translation.
<string name="msg_channel_name">Channel name</string>
// TODO: Add proper translation.
<string name="msg_search">Search</string>
<string name="msg_message_copied">Message copié</string> <string name="msg_message_copied">Message copié</string>
<!-- Create channel messages -->
// TODO: Add proper translation.
<string name="msg_private_channel">Private</string>
<string name="msg_public_channel">Public</string>
<string name="msg_private_channel_description">Only you and invited members can access this channel</string>
<string name="msg_public_channel_description">Everyone can access this channel</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Only admin can write new messages</string>
<string name="msg_invite_members">Invite members to channel</string>
<string name="msg_member_already_added">You have already selected this user</string>
<string name="msg_member_not_found">Member not found</string>
<string name="msg_channel_created_successfully">Channel created successfully</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Le nom de le salle a changé à: %1$s par %2$s</string> <string name="message_room_name_changed">Le nom de le salle a changé à: %1$s par %2$s</string>
<string name="message_user_added_by">Utilisateur %1$s ajouté par %2$s</string> <string name="message_user_added_by">Utilisateur %1$s ajouté par %2$s</string>
...@@ -137,10 +159,10 @@ ...@@ -137,10 +159,10 @@
<string name="message_unmuted">Utilisateur %1$s non muté par %2$s</string> <string name="message_unmuted">Utilisateur %1$s non muté par %2$s</string>
<string name="message_role_add">%1$s a été défini %2$s par %3$s</string> <string name="message_role_add">%1$s a été défini %2$s par %3$s</string>
<string name="message_role_removed">%1$s is no longer %2$s par %3$s</string> <string name="message_role_removed">%1$s is no longer %2$s par %3$s</string>
// TODO:Add proper translation. // TODO:Add proper translation.
<string name="message_credentials_saved_successfully">Credentials saved successfully</string> <string name="message_credentials_saved_successfully">Credentials saved successfully</string>
<!-- Message actions --> <!-- Message actions -->
<string name="action_msg_reply">Répondre</string> <string name="action_msg_reply">Répondre</string>
<string name="action_msg_edit">Modifier</string> <string name="action_msg_edit">Modifier</string>
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
<string name="title_password">पासवर्ड बदलें</string> <string name="title_password">पासवर्ड बदलें</string>
<string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string> <string name="title_update_profile">प्रोफ़ाइल अपडेट करें</string>
<string name="title_about">परिचय</string> <string name="title_about">परिचय</string>
// TODO: Add proper translation.
<string name="title_create_channel">Create Channel</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">जुडिये</string> <string name="action_connect">जुडिये</string>
...@@ -25,6 +27,9 @@ ...@@ -25,6 +27,9 @@
<string name="action_search">खोजें</string> <string name="action_search">खोजें</string>
<string name="action_update">अद्यतन करें</string> <string name="action_update">अद्यतन करें</string>
<string name="action_settings">सेटिंग्स</string> <string name="action_settings">सेटिंग्स</string>
// TODO: Add proper translation.
<string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string>
<string name="action_logout">लोग आउट करें</string> <string name="action_logout">लोग आउट करें</string>
<string name="action_files">फ़ाइलें</string> <string name="action_files">फ़ाइलें</string>
<string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string> <string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string>
...@@ -113,8 +118,25 @@ ...@@ -113,8 +118,25 @@
<string name="msg_are_typing">\u0020टाइप कर रहे हैं…</string> <string name="msg_are_typing">\u0020टाइप कर रहे हैं…</string>
<string name="msg_several_users_are_typing">कई उपयोगकर्ता टाइप कर रहे हैं…</string> <string name="msg_several_users_are_typing">कई उपयोगकर्ता टाइप कर रहे हैं…</string>
<string name="msg_no_search_found">कोई परिणाम नहीं मिला</string> <string name="msg_no_search_found">कोई परिणाम नहीं मिला</string>
// TODO: Add proper translation.
<string name="msg_channel_name">Channel name</string>
// TODO: Add proper translation.
<string name="msg_search">Search</string>
<string name="msg_message_copied">संदेश कॉपी किया गया</string> <string name="msg_message_copied">संदेश कॉपी किया गया</string>
<!-- Create channel messages -->
// TODO: Add proper translation.
<string name="msg_private_channel">Private</string>
<string name="msg_public_channel">Public</string>
<string name="msg_private_channel_description">Only you and invited members can access this channel</string>
<string name="msg_public_channel_description">Everyone can access this channel</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Only admin can write new messages</string>
<string name="msg_invite_members">Invite members to channel</string>
<string name="msg_member_already_added">You have already selected this user</string>
<string name="msg_member_not_found">Member not found</string>
<string name="msg_channel_created_successfully">Channel created successfully</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string> <string name="message_room_name_changed">%2$s ने रूम का नाम बदलकर %1$s किया</string>
<string name="message_user_added_by">उपयोगकर्ता %1$s द्वारा %2$s को जोड़ा गया</string> <string name="message_user_added_by">उपयोगकर्ता %1$s द्वारा %2$s को जोड़ा गया</string>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<string name="title_password">Alterar senha</string> <string name="title_password">Alterar senha</string>
<string name="title_update_profile">Editar perfil</string> <string name="title_update_profile">Editar perfil</string>
<string name="title_about">Sobre</string> <string name="title_about">Sobre</string>
<string name="title_create_channel">Criar chat</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Conectar</string> <string name="action_connect">Conectar</string>
...@@ -25,6 +26,8 @@ ...@@ -25,6 +26,8 @@
<string name="action_search">Pesquisar</string> <string name="action_search">Pesquisar</string>
<string name="action_update">Atualizar</string> <string name="action_update">Atualizar</string>
<string name="action_settings">Configurações</string> <string name="action_settings">Configurações</string>
<string name="action_create_channel">Criar chat</string>
<string name="action_create">Criar</string>
<string name="action_logout">Sair</string> <string name="action_logout">Sair</string>
<string name="action_files">Arquivos</string> <string name="action_files">Arquivos</string>
<string name="action_confirm_password">Confirme a nova senha</string> <string name="action_confirm_password">Confirme a nova senha</string>
...@@ -113,8 +116,22 @@ ...@@ -113,8 +116,22 @@
<string name="msg_are_typing">\u0020estão digitando…</string> <string name="msg_are_typing">\u0020estão digitando…</string>
<string name="msg_several_users_are_typing">Vários usuários estão digitando…</string> <string name="msg_several_users_are_typing">Vários usuários estão digitando…</string>
<string name="msg_no_search_found">nenhum resultado encontrado</string> <string name="msg_no_search_found">nenhum resultado encontrado</string>
<string name="msg_channel_name">Nome do chat</string>
<string name="msg_search">Buscar</string>
<string name="msg_message_copied">Mensagem copiada</string> <string name="msg_message_copied">Mensagem copiada</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Privado</string>
<string name="msg_public_channel">Público</string>
<string name="msg_private_channel_description">Somente você e membros convidados poderão acessar este chat</string>
<string name="msg_public_channel_description">Todos poderão acessar este canal</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Somemnte administradores podem escrever mensagens</string>
<string name="msg_invite_members">Convidar membros para o chat</string>
<string name="msg_member_already_added">Você já selecionou este usuário</string>
<string name="msg_member_not_found">Membro não encontrado</string>
<string name="msg_channel_created_successfully">Chat criado com sucesso</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string>
<string name="message_user_added_by">Usuário %1$s adicionado por %2$s</string> <string name="message_user_added_by">Usuário %1$s adicionado por %2$s</string>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<string name="title_password">Изменить пароль</string> <string name="title_password">Изменить пароль</string>
<string name="title_update_profile">Обновить профиль</string> <string name="title_update_profile">Обновить профиль</string>
<string name="title_about">О программе</string> <string name="title_about">О программе</string>
<string name="title_create_channel">Створити новий канал</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Соединение</string> <string name="action_connect">Соединение</string>
...@@ -25,6 +26,9 @@ ...@@ -25,6 +26,9 @@
<string name="action_search">Поиск</string> <string name="action_search">Поиск</string>
<string name="action_update">Обновить</string> <string name="action_update">Обновить</string>
<string name="action_settings">Настройки</string> <string name="action_settings">Настройки</string>
// TODO: Add proper translation.
<string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string>
<string name="action_logout">Выйти</string> <string name="action_logout">Выйти</string>
<string name="action_files">Файлы</string> <string name="action_files">Файлы</string>
<string name="action_confirm_password">Подтверждение изменения пароля</string> <string name="action_confirm_password">Подтверждение изменения пароля</string>
...@@ -113,6 +117,21 @@ ...@@ -113,6 +117,21 @@
<string name="msg_several_users_are_typing">Несколько пользователей печатают…</string> <string name="msg_several_users_are_typing">Несколько пользователей печатают…</string>
<string name="msg_no_search_found">Результатов не найдено</string> <string name="msg_no_search_found">Результатов не найдено</string>
<string name="msg_message_copied">Сообщение скопировано</string> <string name="msg_message_copied">Сообщение скопировано</string>
<string name="msg_channel_name">Назва каналу</string>
<string name="msg_search">Пошук</string>
<!-- Create channel messages -->
// TODO: Add proper translation.
<string name="msg_private_channel">Private</string>
<string name="msg_public_channel">Public</string>
<string name="msg_private_channel_description">Only you and invited members can access this channel</string>
<string name="msg_public_channel_description">Everyone can access this channel</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Only admin can write new messages</string>
<string name="msg_invite_members">Invite members to channel</string>
<string name="msg_member_already_added">You have already selected this user</string>
<string name="msg_member_not_found">Member not found</string>
<string name="msg_channel_created_successfully">Channel created successfully</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Название канала изменено на: %1$s by %2$s</string> <string name="message_room_name_changed">Название канала изменено на: %1$s by %2$s</string>
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
<dimen name="picker_popup_height">250dp</dimen> <dimen name="picker_popup_height">250dp</dimen>
<dimen name="picker_popup_width">300dp</dimen> <dimen name="picker_popup_width">300dp</dimen>
<!--Toolbar-->
<dimen name="toolbar_height">56dp</dimen>
<!-- Message --> <!-- Message -->
<dimen name="padding_quote">8dp</dimen> <dimen name="padding_quote">8dp</dimen>
<dimen name="padding_mention">4dp</dimen> <dimen name="padding_mention">4dp</dimen>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<string name="title_password">Change Password</string> <string name="title_password">Change Password</string>
<string name="title_update_profile">Update profile</string> <string name="title_update_profile">Update profile</string>
<string name="title_about">About</string> <string name="title_about">About</string>
<string name="title_create_channel">Create Channel</string>
<!-- Actions --> <!-- Actions -->
<string name="action_connect">Connect</string> <string name="action_connect">Connect</string>
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_update">Update</string> <string name="action_update">Update</string>
<string name="action_settings">Settings</string> <string name="action_settings">Settings</string>
<string name="action_create_channel">Create channel</string>
<string name="action_create">Create</string>
<string name="action_logout">Logout</string> <string name="action_logout">Logout</string>
<string name="action_files">Files</string> <string name="action_files">Files</string>
<string name="action_confirm_password">Confirm Password Change</string> <string name="action_confirm_password">Confirm Password Change</string>
...@@ -83,6 +86,8 @@ ...@@ -83,6 +86,8 @@
<string name="msg_utc_offset">UTC offset</string> <string name="msg_utc_offset">UTC offset</string>
<string name="msg_new_password">Enter New Password</string> <string name="msg_new_password">Enter New Password</string>
<string name="msg_confirm_password">Confirm New Password</string> <string name="msg_confirm_password">Confirm New Password</string>
<string name="msg_channel_name">Channel name</string>
<string name="msg_search">Search</string>
<string name="msg_unread_messages">Unread messages</string> <string name="msg_unread_messages">Unread messages</string>
<string name="msg_preview_video">Video</string> <string name="msg_preview_video">Video</string>
<string name="msg_preview_audio">Audio</string> <string name="msg_preview_audio">Audio</string>
...@@ -114,6 +119,19 @@ ...@@ -114,6 +119,19 @@
<string name="msg_are_typing">\u0020are typing…</string> <string name="msg_are_typing">\u0020are typing…</string>
<string name="msg_several_users_are_typing">Several users are typing…</string> <string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">No result found</string> <string name="msg_no_search_found">No result found</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Private</string>
<string name="msg_public_channel">Public</string>
<string name="msg_private_channel_description">Only you and invited members can access this channel</string>
<string name="msg_public_channel_description">Everyone can access this channel</string>
<string name="msg_ready_only_channel">Read only channel</string>
<string name="msg_ready_only_channel_description">Only admin can write new messages</string>
<string name="msg_invite_members">Invite members to channel</string>
<string name="msg_member_already_added">You have already selected this user</string>
<string name="msg_member_not_found">Member not found</string>
<string name="msg_channel_created_successfully">Channel created successfully</string>
<string name="msg_message_copied">Message copied</string> <string name="msg_message_copied">Message copied</string>
<!-- System messages --> <!-- System messages -->
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
</style> </style>
<style name="ToolbarTheme" parent="Base.Widget.AppCompat.Toolbar">
<item name="android:colorAccent">@color/colorLightTheme</item>
</style>
<style name="AuthenticationTheme" parent="Theme.AppCompat.NoActionBar"> <style name="AuthenticationTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:statusBarColor">@color/colorPrimaryDark</item> <item name="android:statusBarColor">@color/colorPrimaryDark</item>
<item name="android:windowBackground">@color/colorPrimary</item> <item name="android:windowBackground">@color/colorPrimary</item>
......
#Wed Sep 06 11:04:56 UYT 2017 #Fri May 18 17:08:16 IST 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
......
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