Commit a99b2e79 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Changes the UI of the main view.

parent 8d2bc2c5
import android.content.Context
import android.graphics.drawable.Drawable
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import android.widget.TextView
import chat.rocket.android.R
import chat.rocket.common.model.UserStatus
......@@ -78,7 +78,7 @@ object DrawableHelper {
*
* @param textView The array of TextView.
* @param drawables The array of Drawable.
* @see compoundDrawable
* @see compoundLeftDrawable
*/
fun compoundDrawables(textView: Array<TextView>, drawables: Array<Drawable>) {
if (textView.size != drawables.size) {
......@@ -97,7 +97,7 @@ object DrawableHelper {
* @param drawable The Drawable.
* @see compoundDrawables
*/
fun compoundDrawable(textView: TextView, drawable: Drawable) =
fun compoundLeftDrawable(textView: TextView, drawable: Drawable) =
textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
/**
......@@ -105,11 +105,26 @@ object DrawableHelper {
*
* @param textView The TextView.
* @param drawable The Drawable.
* @see compoundDrawable
* @see compoundLeftDrawable
*/
fun compoundRightDrawable(textView: TextView, drawable: Drawable) =
textView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null)
/**
* Compounds a Drawable (to appear on the left and right side of a text) into a TextView.
*
* @param textView The TextView.
* @param leftDrawable The left Drawable.
* @param rightDrawable The right Drawable.
* @see compoundLeftDrawable
*/
fun compoundLeftAndRightDrawable(
textView: TextView,
leftDrawable: Drawable,
rightDrawable: Drawable
) =
textView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, rightDrawable, null)
/**
* Returns the user status drawable.
*
......
......@@ -140,7 +140,7 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_20dp, it)
DrawableHelper.wrapDrawable(atDrawable)
DrawableHelper.tintDrawable(atDrawable, it, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawable(text_username, atDrawable)
DrawableHelper.compoundLeftDrawable(text_username, atDrawable)
}
}
......
......@@ -200,7 +200,7 @@ class ChatDetailsFragment : Fragment(), ChatDetailsView {
val wrappedDrawable = DrawableHelper.wrapDrawable(it)
val mutableDrawable = wrappedDrawable.mutate()
DrawableHelper.tintDrawable(mutableDrawable, context!!, R.color.colorPrimary)
DrawableHelper.compoundDrawable(name, mutableDrawable)
DrawableHelper.compoundLeftDrawable(name, mutableDrawable)
}
}
......
package chat.rocket.android.chatrooms.ui
import androidx.appcompat.app.AlertDialog
import android.app.ProgressDialog
import android.os.Bundle
import android.os.Handler
......@@ -10,8 +9,6 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.RadioGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
......@@ -34,8 +31,6 @@ import chat.rocket.android.helper.ChatRoomsSortOrder
import chat.rocket.android.helper.Constants
import chat.rocket.android.helper.SharedPreferenceHelper
import chat.rocket.android.util.extension.onQueryTextListener
import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.ifNotNullNotEmpty
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
......@@ -58,11 +53,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
lateinit var factory: ChatRoomsViewModelFactory
@Inject
lateinit var analyticsManager: AnalyticsManager
private lateinit var viewModel: ChatRoomsViewModel
private var searchView: SearchView? = null
private var sortView: MenuItem? = null
private val handler = Handler()
private var chatRoomId: String? = null
private var progressDialog: ProgressDialog? = null
......@@ -106,6 +97,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
subscribeUi()
setupToolbar()
setupListeners()
analyticsManager.logScreenView(ScreenViewEvent.ChatRooms)
}
......@@ -116,15 +108,17 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
presenter.loadChatRoom(room)
}
recycler_view.layoutManager = LinearLayoutManager(it)
recycler_view.addItemDecoration(
with(recycler_view) {
layoutManager = LinearLayoutManager(it)
addItemDecoration(
DividerItemDecoration(
it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)
)
)
recycler_view.itemAnimator = DefaultItemAnimator()
itemAnimator = DefaultItemAnimator()
}
viewModel.getChatRooms().observe(viewLifecycleOwner, Observer { rooms ->
rooms?.let {
......@@ -134,7 +128,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
recycler_view.adapter = adapter
}
if (rooms.isNotEmpty()) {
text_no_data_to_display.isVisible = false
// text_no_data_to_display.isVisible = false
}
}
})
......@@ -165,88 +159,29 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.chatrooms, menu)
sortView = menu.findItem(R.id.action_sort)
val searchMenuItem = menu.findItem(R.id.action_search)
val searchView = searchMenuItem?.actionView as SearchView
val searchItem = menu.findItem(R.id.action_search)
searchView = searchItem?.actionView as? SearchView
searchView?.setIconifiedByDefault(false)
searchView?.maxWidth = Integer.MAX_VALUE
searchView?.onQueryTextListener { queryChatRoomsByName(it) }
with(searchView) {
setIconifiedByDefault(false)
maxWidth = Integer.MAX_VALUE
onQueryTextListener { queryChatRoomsByName(it) }
}
val expandListener = object : MenuItem.OnActionExpandListener {
searchMenuItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
// Simply setting sortView to visible won't work, so we invalidate the options
// to recreate the entire menu...
viewModel.showLastMessage = true
// We need to show all the menu items here by invalidating the options to recreate the entire menu.
activity?.invalidateOptionsMenu()
queryChatRoomsByName(null)
return true
}
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
viewModel.showLastMessage = false
sortView?.isVisible = false
// We need to hide the all the menu items here.
menu.findItem(R.id.action_new_channel).isVisible = false
return true
}
}
searchItem?.setOnActionExpandListener(expandListener)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
// TODO - simplify this
R.id.action_sort -> {
val dialogLayout = layoutInflater.inflate(R.layout.chatroom_sort_dialog, null)
val sortType = SharedPreferenceHelper.getInt(
Constants.CHATROOM_SORT_TYPE_KEY,
ChatRoomsSortOrder.ACTIVITY
)
val groupByType =
SharedPreferenceHelper.getBoolean(Constants.CHATROOM_GROUP_BY_TYPE_KEY, false)
val radioGroup = dialogLayout.findViewById<RadioGroup>(R.id.radio_group_sort)
val groupByTypeCheckBox =
dialogLayout.findViewById<CheckBox>(R.id.checkbox_group_by_type)
radioGroup.check(
when (sortType) {
0 -> R.id.radio_sort_alphabetical
else -> R.id.radio_sort_activity
}
)
radioGroup.setOnCheckedChangeListener { _, checkedId ->
run {
SharedPreferenceHelper.putInt(
Constants.CHATROOM_SORT_TYPE_KEY, when (checkedId) {
R.id.radio_sort_alphabetical -> 0
R.id.radio_sort_activity -> 1
else -> 1
}
)
}
}
groupByTypeCheckBox.isChecked = groupByType
groupByTypeCheckBox.setOnCheckedChangeListener { _, isChecked ->
SharedPreferenceHelper.putBoolean(
Constants.CHATROOM_GROUP_BY_TYPE_KEY,
isChecked
)
}
context?.let {
AlertDialog.Builder(it)
.setTitle(R.string.dialog_sort_title)
.setView(dialogLayout)
.setPositiveButton(R.string.msg_sort) { dialog, _ ->
invalidateQueryOnSearch()
updateSort()
dialog.dismiss()
}.show()
}
}
}
return super.onOptionsItemSelected(item)
})
}
private fun updateSort() {
......@@ -269,16 +204,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
viewModel.setQuery(query)
}
private fun invalidateQueryOnSearch() {
searchView?.let {
if (!searchView!!.isIconified) {
queryChatRoomsByName(searchView!!.query.toString())
}
}
}
private fun showNoChatRoomsToDisplay() {
ui { text_no_data_to_display.isVisible = true }
// ui { text_no_data_to_display.isVisible = true }
}
override fun showLoading() {
......@@ -315,42 +242,68 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
private fun showConnectionState(state: State) {
Timber.d("Got new state: $state")
ui {
text_connection_status.fadeIn()
handler.removeCallbacks(dismissStatus)
text_connection_status.text = when (state) {
is State.Connected -> {
handler.postDelayed(dismissStatus, 2000)
getString(R.string.status_connected)
// ui {
// text_connection_status.fadeIn()
// handler.removeCallbacks(dismissStatus)
// text_connection_status.text = when (state) {
// is State.Connected -> {
// handler.postDelayed(dismissStatus, 2000)
// getString(R.string.status_connected)
// }
// is State.Disconnected -> getString(R.string.status_disconnected)
// is State.Connecting -> getString(R.string.status_connecting)
// is State.Authenticating -> getString(R.string.status_authenticating)
// is State.Disconnecting -> getString(R.string.status_disconnecting)
// is State.Waiting -> getString(R.string.status_waiting, state.seconds)
// else -> {
// handler.postDelayed(dismissStatus, 500)
// ""
// }
// }
// }
}
is State.Disconnected -> getString(R.string.status_disconnected)
is State.Connecting -> getString(R.string.status_connecting)
is State.Authenticating -> getString(R.string.status_authenticating)
is State.Disconnecting -> getString(R.string.status_disconnecting)
is State.Waiting -> getString(R.string.status_waiting, state.seconds)
else -> {
handler.postDelayed(dismissStatus, 500)
""
private val dismissStatus = {
// if (text_connection_status != null) {
// text_connection_status.fadeOut()
// }
}
private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_chats)
}
private fun setupListeners() {
text_sort_by.setOnClickListener {
SortByBottomSheetFragment()
.show(activity?.supportFragmentManager, TAG)
}
}
private val dismissStatus = {
if (text_connection_status != null) {
text_connection_status.fadeOut()
fun sortChatRoomsList(
isSortByName: Boolean,
isUnreadOnTop: Boolean,
isGroupByType: Boolean,
isGroupByFavorites: Boolean
) {
if (isSortByName) {
viewModel.setQuery(Query.ByName(isGroupByType))
changeSortByTitle(getString(R.string.msg_sort_by_name))
} else {
viewModel.setQuery(Query.ByActivity(isGroupByType))
changeSortByTitle(getString(R.string.msg_sort_by_activity))
}
}
private fun setupToolbar() {
(activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_chats)
private fun changeSortByTitle(text: String) {
text_sort_by.text = getString(R.string.msg_sort_by, text.toLowerCase())
}
private fun queryChatRoomsByName(name: String?): Boolean {
if (name.isNullOrEmpty()) {
updateSort()
} else {
viewModel.setQuery(Query.Search(name!!))
viewModel.setQuery(Query.Search(name))
}
return true
}
......
package chat.rocket.android.chatrooms.ui
import DrawableHelper
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.DrawableRes
import chat.rocket.android.R
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.bottom_sheet_fragment_sort_by.*
internal const val TAG = "SortByBottomSheetFragment"
class SortByBottomSheetFragment : BottomSheetDialogFragment() {
private var isSortByName = false
private var isUnreadOnTop = false
private var isGroupByType = false
private var isGroupByFavorites = false
private val chatRoomFragment by lazy {
activity?.supportFragmentManager?.findFragmentByTag(TAG_CHAT_ROOMS_FRAGMENT) as ChatRoomsFragment
}
private val filterDrawable by lazy { R.drawable.ic_filter_20dp }
private val activityDrawable by lazy { R.drawable.ic_activity_20dp }
private val unreadOnTopDrawable by lazy { R.drawable.ic_unread_20dp }
private val groupByTypeDrawable by lazy { R.drawable.ic_group_by_type_20dp }
private val groupByFavoritesDrawable by lazy { R.drawable.ic_favorites_20dp }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
inflater.inflate(R.layout.bottom_sheet_fragment_sort_by, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
}
private fun setupListeners() {
text_name.setOnClickListener {
changeSortByTitle(getString(R.string.msg_sort_by_name))
checkSelection(text_name, filterDrawable)
uncheckSelection(text_activity, activityDrawable)
isSortByName = true
sortChatRoomsList()
}
text_activity.setOnClickListener {
changeSortByTitle(getString(R.string.msg_sort_by_activity))
checkSelection(text_activity, activityDrawable)
uncheckSelection(text_name, filterDrawable)
isSortByName = false
sortChatRoomsList()
}
text_unread_on_top.setOnClickListener {
isUnreadOnTop = if (isUnreadOnTop) {
uncheckSelection(text_unread_on_top, unreadOnTopDrawable)
false
} else {
checkSelection(text_unread_on_top, unreadOnTopDrawable)
true
}
sortChatRoomsList()
}
text_group_by_type.setOnClickListener {
isGroupByType = if (isGroupByType) {
uncheckSelection(text_group_by_type, groupByTypeDrawable)
false
} else {
checkSelection(text_group_by_type, groupByTypeDrawable)
true
}
sortChatRoomsList()
}
text_group_by_favorites.setOnClickListener {
isGroupByFavorites = if (isGroupByFavorites) {
uncheckSelection(text_group_by_favorites, groupByFavoritesDrawable)
false
} else {
checkSelection(text_group_by_favorites, groupByFavoritesDrawable)
true
}
sortChatRoomsList()
}
}
private fun changeSortByTitle(text: String) {
text_sort_by.text = getString(R.string.msg_sort_by, text.toLowerCase())
}
private fun checkSelection(textView: TextView, @DrawableRes leftDrawable: Int) {
context?.let {
DrawableHelper.compoundLeftAndRightDrawable(
textView,
DrawableHelper.getDrawableFromId(leftDrawable, it),
DrawableHelper.getDrawableFromId(R.drawable.ic_check, it)
)
}
}
private fun uncheckSelection(textView: TextView, @DrawableRes leftDrawable: Int) {
context?.let {
DrawableHelper.compoundLeftDrawable(
textView,
DrawableHelper.getDrawableFromId(leftDrawable, it)
)
}
}
private fun sortChatRoomsList() {
chatRoomFragment.sortChatRoomsList(
isSortByName,
isUnreadOnTop,
isGroupByType,
isGroupByFavorites
)
}
}
\ No newline at end of file
......@@ -167,13 +167,16 @@ class CreateChannelFragment : Fragment(), CreateChannelView, ActionMode.Callback
override fun prepareToShowChatList() {
with(activity as MainActivity) {
setCheckedNavDrawerItem(R.id.menu_action_chats)
openDrawer()
getDrawerLayout().postDelayed(1000) {
closeDrawer()
createChannelPresenter.toChatList()
}
// setCheckedNavDrawerItem(R.id.menu_action_chats)
// openDrawer()
// getDrawerLayout().postDelayed(1000) {
// closeDrawer()
// createChannelPresenter.toChatList()
// }
}
}
override fun showChannelCreatedSuccessfullyMessage() {
......
package chat.rocket.android.main.presentation
import android.content.Context
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.emoji.Emoji
import chat.rocket.android.emoji.EmojiRepository
import chat.rocket.android.emoji.Fitzpatrick
import chat.rocket.android.emoji.internal.EmojiCategory
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.main.uimodel.NavHeaderUiModel
import chat.rocket.android.main.uimodel.NavHeaderUiModelMapper
import chat.rocket.android.push.GroupedPush
import chat.rocket.android.server.domain.GetAccountsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.domain.PublicSettings
import chat.rocket.android.server.domain.RefreshSettingsInteractor
import chat.rocket.android.server.domain.RefreshPermissionsInteractor
import chat.rocket.android.server.domain.RefreshSettingsInteractor
import chat.rocket.android.server.domain.RemoveAccountInteractor
import chat.rocket.android.server.domain.SaveAccountInteractor
import chat.rocket.android.server.domain.TokenRepository
import chat.rocket.android.server.domain.favicon
import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.server.presentation.CheckServerPresenter
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.adminPanelUrl
import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.android.util.retryIO
import chat.rocket.common.RocketChatAuthException
import chat.rocket.common.RocketChatException
import chat.rocket.common.model.UserStatus
import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.getCustomEmojis
import chat.rocket.core.internal.rest.me
import chat.rocket.core.model.Myself
import kotlinx.coroutines.channels.Channel
import timber.log.Timber
import javax.inject.Inject
class MainPresenter @Inject constructor(
private val view: MainView,
private val strategy: CancelStrategy,
private val navigator: MainNavigator,
private val tokenRepository: TokenRepository,
private val mainView: MainView,
private val cancelStrategy: CancelStrategy,
private val mainNavigator: MainNavigator,
val getCurrentServerInteractor: GetCurrentServerInteractor,
private val groupedPush: GroupedPush,
private val getAccountsInteractor: GetAccountsInteractor,
rocketChatClientFactory: RocketChatClientFactory,
localRepository: LocalRepository,
removeAccountInteractor: RemoveAccountInteractor,
tokenRepository: TokenRepository,
private val connectionManagerFactory: ConnectionManagerFactory,
databaseManagerFactory: DatabaseManagerFactory,
private val refreshSettingsInteractor: RefreshSettingsInteractor,
private val refreshPermissionsInteractor: RefreshPermissionsInteractor,
private val refreshPermissionsInteractor: RefreshPermissionsInteractor
/*
private val navHeaderMapper: NavHeaderUiModelMapper,
private val saveAccountInteractor: SaveAccountInteractor,
private val getAccountsInteractor: GetAccountsInteractor,
private val groupedPush: GroupedPush,
serverInteractor: GetCurrentServerInteractor,
localRepository: LocalRepository,
removeAccountInteractor: RemoveAccountInteractor,
factory: RocketChatClientFactory,
dbManagerFactory: DatabaseManagerFactory,
getSettingsInteractor: GetSettingsInteractor,
managerFactory: ConnectionManagerFactory
*/
) : CheckServerPresenter(
strategy = strategy,
factory = factory,
serverInteractor = serverInteractor,
strategy = cancelStrategy,
factory = rocketChatClientFactory,
serverInteractor = getCurrentServerInteractor,
localRepository = localRepository,
removeAccountInteractor = removeAccountInteractor,
tokenRepository = tokenRepository,
managerFactory = managerFactory,
dbManagerFactory = dbManagerFactory,
tokenView = view,
navigator = navigator
managerFactory = connectionManagerFactory,
dbManagerFactory = databaseManagerFactory,
tokenView = mainView,
navigator = mainNavigator
) {
private val currentServer = serverInteractor.get()!!
private val manager = managerFactory.create(currentServer)
private val client: RocketChatClient = factory.create(currentServer)
private var settings: PublicSettings = getSettingsInteractor.get(serverInteractor.get()!!)
private val userDataChannel = Channel<Myself>()
fun toChatList(chatRoomId: String? = null) = navigator.toChatList(chatRoomId)
fun toUserProfile() = navigator.toUserProfile()
fun toSettings() = navigator.toSettings()
fun toAdminPanel() = tokenRepository.get(currentServer)?.let {
navigator.toAdminPanel(currentServer.adminPanelUrl(), it.authToken)
}
fun toCreateChannel() = navigator.toCreateChannel()
fun loadServerAccounts() {
launchUI(strategy) {
try {
view.setupServerAccountList(getAccountsInteractor.get())
} catch (ex: Exception) {
when (ex) {
is RocketChatAuthException -> logout()
else -> {
Timber.d(ex, "Error loading serve accounts")
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
}
}
}
fun loadCurrentInfo() {
setupConnectionInfo(currentServer)
checkServerInfo(currentServer)
launchUI(strategy) {
try {
val me = retryIO("me") { client.me() }
val model = navHeaderMapper.mapToUiModel(me)
saveAccount(model)
view.setupUserAccountInfo(model)
} catch (ex: Exception) {
when (ex) {
is RocketChatAuthException -> logout()
else -> {
Timber.d(ex, "Error loading my information for navheader")
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
}
subscribeMyselfUpdates()
}
}
/**
* Load all emojis for the current server. Simple emojis are always the same for every server,
* but custom emojis vary according to the its url.
*/
fun loadEmojis() {
launchUI(strategy) {
EmojiRepository.setCurrentServerUrl(currentServer)
val customEmojiList = mutableListOf<Emoji>()
try {
for (customEmoji in retryIO("getCustomEmojis()") { client.getCustomEmojis() }) {
customEmojiList.add(Emoji(
shortname = ":${customEmoji.name}:",
category = EmojiCategory.CUSTOM.name,
url = "$currentServer/emoji-custom/${customEmoji.name}.${customEmoji.extension}",
count = 0,
fitzpatrick = Fitzpatrick.Default.type,
keywords = customEmoji.aliases,
shortnameAlternates = customEmoji.aliases,
siblings = mutableListOf(),
unicode = "",
isDefault = true
))
}
fun clearNotificationsForChatRoom(chatRoomId: String?) {
if (chatRoomId == null) return
EmojiRepository.load(view as Context, customEmojis = customEmojiList)
} catch (ex: RocketChatException) {
Timber.e(ex)
EmojiRepository.load(view as Context)
}
getCurrentServerInteractor.get()?.let { currentServer ->
groupedPush.hostToPushMessageList[currentServer].let { list ->
list?.removeAll { it.info.roomId == chatRoomId }
}
}
fun logout() {
setupConnectionInfo(currentServer)
super.logout(userDataChannel)
}
fun connect() {
getCurrentServerInteractor.get()?.let { currentServer ->
refreshSettingsInteractor.refreshAsync(currentServer)
refreshPermissionsInteractor.refreshAsync(currentServer)
manager.connect()
connectionManagerFactory.create(currentServer).connect()
}
fun disconnect() {
setupConnectionInfo(currentServer)
super.disconnect(userDataChannel)
}
fun changeServer(serverUrl: String) {
if (currentServer != serverUrl) {
navigator.switchOrAddNewServer(serverUrl)
} else {
view.closeServerSelection()
}
fun getCurrentServerName() {
getCurrentServerInteractor.get()?.let { currentServer ->
mainView.setupToolbar(currentServer)
}
fun addNewServer() {
navigator.toServerScreen()
}
fun changeDefaultStatus(userStatus: UserStatus) {
launchUI(strategy) {
fun getAllServers() {
launchUI(cancelStrategy) {
try {
manager.setDefaultStatus(userStatus)
view.showUserStatus(userStatus)
} catch (ex: RocketChatException) {
ex.message?.let {
view.showMessage(it)
mainView.setupServerListView(getAccountsInteractor.get())
} catch (exception: Exception) {
Timber.e(exception, "Error while getting all servers")
when (exception) {
is RocketChatAuthException -> logout()
else -> {
exception.message?.let {
mainView.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
mainView.showGenericErrorMessage()
}
}
}
private fun saveAccount(uiModel: NavHeaderUiModel) {
val icon = settings.favicon()?.let {
currentServer.serverLogoUrl(it)
}
val account = Account(
currentServer,
icon,
uiModel.serverLogo,
uiModel.userDisplayName!!,
uiModel.userAvatar
)
saveAccountInteractor.save(account)
}
private suspend fun subscribeMyselfUpdates() {
manager.addUserDataChannel(userDataChannel)
for (myself in userDataChannel) {
updateMyself(myself)
}
}
private fun updateMyself(myself: Myself) =
view.setupUserAccountInfo(navHeaderMapper.mapToUiModel(myself))
fun showChatList(chatRoomId: String? = null) = mainNavigator.toChatList(chatRoomId)
fun clearNotificationsForChatroom(chatRoomId: String?) {
if (chatRoomId == null) return
fun showSettings() = mainNavigator.toSettings()
groupedPush.hostToPushMessageList[currentServer]?.let { list ->
list.removeAll { it.info.roomId == chatRoomId }
fun logout() {
getCurrentServerInteractor.get()?.let { currentServer ->
setupConnectionInfo(currentServer)
}
}
}
package chat.rocket.android.main.presentation
import chat.rocket.android.authentication.server.presentation.VersionCheckView
import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.main.uimodel.NavHeaderUiModel
import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.presentation.TokenView
import chat.rocket.common.model.UserStatus
interface MainView : MessageView, VersionCheckView, TokenView {
interface MainView : TokenView, MessageView {
/**
* Shows the current user status.
* Setups the toolbar with the current logged in server name.
*
* @see [UserStatus]
* @param serverName The current logged in server name to show on Toolbar.
*/
fun showUserStatus(userStatus: UserStatus)
fun setupToolbar(serverName: String)
/**
* Setups the user account info (displayed in the nav. header)
* Setups the server list view with all server list.
*
* @param uiModel The [NavHeaderUiModel].
* @param serverList The server list to show on server list.
*/
fun setupUserAccountInfo(uiModel: NavHeaderUiModel)
/**
* Setups the server account list.
*
* @param serverAccountList The list of server accounts.
*/
fun setupServerAccountList(serverAccountList: List<Account>)
fun closeServerSelection()
fun showProgress()
fun hideProgress()
fun setupServerListView(serverList: List<Account>)
}
\ No newline at end of file
package chat.rocket.android.main.ui
import DrawableHelper
import android.app.Activity
import androidx.appcompat.app.AlertDialog
import android.app.ProgressDialog
import android.app.NotificationManager
import android.content.Context
import android.os.Bundle
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import chat.rocket.android.BuildConfig
import chat.rocket.android.R
import chat.rocket.android.chatrooms.ui.ChatRoomsFragment
import chat.rocket.android.main.adapter.AccountsAdapter
import chat.rocket.android.main.adapter.Selector
import chat.rocket.android.main.presentation.MainPresenter
import chat.rocket.android.main.presentation.MainView
import chat.rocket.android.main.uimodel.NavHeaderUiModel
import chat.rocket.android.push.refreshPushToken
import chat.rocket.android.server.domain.PermissionsInteractor
import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.server.ui.INTENT_CHAT_ROOM_ID
import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.invalidateFirebaseToken
import chat.rocket.common.model.UserStatus
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasActivityInjector
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.nav_header.view.*
import kotlinx.android.synthetic.main.app_bar_main.*
import javax.inject.Inject
import android.app.NotificationManager
import android.content.Context
private const val CURRENT_STATE = "current_state"
class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
HasSupportFragmentInjector {
@Inject
lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
lateinit var fagmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var presenter: MainPresenter
@Inject
lateinit var permissions: PermissionsInteractor
private var isFragmentAdded: Boolean = false
private var expanded = false
private val headerLayout by lazy { view_navigation.getHeaderView(0) }
private var chatRoomId: String? = null
private var progressDialog: ProgressDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
......@@ -67,158 +39,36 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
refreshPushToken()
chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
presenter.clearNotificationsForChatroom(chatRoomId)
presenter.connect()
presenter.loadServerAccounts()
presenter.loadCurrentInfo()
presenter.loadEmojis()
setupToolbar()
setupNavigationView()
}
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
outState?.putBoolean(CURRENT_STATE, isFragmentAdded)
with(presenter) {
clearNotificationsForChatRoom(chatRoomId)
connect()
getCurrentServerName()
getAllServers()
showChatList(chatRoomId)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
isFragmentAdded = savedInstanceState?.getBoolean(CURRENT_STATE) ?: false
setupListeners()
}
override fun onResume() {
super.onResume()
if (!isFragmentAdded) {
presenter.toChatList(chatRoomId)
isFragmentAdded = true
}
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
notificationManager.cancelAll()
clearAppNotifications()
}
override fun onDestroy() {
super.onDestroy()
if (isFinishing) {
presenter.disconnect()
}
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
closeDrawer()
} else {
supportFragmentManager.findFragmentById(R.id.fragment_container)?.let {
if (it !is ChatRoomsFragment && supportFragmentManager.backStackEntryCount == 0) {
presenter.toChatList(chatRoomId)
setCheckedNavDrawerItem(R.id.menu_action_chats)
} else {
super.onBackPressed()
}
}
}
}
override fun activityInjector(): AndroidInjector<Activity> = activityDispatchingAndroidInjector
override fun activityInjector(): AndroidInjector<Activity> =
activityDispatchingAndroidInjector
override fun supportFragmentInjector(): AndroidInjector<Fragment> =
fragmentDispatchingAndroidInjector
override fun showUserStatus(userStatus: UserStatus) {
headerLayout.apply {
image_user_status.setImageDrawable(
DrawableHelper.getUserStatusDrawable(userStatus, this.context)
)
}
}
override fun setupUserAccountInfo(uiModel: NavHeaderUiModel) {
with(headerLayout) {
with(uiModel) {
if (userStatus != null) {
image_user_status.setImageDrawable(
DrawableHelper.getUserStatusDrawable(userStatus, context)
)
}
if (userDisplayName != null) {
text_user_name.text = userDisplayName
}
if (userAvatar != null) {
setAvatar(userAvatar)
}
if (serverLogo != null) {
server_logo.setImageURI(serverLogo)
}
text_server_url.text = uiModel.serverUrl
}
}
}
override fun setupServerAccountList(serverAccountList: List<Account>) {
accounts_list.layoutManager = LinearLayoutManager(this)
accounts_list.adapter = AccountsAdapter(serverAccountList, object : Selector {
override fun onStatusSelected(userStatus: UserStatus) {
presenter.changeDefaultStatus(userStatus)
}
override fun onAccountSelected(serverUrl: String) {
presenter.changeServer(serverUrl)
}
override fun onAddedAccountSelected() {
presenter.addNewServer()
}
})
headerLayout.account_container.setOnClickListener {
it.image_account_expand.rotateBy(180f)
if (expanded) {
accounts_list.fadeOut()
} else {
accounts_list.fadeIn()
}
expanded = !expanded
}
fagmentDispatchingAndroidInjector
headerLayout.image_avatar.setOnClickListener {
view_navigation.menu.findItem(R.id.menu_action_profile).isChecked = true
presenter.toUserProfile()
drawer_layout.closeDrawer(GravityCompat.START)
}
}
override fun closeServerSelection() {
view_navigation.getHeaderView(0).account_container.performClick()
}
override fun alertNotRecommendedVersion() {
AlertDialog.Builder(this)
.setMessage(
getString(
R.string.msg_ver_not_recommended,
BuildConfig.RECOMMENDED_SERVER_VERSION
)
)
.setPositiveButton(android.R.string.ok, null)
.create()
.show()
override fun setupToolbar(serverName: String) {
setSupportActionBar(toolbar)
text_server_name.text = serverName
}
override fun blockAndAlertNotRequiredVersion() {
AlertDialog.Builder(this)
.setMessage(
getString(
R.string.msg_ver_not_minimum,
BuildConfig.REQUIRED_SERVER_VERSION
)
)
.setOnDismissListener { presenter.logout() }
.setPositiveButton(android.R.string.ok, null)
.create()
.show()
override fun setupServerListView(serverList: List<Account>) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun invalidateToken(token: String) = invalidateFirebaseToken(token)
......@@ -229,54 +79,13 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
private fun setupToolbar() {
setSupportActionBar(toolbar)
}
fun setupNavigationView() {
with (view_navigation.menu) {
clear()
setupMenu(this)
}
view_navigation.setNavigationItemSelectedListener {
it.isChecked = true
closeDrawer()
onNavDrawerItemSelected(it)
true
}
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp)
toolbar.setNavigationOnClickListener { openDrawer() }
}
private fun clearAppNotifications() =
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager).cancelAll()
fun showLogoutDialog() {
val builder = AlertDialog.Builder(this)
builder.setTitle(R.string.title_are_you_sure)
.setPositiveButton(R.string.action_logout) { _, _ -> presenter.logout()}
.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.cancel() }
.create()
.show()
private fun setupListeners() {
text_server_name.setOnClickListener {
// SortByBottomSheetFragment().show(supportFragmentManager, TAG)
}
fun setAvatar(avatarUrl: String) {
headerLayout.image_avatar.setImageURI(avatarUrl)
}
fun getDrawerLayout(): DrawerLayout = drawer_layout
fun openDrawer() = drawer_layout.openDrawer(GravityCompat.START)
fun closeDrawer() = drawer_layout.closeDrawer(GravityCompat.START)
fun setCheckedNavDrawerItem(@IdRes item: Int) = view_navigation.setCheckedItem(item)
override fun showProgress() {
progressDialog = ProgressDialog.show(this, getString(R.string.app_name), getString(R.string.msg_log_out), true, false)
}
override fun hideProgress() {
progressDialog?.dismiss()
progressDialog = null
}
}
package chat.rocket.android.main.ui
import android.view.Menu
import android.view.MenuItem
import chat.rocket.android.R
internal fun MainActivity.setupMenu(menu: Menu) {
with(menu) {
add(
R.id.menu_section_one,
R.id.menu_action_chats,
Menu.NONE,
R.string.title_chats
).setIcon(R.drawable.ic_chat_bubble_black_24dp)
.isChecked = true
add(
R.id.menu_section_one,
R.id.menu_action_create_channel,
Menu.NONE,
R.string.action_create_channel
).setIcon(R.drawable.ic_create_black_24dp)
add(
R.id.menu_section_two,
R.id.menu_action_profile,
Menu.NONE,
R.string.title_profile
).setIcon(R.drawable.ic_person_black_20dp)
add(
R.id.menu_section_two,
R.id.menu_action_settings,
Menu.NONE,
R.string.title_settings
).setIcon(R.drawable.ic_settings_black_24dp)
if (permissions.canSeeTheAdminPanel()) {
add(
R.id.menu_section_two,
R.id.menu_action_admin_panel,
Menu.NONE,
R.string.title_admin_panel
).setIcon(R.drawable.ic_settings_black_24dp)
}
add(
R.id.menu_section_three,
R.id.menu_action_logout,
Menu.NONE,
R.string.action_logout
).setIcon(R.drawable.ic_logout_black_24dp)
setGroupCheckable(R.id.menu_section_one, true, true)
setGroupCheckable(R.id.menu_section_two, true, true)
setGroupCheckable(R.id.menu_section_three, true, true)
}
}
internal fun MainActivity.onNavDrawerItemSelected(menuItem: MenuItem) {
when (menuItem.itemId) {
R.id.menu_action_chats-> presenter.toChatList()
R.id.menu_action_create_channel -> presenter.toCreateChannel()
R.id.menu_action_profile -> presenter.toUserProfile()
R.id.menu_action_settings -> presenter.toSettings()
R.id.menu_action_admin_panel -> presenter.toAdminPanel()
R.id.menu_action_logout -> showLogoutDialog()
}
}
package chat.rocket.android.main.uimodel
import chat.rocket.common.model.UserStatus
data class NavHeaderUiModel(
val userDisplayName: String?,
val userStatus: UserStatus?,
val userAvatar: String?,
val serverUrl: String,
val serverLogo: String?
)
\ No newline at end of file
package chat.rocket.android.main.uimodel
import chat.rocket.android.server.domain.*
import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.extensions.serverLogoUrl
import chat.rocket.core.model.Myself
import javax.inject.Inject
class NavHeaderUiModelMapper @Inject constructor(
serverInteractor: GetCurrentServerInteractor,
getSettingsInteractor: GetSettingsInteractor
) {
private val currentServer = serverInteractor.get()!!
private var settings: PublicSettings = getSettingsInteractor.get(currentServer)
fun mapToUiModel(me: Myself): NavHeaderUiModel {
val displayName = mapDisplayName(me)
val status = me.status
val avatar = me.username?.let { currentServer.avatarUrl(it) }
val image = settings.wideTile() ?: settings.faviconLarge()
val logo = image?.let { currentServer.serverLogoUrl(it) }
return NavHeaderUiModel(displayName, status, avatar, currentServer, logo)
}
private fun mapDisplayName(me: Myself): String? {
val username = me.username
val realName = me.name
val senderName = if (settings.useRealName()) realName else username
return senderName ?: username
}
}
\ No newline at end of file
......@@ -142,7 +142,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
override fun reloadUserAvatar(avatarUrl: String) {
Fresco.getImagePipeline().evictFromCache(avatarUrl.toUri())
image_avatar.setImageURI(avatarUrl)
(activity as MainActivity).setAvatar(avatarUrl)
// (activity as MainActivity).setAvatar(avatarUrl)
}
override fun showProfileUpdateSuccessfullyMessage() {
......
......@@ -55,12 +55,6 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
analyticsManager.logScreenView(ScreenViewEvent.Settings)
}
override fun onResume() {
// FIXME - gambiarra ahead. will fix when moving to new androidx Navigation
(activity as? MainActivity)?.setupNavigationView()
super.onResume()
}
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (parent?.getItemAtPosition(position).toString()) {
resources.getStringArray(R.array.settings_actions)[0] -> {
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M10,10m-9.25,0a9.25,9.25 0,1 1,18.5 0a9.25,9.25 0,1 1,-18.5 0"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M10,4.004V10l4,4"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="4dp"
android:viewportWidth="8"
android:viewportHeight="4">
<path
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:pathData="M1.20711,0L6.79289,0C7.06904,0 7.29289,0.22386 7.29289,0.5C7.29289,0.63261 7.24021,0.75979 7.14645,0.85355L4.35355,3.64645C4.15829,3.84171 3.84171,3.84171 3.64645,3.64645L0.85355,0.85355C0.65829,0.65829 0.65829,0.34171 0.85355,0.14645C0.94732,0.05268 1.0745,0 1.20711,0Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="12dp"
android:viewportWidth="17"
android:viewportHeight="12">
<path
android:fillColor="#1D74F5"
android:fillType="nonZero"
android:pathData="M5.5875,9.7331L14.7078,0.6128C15.0463,0.2744 15.595,0.2744 15.9335,0.6128L15.9335,0.6128C16.2719,0.9513 16.2719,1.5 15.9335,1.8385L6.2225,11.5494C5.832,11.9399 5.1989,11.9399 4.8083,11.5494L0.6489,7.39C0.2905,7.0316 0.2905,6.4506 0.6489,6.0922L0.6489,6.0922C1.0072,5.7338 1.5883,5.7338 1.9466,6.0922L5.5875,9.7331Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
......@@ -2,8 +2,9 @@
android:width="24dp"
android:height="24dp"
android:tint="#1D74F5"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF1D74F5"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="19">
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M14.882,16.72l-0.933,-5.437 3.95,-3.85 -5.458,-0.793L10,1.695 7.56,6.64 2.1,7.434l3.95,3.85 -0.933,5.435L10,14.153l4.882,2.566z"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M5,4L5,18"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8"
android:strokeLineCap="round" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M2,16L5,19"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8"
android:strokeLineCap="round" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M8,16L5,19"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8"
android:strokeLineCap="round" />
<path
android:fillColor="#9EA2A8"
android:fillType="evenOdd"
android:pathData="M17.4434,7.0605L16.3545,3.8916L15.1973,7.0605L17.4434,7.0605ZM15.8467,2.8271L16.9453,2.8271L19.5479,10L18.4834,10L17.7559,7.8516L14.9189,7.8516L14.1426,10L13.1465,10L15.8467,2.8271Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
<path
android:fillColor="#9EA2A8"
android:fillType="evenOdd"
android:pathData="M13.2295,19.1943l4.3994,-5.5127l-4.0771,0l0,-0.8545l5.3271,0l0,0.835l-4.4238,5.4834l4.4238,0l0,0.8545l-5.6494,0z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M5,4v14M12,5h10.88M12,10h8.88M12,15h5.88M2,16l3,3M8,16l-3,3"
android:strokeWidth="1.5"
android:strokeColor="#9EA2A8"
android:strokeLineCap="round" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M12.0455,10.4052C12.5308,8.6894 14.1082,7.4323 15.9794,7.4323C17.8505,7.4323 19.428,8.6894 19.9132,10.4052L22.04,10.4052C22.5923,10.4052 23.04,10.8529 23.04,11.4052L23.04,11.6348C23.04,12.1871 22.5923,12.6348 22.04,12.6348L19.9132,12.6348C19.428,14.3506 17.8505,15.6077 15.9794,15.6077C14.1082,15.6077 12.5308,14.3506 12.0455,12.6348L1,12.6348C0.4477,12.6348 0,12.1871 0,11.6348L0,11.4052C0,10.8529 0.4477,10.4052 1,10.4052L12.0455,10.4052ZM15.9794,13.3781C17.0055,13.3781 17.8374,12.5462 17.8374,11.52C17.8374,10.4938 17.0055,9.6619 15.9794,9.6619C14.9532,9.6619 14.1213,10.4938 14.1213,11.52C14.1213,12.5462 14.9532,13.3781 15.9794,13.3781ZM8.5471,14.8645C10.4182,14.8645 11.9957,16.1217 12.481,17.8374L22.04,17.8374C22.5923,17.8374 23.04,18.2851 23.04,18.8374L23.04,19.0671C23.04,19.6194 22.5923,20.0671 22.04,20.0671L12.481,20.0671C11.9957,21.7828 10.4182,23.04 8.5471,23.04C6.676,23.04 5.0985,21.7828 4.6132,20.0671L1,20.0671C0.4477,20.0671 0,19.6194 0,19.0671L0,18.8374C-0,18.2851 0.4477,17.8374 1,17.8374L4.6132,17.8374C5.0985,16.1217 6.676,14.8645 8.5471,14.8645ZM8.5471,20.8103C9.5733,20.8103 10.4052,19.9784 10.4052,18.9523C10.4052,17.9261 9.5733,17.0942 8.5471,17.0942C7.5209,17.0942 6.689,17.9261 6.689,18.9523C6.689,19.9784 7.5209,20.8103 8.5471,20.8103ZM7.0606,0C8.9318,0 10.5092,1.2572 10.9945,2.9729L22.04,2.9729C22.5923,2.9729 23.04,3.4206 23.04,3.9729L23.04,4.2026C23.04,4.7549 22.5923,5.2026 22.04,5.2026L10.9945,5.2026C10.5092,6.9183 8.9318,8.1755 7.0606,8.1755C5.1895,8.1755 3.612,6.9183 3.1268,5.2026L1,5.2026C0.4477,5.2026 0,4.7549 0,4.2026L0,3.9729C-0,3.4206 0.4477,2.9729 1,2.9729L3.1268,2.9729C3.612,1.2572 5.1895,0 7.0606,0ZM7.0606,5.9458C8.0868,5.9458 8.9187,5.1139 8.9187,4.0877C8.9187,3.0616 8.0868,2.2297 7.0606,2.2297C6.0345,2.2297 5.2026,3.0616 5.2026,4.0877C5.2026,5.1139 6.0345,5.9458 7.0606,5.9458Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:pathData="M16.523,11.0833C16.907,11.0833 17.218,11.3942 17.218,11.7782L17.218,16.6582C17.218,17.9513 16.169,19.0002 14.876,19.0002L3.343,19.0002C2.049,19.0002 1,17.9513 1,16.6582L1,5.1263C1,3.8333 2.049,2.7843 3.343,2.7843L8.149,2.7843C8.533,2.7843 8.845,3.0953 8.845,3.4792C8.845,3.8623 8.533,4.1743 8.149,4.1743L3.343,4.1743C2.816,4.1743 2.39,4.6003 2.39,5.1263L2.39,16.6582C2.39,17.1842 2.816,17.6103 3.343,17.6103L14.876,17.6103C15.401,17.6103 15.828,17.1842 15.828,16.6582L15.828,11.7782C15.828,11.3942 16.139,11.0833 16.523,11.0833ZM18.256,2.1318C19.25,3.1248 19.247,4.7428 18.256,5.7337L9.501,14.4877L5.5647,15.6828C5.0363,15.8432 4.4778,15.5449 4.3173,15.0164C4.2598,14.8269 4.2598,14.6246 4.3174,14.4352L5.513,10.5007L14.268,1.7468C15.263,0.7518 16.876,0.7508 17.87,1.7458L18.256,2.1318ZM17.273,4.7508C17.722,4.3028 17.723,3.5638 17.273,3.1147L16.887,2.7288C16.436,2.2768 15.703,2.2768 15.251,2.7298L14.599,3.3808L16.656,5.3678L17.273,4.7508ZM8.764,13.2587L15.673,6.3507L13.616,4.3637L6.742,11.2367L5.86,14.1407L8.764,13.2587Z"
android:strokeWidth="0.1"
android:strokeColor="#FFFFFF" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M18.976,9.783C15.808,6.408 12.812,4.75 10,4.75c-2.812,0 -5.808,1.658 -8.976,5.033C4.28,13.166 7.278,14.829 10,14.829c2.722,0 5.72,-1.663 8.976,-5.046z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#9EA2A8"/>
<path
android:pathData="M7.965,11.783a2.75,2.75 0,0 0,3.915 -3.661l-3.915,3.66z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#9EA2A8"/>
<path
android:pathData="M3.025,15.047L16.105,3.14"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#9EA2A8"
android:strokeLineCap="round"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:theme="@style/AppTheme"
tools:context=".main.ui.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar" />
android:id="@+id/layout_app_bar_main"
layout="@layout/app_bar_main" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<FrameLayout
android:id="@+id/navigation_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
<com.google.android.material.navigation.NavigationView
android:id="@+id/view_navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:headerLayout="@layout/nav_header" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/accounts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/nav_header_height"
android:alpha="0"
android:background="@color/colorWhite"
android:elevation="20dp"
android:visibility="gone" />
</FrameLayout>
</androidx.drawerlayout.widget.DrawerLayout>
\ No newline at end of file
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/ic_navigation_24dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:id="@+id/text_server_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_arrow_expand_20dp"
android:drawablePadding="10dp"
android:fontFamily="sans-serif-medium"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="normal"
tools:text="Server Name" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/screen_edge_left_and_right_margins">
tools:context=".chatrooms.ui.SortByBottomSheetFragment">
<TextView
android:id="@+id/text_activity"
android:id="@+id/text_sort_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/msg_sort_by"
android:textColor="#9EA2A8"
android:textSize="17sp"
android:textStyle="normal" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="#1F000000" />
<TextView
android:id="@+id/text_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_action_message_star_24dp"
android:drawableStart="@drawable/ic_filter_20dp"
android:drawablePadding="16dp"
android:text="@string/msg_sort_by_activity" />
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/msg_sort_by_name"
android:textColor="#2F343D"
android:textSize="16sp"
android:textStyle="normal" />
<TextView
android:id="@+id/text_name"
android:id="@+id/text_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_action_message_star_24dp"
android:drawableStart="@drawable/ic_activity_20dp"
android:drawablePadding="16dp"
android:text="@string/msg_sort_by_name" />
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/msg_sort_by_activity"
android:textColor="#2F343D"
android:textSize="16sp"
android:textStyle="normal" />
<View
android:id="@+id/view_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="@color/colorDividerMessageComposer" />
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="#1F000000" />
<TextView
android:id="@+id/text_unread_on_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_action_message_star_24dp"
android:drawableStart="@drawable/ic_unread_20dp"
android:drawablePadding="16dp"
android:text="@string/msg_group_by_unread_on_top" />
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/msg_group_by_unread_on_top"
android:textColor="#2F343D"
android:textSize="16sp"
android:textStyle="normal" />
<TextView
android:id="@+id/text_group_by_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_action_message_star_24dp"
android:drawableStart="@drawable/ic_group_by_type_20dp"
android:drawablePadding="16dp"
android:text="@string/msg_group_by_type" />
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/msg_group_by_type"
android:textColor="#2F343D"
android:textSize="16sp"
android:textStyle="normal" />
<TextView
android:id="@+id/text_group_by_favorites"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_action_message_star_24dp"
android:drawableStart="@drawable/ic_favorites_20dp"
android:drawablePadding="16dp"
android:text="@string/msg_group_by_favorites" />
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:text="@string/msg_group_by_favorites"
android:textColor="#2F343D"
android:textSize="16sp"
android:textStyle="normal" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp">
<RadioGroup
android:id="@+id/radio_group_sort"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radio_sort_alphabetical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/dialog_sort_by_alphabet"
android:textSize="18sp" />
<RadioButton
android:id="@+id/radio_sort_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@string/dialog_sort_by_activity"
android:textSize="18sp" />
</RadioGroup>
<CheckBox
android:id="@+id/checkbox_group_by_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:padding="8dp"
android:text="@string/dialog_group_by_type"
android:textSize="18sp" />
<!--TODO Add checkbox for "Group favourites after sdk support"-->
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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"
tools:context=".chatrooms.ui.ChatRoomsFragment">
<TextView
android:id="@+id/text_sort_by"
android:layout_width="match_parent"
android:layout_height="42dp"
android:background="#54585E"
android:drawableEnd="@drawable/ic_group_by_type_20dp"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical"
android:paddingStart="@dimen/screen_edge_left_and_right_margins"
android:paddingEnd="@dimen/screen_edge_left_and_right_margins"
android:text="@string/msg_sort_by"
android:textColor="#CBCED1"
android:textSize="14sp"
android:textStyle="normal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_below="@+id/text_connection_status"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_sort_by" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator" />
<TextView
android:id="@+id/text_no_data_to_display"
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/msg_no_data_to_display"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/text_connection_status"
android:layout_width="match_parent"
android:layout_height="32dp"
android:alpha="0"
android:background="@color/colorPrimary"
android:elevation="4dp"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="@color/colorWhite"
android:visibility="gone"
tools:alpha="1"
tools:text="connected"
tools:visibility="visible" />
<TextView
android:id="@+id/text_no_result_found"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="56dp"
android:text="@string/msg_no_search_found"
android:textSize="20sp"
android:visibility="gone"
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" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<?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:padding="@dimen/screen_edge_left_and_right_margins">
......
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AppCompatResource">
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_new_channel"
android:icon="@drawable/ic_new_channel_24dp"
android:title="@string/action_new_channel"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_search"
......@@ -10,11 +14,4 @@
android:title="@string/action_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
<item
android:id="@+id/action_sort"
android:icon="@drawable/ic_sort"
android:title="@string/msg_sort"
app:showAsAction="ifRoom" />
</menu>
......@@ -35,6 +35,7 @@
<string name="action_use_this_username">استخدم هذا الاسم</string>
<string name="action_terms_of_service">شروط الخدمة</string>
<string name="action_privacy_policy">شروط الخدمة</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">بحث</string>
<string name="action_update">تحديث</string>
<string name="action_settings">الإعدادات</string>
......@@ -314,14 +315,13 @@
<string name="msg_no_recent_emoji">لا يوجد ايموجيز </string>
<string name="alert_title_default_skin_tone">نغمة الجلد الافتراضية</string>
<!-- Sorting and grouping-->
<string name="msg_sort">ترتيب</string>
<string name="dialog_sort_title">ترتيب حسب</string>
<string name="dialog_sort_by_alphabet">أبجدي</string>
<string name="dialog_sort_by_activity">النشاط</string>
<string name="dialog_group_by_type">تجميع حسب النوع</string>
<string name="dialog_group_favourites">تجميع المفصلات</string>
<string name="chatroom_header">العناوين</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string> <!-- TODO Translate -->
......
......@@ -37,6 +37,7 @@
<string name="action_use_this_username">Benutze den Benutzernamen</string>
<string name="action_terms_of_service">Nutzungsbedingungen</string>
<string name="action_privacy_policy">Datenschutz</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Suche</string>
<string name="action_update">Updaten</string>
<string name="action_settings">Einstellungen</string>
......@@ -315,14 +316,13 @@
<string name="msg_no_recent_emoji">Keine letzten Emojis</string>
<string name="alert_title_default_skin_tone">Standard Hautton</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Sortiere</string>
<string name="dialog_sort_title">Sortieren nach</string>
<string name="dialog_sort_by_alphabet">Alphabetisch</string>
<string name="dialog_sort_by_activity">Aktivität</string>
<string name="dialog_group_by_type">Räume nach Typ</string>
<string name="dialog_group_favourites">Räume nach Favoriten</string>
<string name="chatroom_header">Kopf</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favoriten</string>
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Usa este nombre de usuario</string>
<string name="action_terms_of_service">Términos de Servicio</string>
<string name="action_privacy_policy">Política de Privacidad</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Buscar</string>
<string name="action_update">Actualizar</string>
<string name="action_settings">Configuraciones</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">Sin emojis recientes</string>
<string name="alert_title_default_skin_tone">Tono de piel predeterminado</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Ordenar</string>
<string name="dialog_sort_title">Ordenar por</string>
<string name="dialog_sort_by_alphabet">Alfabético</string>
<string name="dialog_sort_by_activity">Actividad</string>
<string name="dialog_group_by_type">Agrupar por tipo</string>
<string name="dialog_group_favourites">Agrupar favoritos</string>
<string name="chatroom_header">Cabezazo</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">از این شناسه‌ی کاربری استفاده کنید</string>
<string name="action_terms_of_service">شرایط خدمات رسانی</string>
<string name="action_privacy_policy">سیاست حفظ جریم خصوصی</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">جست‌وجو</string>
<string name="action_update">به روزرسانی</string>
<string name="action_settings">تنظیمات</string>
......@@ -309,14 +310,13 @@
<string name="msg_no_recent_emoji">هیچ ایموجی اخیری موجود نیست</string>
<string name="alert_title_default_skin_tone">مدل پوسته‌ی پیش‌فرض</string>
<!-- Sorting and grouping-->
<string name="msg_sort">دسته بندی</string>
<string name="dialog_sort_title">دسته بندی بر اساس</string>
<string name="dialog_sort_by_alphabet">الفبا</string>
<string name="dialog_sort_by_activity">فعالیت</string>
<string name="dialog_group_by_type">گروه کردن بر اساس نوع</string>
<string name="dialog_group_favourites">گروه کردن موردعلاقه‌ها</string>
<string name="chatroom_header">سرپیام</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Utilisez ce nom d\'utilisateur</string>
<string name="action_terms_of_service">Conditions d\'utilisation</string>
<string name="action_privacy_policy">Politique de confidentialité</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Chercher</string>
<string name="action_update">Mettre à jour</string>
<string name="action_settings">Paramètres</string>
......@@ -307,14 +308,13 @@
<string name="msg_no_recent_emoji">Aucun emoji récent</string>
<string name="alert_title_default_skin_tone">Tonalité de peau par défaut</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Trier</string>
<string name="dialog_sort_title">Trier par</string>
<string name="dialog_sort_by_alphabet">Alphabétique</string>
<string name="dialog_sort_by_activity">Activité</string>
<string name="dialog_group_by_type">Grouper par type</string>
<string name="dialog_group_favourites">Grouper favoris</string>
<string name="chatroom_header">Entête</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favoris</string>
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">इस उपयोगकर्ता नाम का उपयोग करें</string>
<string name="action_terms_of_service">सेवा की शर्तें</string>
<string name="action_privacy_policy">गोपनीयता नीति</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">खोजें</string>
<string name="action_update">अद्यतन करें</string>
<string name="action_settings">सेटिंग्स</string>
......@@ -310,14 +311,13 @@
<string name="msg_no_recent_emoji"> कोई नया इमोजी नहीं</string>
<string name="alert_title_default_skin_tone">डिफ़ॉल्ट त्वचा टोन</string>
<!-- Sorting and grouping-->
<string name="msg_sort">क्रम</string>
<string name="dialog_sort_title">द्वारा सॉर्ट करें</string>
<string name="dialog_sort_by_alphabet">वर्णानुक्रम</string>
<string name="dialog_sort_by_activity">गतिविधि</string>
<string name="dialog_group_by_type">प्रकार के आधार पर समूह</string>
<string name="dialog_group_favourites">पसंदीदा समूह</string>
<string name="chatroom_header">हैडर</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">पसंदीदा</string>
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Usa questo nome utente</string>
<string name="action_terms_of_service">Termini di Servizio</string>
<string name="action_privacy_policy">Politica sulla Riservatezza</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Cerca</string>
<string name="action_update">Aggiorna</string>
<string name="action_settings">Parametri</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">No recent emojis</string>
<string name="alert_title_default_skin_tone">Default skin tone</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Ordinare</string>
<string name="dialog_sort_title">Ordinare per</string>
<string name="dialog_sort_by_alphabet">Alfabeto</string>
<string name="dialog_sort_by_activity">Attività</string>
<string name="dialog_group_by_type">Raggruppa per tipo</string>
<string name="dialog_group_favourites">Raggruppa preferiti</string>
<string name="chatroom_header">Intestazione</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">このユーザー名を使用する</string>
<string name="action_terms_of_service">サービス利用規約</string>
<string name="action_privacy_policy">プライバシーポリシー</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">検索</string>
<string name="action_update">更新</string>
<string name="action_settings">設定</string>
......@@ -309,15 +310,13 @@
<string name="msg_no_recent_emoji">最近の絵文字はありません</string>
<string name="alert_title_default_skin_tone">デフォルトスキントークン</string>
<!-- Sorting and grouping-->
<string name="msg_sort">ソート</string>
<string name="dialog_sort_title">ソート</string>
<string name="dialog_sort_by_alphabet">アルファベット順</string>
<string name="dialog_sort_by_activity">アクティビティ順</string>
<string name="dialog_group_by_type">グループ別</string>
<string name="dialog_group_favourites">お気に入りのグループ</string>
<string name="chatroom_header">ヘッダ</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Usar este nome de usuário</string>
<string name="action_terms_of_service">Termos de Serviço</string>
<string name="action_privacy_policy">Política de Privacidade</string>
<string name="action_new_channel">Novo canal</string>
<string name="action_search">Pesquisar</string>
<string name="action_update">Atualizar</string>
<string name="action_settings">Configurações</string>
......@@ -309,13 +310,13 @@
<string name="msg_no_recent_emoji">Nenhum emoji recente</string>
<string name="alert_title_default_skin_tone">Tom de pele padrão</string>
<!-- Sorting and grouping-->
<string name="dialog_sort_title">Ordenar por</string>
<string name="dialog_sort_by_alphabet">Alfabeticamente</string>
<string name="dialog_sort_by_activity">Atividade</string>
<string name="dialog_group_by_type">Agrupar por tipo</string>
<string name="dialog_group_favourites">Grupos favoritos</string>
<string name="chatroom_header">Cabeçalho</string>
<!-- Sort and group -->
<string name="msg_sort_by">Ordenar por %1$s</string>
<string name="msg_sort_by_activity">Atividade</string>
<string name="msg_sort_by_name">Nome</string>
<string name="msg_group_by_unread_on_top">Não lidas no topo</string>
<string name="msg_group_by_type">Agrupar por tipo</string>
<string name="msg_group_by_favorites">Agrupar por favoritos</string>
<!--ChatRooms Headers-->
<string name="header_favorite">Favoritos</string>
......
......@@ -35,6 +35,7 @@
<string name="action_terms_of_service">Termos do Serviço</string>
<string name="action_privacy_policy">Política de Privacidade</string>
<string name="action_search">Pesquisar</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_update">Actualizar</string>
<string name="action_settings">Definições</string>
<string name="action_create_channel">Criar canal</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">Nenhum emojis recente</string>
<string name="alert_title_default_skin_tone">Tom de pele padrão</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Ordenar</string>
<string name="dialog_sort_title">Ordenar por</string>
<string name="dialog_sort_by_alphabet">Alfabeticamente</string>
<string name="dialog_sort_by_activity">Actividade</string>
<string name="dialog_group_by_type">Agrupar por tipo</string>
<string name="dialog_group_favourites">Agrupar favoritos</string>
<string name="chatroom_header">Cabeçalho</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favoritos</string>
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Использовать это имя</string>
<string name="action_terms_of_service">Условия использования</string>
<string name="action_privacy_policy">Политика конфиденциальности</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Поиск</string>
<string name="action_update">Обновить</string>
<string name="action_settings">Настройки</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">Пусто</string>
<string name="alert_title_default_skin_tone">Тон кожи по умолчанию</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Сортировать</string>
<string name="dialog_sort_title">Сортировать по</string>
<string name="dialog_sort_by_alphabet">По алфавиту</string>
<string name="dialog_sort_by_activity">По активности</string>
<string name="dialog_group_by_type">Группировать по типу</string>
<string name="dialog_group_favourites">Группировать избранное</string>
<string name="chatroom_header">Заголовок</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Избранные</string>
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Bu kullanıcı adını kullan</string>
<string name="action_terms_of_service">Kullanım Şartları</string>
<string name="action_privacy_policy">Gizlilik Sözleşmesi</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Ara</string>
<string name="action_update">Güncelle</string>
<string name="action_settings">Ayarlar</string>
......@@ -310,14 +311,13 @@
<string name="msg_no_recent_emoji">Son kullanılan emoji bulunmamaktadır</string>
<string name="alert_title_default_skin_tone">Varsayılan tasarım tonu</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Sırala</string>
<string name="dialog_sort_title">Sırala</string>
<string name="dialog_sort_by_alphabet">Alfabetik</string>
<string name="dialog_sort_by_activity">Aktiviteye Göre</string>
<string name="dialog_group_by_type">Türüne göre grupla</string>
<string name="dialog_group_favourites">Favorileri grupla</string>
<string name="chatroom_header">Başlık</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">Використати це ім\'я</string>
<string name="action_terms_of_service">Умови використання</string>
<string name="action_privacy_policy">Політика конфіденційності</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">Пошук</string>
<string name="action_update">Оновити</string>
<string name="action_settings">Налаштування</string>
......@@ -305,14 +306,13 @@
<string name="msg_no_recent_emoji">Пусто</string>
<string name="alert_title_default_skin_tone">Тон шкіри за замовчуванням</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Сортувати</string>
<string name="dialog_sort_title">Сортувати за</string>
<string name="dialog_sort_by_alphabet">За алфавітом</string>
<string name="dialog_sort_by_activity">За активністю</string>
<string name="dialog_group_by_type">Групувати за типом</string>
<string name="dialog_group_favourites">Групувати обране</string>
<string name="chatroom_header">Заголовок</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">使用这个用户名</string>
<string name="action_terms_of_service">服务条款</string>
<string name="action_privacy_policy">隐私政策</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">搜索</string>
<string name="action_update">更新</string>
<string name="action_settings">设置</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">没有最近的emojis</string>
<string name="alert_title_default_skin_tone">默认皮肤颜色</string>
<!-- Sorting and grouping-->
<string name="msg_sort">排序</string>
<string name="dialog_sort_title">排序按</string>
<string name="dialog_sort_by_alphabet">字母</string>
<string name="dialog_sort_by_activity">活跃</string>
<string name="dialog_group_by_type">按类型分组</string>
<string name="dialog_group_favourites">收藏分组</string>
<string name="chatroom_header">头部</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -34,6 +34,7 @@
<string name="action_use_this_username">使用這個名稱</string>
<string name="action_terms_of_service">服務條款</string>
<string name="action_privacy_policy">隱私政策</string>
<string name="action_new_channel">New channel</string> <!-- TODO Translate -->
<string name="action_search">搜尋</string>
<string name="action_update">更新</string>
<string name="action_settings">設定</string>
......@@ -306,14 +307,13 @@
<string name="msg_no_recent_emoji">最近沒有使用emojis</string>
<string name="alert_title_default_skin_tone">預設主題顏色</string>
<!-- Sorting and grouping-->
<string name="msg_sort">排序</string>
<string name="dialog_sort_title">根據開頭排序</string>
<string name="dialog_sort_by_alphabet">根據字母排序</string>
<string name="dialog_sort_by_activity">根據活躍度排序</string>
<string name="dialog_group_by_type">根據類型分組</string>
<string name="dialog_group_favourites">根據蒐藏分组</string>
<string name="chatroom_header">聊天室頭貼</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string> <!-- TODO Translate -->
<string name="msg_sort_by_activity">Activity</string> <!-- TODO Translate -->
<string name="msg_sort_by_name">Name</string> <!-- TODO Translate -->
<string name="msg_group_by_unread_on_top">Unread on top</string> <!-- TODO Translate -->
<string name="msg_group_by_type">Group by type</string> <!-- TODO Translate -->
<string name="msg_group_by_favorites">Group by favorites</string> <!-- TODO Translate -->
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string><!-- TODO - Add proper translation -->
......
......@@ -46,6 +46,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="action_use_this_username">Use this username</string>
<string name="action_terms_of_service">Terms of Service</string>
<string name="action_privacy_policy">Privacy Policy</string>
<string name="action_new_channel">New channel</string>
<string name="action_search">Search</string>
<string name="action_update">Update</string>
<string name="action_settings">Settings</string>
......@@ -322,14 +323,13 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_no_recent_emoji">No recent emojis</string>
<string name="alert_title_default_skin_tone">Default skin tone</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Sort</string>
<string name="dialog_sort_title">Sort by</string>
<string name="dialog_sort_by_alphabet">Alphabetical</string>
<string name="dialog_sort_by_activity">Activity</string>
<string name="dialog_group_by_type">Group by type</string>
<string name="dialog_group_favourites">Group favourites</string>
<string name="chatroom_header">Header</string>
<!-- Sort and group -->
<string name="msg_sort_by">Sort by %1$s</string>
<string name="msg_sort_by_activity">Activity</string>
<string name="msg_sort_by_name">Name</string>
<string name="msg_group_by_unread_on_top">Unread on top</string>
<string name="msg_group_by_type">Group by type</string>
<string name="msg_group_by_favorites">Group by favorites</string>
<!--ChatRooms Headers-->
<string name="header_favorite">Favorites</string>
......
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