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

Merge branch 'develop' of github.com:RocketChat/Rocket.Chat.Android into...

Merge branch 'develop' of github.com:RocketChat/Rocket.Chat.Android into improvement/chat-list-layout
parents be7e816a 3cd06475
...@@ -93,6 +93,16 @@ ...@@ -93,6 +93,16 @@
android:name=".settings.password.ui.PasswordActivity" android:name=".settings.password.ui.PasswordActivity"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity
android:name=".userdetails.ui.UserDetailsActivity"
android:theme="@style/AppTheme"
android:windowSoftInputMode="stateAlwaysHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".chatroom.ui.ChatRoomActivity" />
</activity>
<receiver <receiver
android:name=".push.DirectReplyReceiver" android:name=".push.DirectReplyReceiver"
android:enabled="true" android:enabled="true"
......
...@@ -19,7 +19,6 @@ import dagger.android.AndroidInjector ...@@ -19,7 +19,6 @@ import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar.* import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.coroutines.experimental.Job
import javax.inject.Inject import javax.inject.Inject
class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
...@@ -27,7 +26,6 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -27,7 +26,6 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment> lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
@Inject @Inject
lateinit var presenter: AuthenticationPresenter lateinit var presenter: AuthenticationPresenter
val job = Job()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this) AndroidInjection.inject(this)
......
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.Spannable import android.text.Spannable
...@@ -10,6 +11,7 @@ import androidx.core.view.isVisible ...@@ -10,6 +11,7 @@ import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.MessageUiModel import chat.rocket.android.chatroom.uimodel.MessageUiModel
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.userdetails.ui.userDetailsIntent
import chat.rocket.core.model.isSystemMessage import chat.rocket.core.model.isSystemMessage
import com.bumptech.glide.load.resource.gif.GifDrawable import com.bumptech.glide.load.resource.gif.GifDrawable
import kotlinx.android.synthetic.main.avatar.view.* import kotlinx.android.synthetic.main.avatar.view.*
...@@ -70,9 +72,24 @@ class MessageViewHolder( ...@@ -70,9 +72,24 @@ class MessageViewHolder(
) )
read_receipt_view.isVisible = true read_receipt_view.isVisible = true
} }
val senderId = data.message.sender?.id
val subscriptionId = data.subscriptionId
text_sender.setOnClickListener {
toUserDetails(context, senderId, subscriptionId)
}
image_avatar.setOnClickListener {
toUserDetails(context, senderId, subscriptionId)
}
} }
} }
private fun toUserDetails(context: Context, userId: String?, subscriptionId: String) {
userId?.let { context.startActivity(context.userDetailsIntent(it, subscriptionId)) }
}
override fun unscheduleDrawable(who: Drawable?, what: Runnable?) { override fun unscheduleDrawable(who: Drawable?, what: Runnable?) {
with(itemView) { with(itemView) {
text_content.removeCallbacks(what) text_content.removeCallbacks(what)
......
...@@ -66,4 +66,4 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) { ...@@ -66,4 +66,4 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
activity.startActivity(activity.messageInformationIntent(messageId = messageId)) activity.startActivity(activity.messageInformationIntent(messageId = messageId))
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit) activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
} }
} }
\ No newline at end of file
...@@ -68,17 +68,17 @@ import chat.rocket.android.helper.ImageHelper ...@@ -68,17 +68,17 @@ import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extension.createImageFile
import chat.rocket.android.util.extensions.circularRevealOrUnreveal import chat.rocket.android.util.extensions.circularRevealOrUnreveal
import chat.rocket.android.util.extensions.fadeIn import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.getBitmpap
import chat.rocket.android.util.extensions.hideKeyboard import chat.rocket.android.util.extensions.hideKeyboard
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.rotateBy import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import chat.rocket.android.util.extension.createImageFile
import chat.rocket.android.util.extensions.getBitmpap
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
...@@ -86,19 +86,16 @@ import dagger.android.support.AndroidSupportInjection ...@@ -86,19 +86,16 @@ import dagger.android.support.AndroidSupportInjection
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.emoji_image_row_item.*
import kotlinx.android.synthetic.main.emoji_image_row_item.view.* import kotlinx.android.synthetic.main.emoji_image_row_item.view.*
import kotlinx.android.synthetic.main.emoji_row_item.*
import kotlinx.android.synthetic.main.emoji_row_item.view.* import kotlinx.android.synthetic.main.emoji_row_item.view.*
import kotlinx.android.synthetic.main.fragment_chat_room.* import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_composer.*
import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.message_list.*
import kotlinx.android.synthetic.main.reaction_praises_list_item.view.*
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import kotlinx.android.synthetic.main.reaction_praises_list_item.*
import kotlinx.android.synthetic.main.reaction_praises_list_item.view.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject import javax.inject.Inject
...@@ -144,7 +141,7 @@ private const val BUNDLE_CHAT_ROOM_IS_CREATOR = "chat_room_is_creator" ...@@ -144,7 +141,7 @@ private const val BUNDLE_CHAT_ROOM_IS_CREATOR = "chat_room_is_creator"
private const val BUNDLE_CHAT_ROOM_IS_FAVORITE = "chat_room_is_favorite" private const val BUNDLE_CHAT_ROOM_IS_FAVORITE = "chat_room_is_favorite"
private const val BUNDLE_CHAT_ROOM_MESSAGE = "chat_room_message" private const val BUNDLE_CHAT_ROOM_MESSAGE = "chat_room_message"
internal const val MENU_ACTION_FAVORITE_UNFAVORITE_CHAT = 1 internal const val MENU_ACTION_FAVORITE_UNFAVOURITE_CHAT = 1
internal const val MENU_ACTION_SHOW_DETAILS = 2 internal const val MENU_ACTION_SHOW_DETAILS = 2
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener, class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener,
......
...@@ -17,7 +17,7 @@ internal fun ChatRoomFragment.setupMenu(menu: Menu) { ...@@ -17,7 +17,7 @@ internal fun ChatRoomFragment.setupMenu(menu: Menu) {
internal fun ChatRoomFragment.setOnMenuItemClickListener(item: MenuItem) { internal fun ChatRoomFragment.setOnMenuItemClickListener(item: MenuItem) {
when (item.itemId) { when (item.itemId) {
MENU_ACTION_FAVORITE_UNFAVORITE_CHAT -> presenter.toggleFavoriteChatRoom( MENU_ACTION_FAVORITE_UNFAVOURITE_CHAT -> presenter.toggleFavoriteChatRoom(
chatRoomId, chatRoomId,
isFavorite isFavorite
) )
...@@ -87,7 +87,7 @@ private fun ChatRoomFragment.setupFavoriteMenuItem(menu: Menu) { ...@@ -87,7 +87,7 @@ private fun ChatRoomFragment.setupFavoriteMenuItem(menu: Menu) {
if (isFavorite) { if (isFavorite) {
menu.add( menu.add(
Menu.NONE, Menu.NONE,
MENU_ACTION_FAVORITE_UNFAVORITE_CHAT, MENU_ACTION_FAVORITE_UNFAVOURITE_CHAT,
Menu.NONE, Menu.NONE,
R.string.title_unfavorite_chat R.string.title_unfavorite_chat
).setIcon(R.drawable.ic_star_yellow_24dp) ).setIcon(R.drawable.ic_star_yellow_24dp)
...@@ -95,7 +95,7 @@ private fun ChatRoomFragment.setupFavoriteMenuItem(menu: Menu) { ...@@ -95,7 +95,7 @@ private fun ChatRoomFragment.setupFavoriteMenuItem(menu: Menu) {
} else { } else {
menu.add( menu.add(
Menu.NONE, Menu.NONE,
MENU_ACTION_FAVORITE_UNFAVORITE_CHAT, MENU_ACTION_FAVORITE_UNFAVOURITE_CHAT,
Menu.NONE, Menu.NONE,
R.string.title_favorite_chat R.string.title_favorite_chat
).setIcon(R.drawable.ic_star_border_white_24dp) ).setIcon(R.drawable.ic_star_border_white_24dp)
......
...@@ -21,7 +21,8 @@ data class MessageUiModel( ...@@ -21,7 +21,8 @@ data class MessageUiModel(
var isFirstUnread: Boolean, var isFirstUnread: Boolean,
override var isTemporary: Boolean = false, override var isTemporary: Boolean = false,
override var menuItemsToHide: MutableList<Int> = mutableListOf(), override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var permalink: String override var permalink: String,
val subscriptionId: String
) : BaseMessageUiModel<Message> { ) : BaseMessageUiModel<Message> {
override val viewType: Int override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE.viewType get() = BaseUiModel.ViewType.MESSAGE.viewType
......
...@@ -456,7 +456,8 @@ class UiModelMapper @Inject constructor( ...@@ -456,7 +456,8 @@ class UiModelMapper @Inject constructor(
messageId = message.id, avatar = avatar!!, time = time, senderName = sender, messageId = message.id, avatar = avatar!!, time = time, senderName = sender,
content = content, isPinned = message.pinned, currentDayMarkerText = dayMarkerText, content = content, isPinned = message.pinned, currentDayMarkerText = dayMarkerText,
showDayMarker = false, reactions = getReactions(message), isFirstUnread = false, showDayMarker = false, reactions = getReactions(message), isFirstUnread = false,
preview = preview, isTemporary = !synced, unread = unread, permalink = permalink) preview = preview, isTemporary = !synced, unread = unread, permalink = permalink,
subscriptionId = chatRoom.subscriptionId)
} }
private fun mapMessagePreview(message: Message): Message { private fun mapMessagePreview(message: Message): Message {
......
...@@ -38,6 +38,8 @@ import chat.rocket.android.server.ui.ChangeServerActivity ...@@ -38,6 +38,8 @@ import chat.rocket.android.server.ui.ChangeServerActivity
import chat.rocket.android.settings.di.SettingsFragmentProvider 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 chat.rocket.android.userdetails.di.UserDetailsModule
import chat.rocket.android.userdetails.ui.UserDetailsActivity
import chat.rocket.android.webview.adminpanel.di.AdminPanelWebViewFragmentProvider import chat.rocket.android.webview.adminpanel.di.AdminPanelWebViewFragmentProvider
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
...@@ -46,16 +48,16 @@ import dagger.android.ContributesAndroidInjector ...@@ -46,16 +48,16 @@ import dagger.android.ContributesAndroidInjector
abstract class ActivityBuilder { abstract class ActivityBuilder {
@PerActivity @PerActivity
@ContributesAndroidInjector( @ContributesAndroidInjector(
modules = [AuthenticationModule::class, modules = [AuthenticationModule::class,
OnBoardingFragmentProvider::class, OnBoardingFragmentProvider::class,
ServerFragmentProvider::class, ServerFragmentProvider::class,
LoginOptionsFragmentProvider::class, LoginOptionsFragmentProvider::class,
LoginFragmentProvider::class, LoginFragmentProvider::class,
RegisterUsernameFragmentProvider::class, RegisterUsernameFragmentProvider::class,
ResetPasswordFragmentProvider::class, ResetPasswordFragmentProvider::class,
SignupFragmentProvider::class, SignupFragmentProvider::class,
TwoFAFragmentProvider::class TwoFAFragmentProvider::class
] ]
) )
abstract fun bindAuthenticationActivity(): AuthenticationActivity abstract fun bindAuthenticationActivity(): AuthenticationActivity
...@@ -108,6 +110,11 @@ abstract class ActivityBuilder { ...@@ -108,6 +110,11 @@ abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = [MessageInfoFragmentProvider::class]) @ContributesAndroidInjector(modules = [MessageInfoFragmentProvider::class])
abstract fun bindMessageInfoActiviy(): MessageInfoActivity abstract fun bindMessageInfoActiviy(): MessageInfoActivity
@PerActivity
@ContributesAndroidInjector(modules = [DrawModule::class]) @ContributesAndroidInjector(modules = [DrawModule::class])
abstract fun bindDrawingActivity(): DrawingActivity abstract fun bindDrawingActivity(): DrawingActivity
@PerActivity
@ContributesAndroidInjector(modules = [UserDetailsModule::class])
abstract fun bindUserDetailsActivity(): UserDetailsActivity
} }
...@@ -47,4 +47,4 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : ...@@ -47,4 +47,4 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) :
setOnClickListener { listener(memberUiModel) } setOnClickListener { listener(memberUiModel) }
} }
} }
} }
\ No newline at end of file
package chat.rocket.android.members.presentation package chat.rocket.android.members.presentation
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.members.ui.TAG_MEMBER_BOTTOM_SHEET_FRAGMENT import chat.rocket.android.userdetails.ui.userDetailsIntent
import chat.rocket.android.members.ui.newInstance
class MembersNavigator(internal val activity: ChatDetailsActivity) { class MembersNavigator(internal val activity: ChatDetailsActivity) {
fun toMemberDetails(avatarUri: String, realName: String, username: String, email: String, utcOffset: String) { fun toMemberDetails(userId: String) {
activity.apply { activity.apply {
newInstance(avatarUri, realName, username, email, utcOffset) startActivity(this.userDetailsIntent(userId, ""))
.show(supportFragmentManager, TAG_MEMBER_BOTTOM_SHEET_FRAGMENT)
} }
} }
} }
...@@ -59,12 +59,6 @@ class MembersPresenter @Inject constructor( ...@@ -59,12 +59,6 @@ class MembersPresenter @Inject constructor(
} }
fun toMemberDetails(memberUiModel: MemberUiModel) { fun toMemberDetails(memberUiModel: MemberUiModel) {
navigator.toMemberDetails( navigator.toMemberDetails(memberUiModel.userId)
memberUiModel.avatarUri.toString(),
memberUiModel.realName.toString(),
"@${memberUiModel.username}",
memberUiModel.email ?: "",
memberUiModel.utcOffset.toString()
)
} }
} }
\ No newline at end of file
...@@ -11,6 +11,7 @@ class MemberUiModel( ...@@ -11,6 +11,7 @@ class MemberUiModel(
private val settings: Map<String, Value<Any>>, private val settings: Map<String, Value<Any>>,
private val baseUrl: String? private val baseUrl: String?
) { ) {
val userId: String = member.id
val avatarUri: String? val avatarUri: String?
val displayName: String val displayName: String
val realName: String? val realName: String?
...@@ -52,4 +53,4 @@ class MemberUiModel( ...@@ -52,4 +53,4 @@ class MemberUiModel(
private fun getUserUtcOffset(): Float? = member.utcOffset private fun getUserUtcOffset(): Float? = member.utcOffset
private fun getUserStatus(): UserStatus? = member.status private fun getUserStatus(): UserStatus? = member.status
} }
\ No newline at end of file
...@@ -7,11 +7,14 @@ import chat.rocket.common.model.User ...@@ -7,11 +7,14 @@ import chat.rocket.common.model.User
import chat.rocket.core.model.Value import chat.rocket.core.model.Value
import javax.inject.Inject import javax.inject.Inject
class MemberUiModelMapper @Inject constructor(serverInteractor: GetCurrentServerInteractor, getSettingsInteractor: GetSettingsInteractor) { class MemberUiModelMapper @Inject constructor(
serverInteractor: GetCurrentServerInteractor,
getSettingsInteractor: GetSettingsInteractor
) {
private var settings: Map<String, Value<Any>> = getSettingsInteractor.get(serverInteractor.get()!!) private var settings: Map<String, Value<Any>> = getSettingsInteractor.get(serverInteractor.get()!!)
private val baseUrl = settings.baseUrl() private val baseUrl = settings.baseUrl()
fun mapToUiModelList(memberList: List<User>): List<MemberUiModel> { fun mapToUiModelList(memberList: List<User>): List<MemberUiModel> {
return memberList.map { MemberUiModel(it, settings, baseUrl) } return memberList.map { MemberUiModel(it, settings, baseUrl) }
} }
} }
\ No newline at end of file
...@@ -35,10 +35,6 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback { ...@@ -35,10 +35,6 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val disposables = CompositeDisposable() private val disposables = CompositeDisposable()
companion object {
fun newInstance() = PasswordFragment()
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -143,4 +139,8 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback { ...@@ -143,4 +139,8 @@ class PasswordFragment : Fragment(), PasswordView, ActionMode.Callback {
actionMode = (activity as PasswordActivity).startSupportActionMode(this) actionMode = (activity as PasswordActivity).startSupportActionMode(this)
} }
} }
}
\ No newline at end of file companion object {
fun newInstance() = PasswordFragment()
}
}
package chat.rocket.android.userdetails.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerActivity
import chat.rocket.android.userdetails.presentation.UserDetailsView
import chat.rocket.android.userdetails.ui.UserDetailsActivity
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class UserDetailsModule {
@Provides
@PerActivity
fun provideJob() = Job()
@Provides
@PerActivity
fun provideUserDetailsView(activity: UserDetailsActivity): UserDetailsView = activity
@Provides
@PerActivity
fun provideLifecycleOwner(activity: UserDetailsActivity): LifecycleOwner = activity
@Provides
@PerActivity
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
package chat.rocket.android.userdetails.presentation
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.helper.UserHelper
import chat.rocket.android.server.domain.GetConnectingServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.android.util.retryIO
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.rest.createDirectMessage
import chat.rocket.core.internal.rest.spotlight
import chat.rocket.core.model.ChatRoom
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import javax.inject.Inject
class UserDetailsPresenter @Inject constructor(
private val view: UserDetailsView,
private val dbManager: DatabaseManager,
private val strategy: CancelStrategy,
serverInteractor: GetConnectingServerInteractor,
factory: ConnectionManagerFactory,
userHelper: UserHelper
) {
private var currentServer = serverInteractor.get()!!
private val manager = factory.create(currentServer)
private val client = manager.client
private val currentUserId = userHelper.user()?.id
fun loadUserDetails(userId: String) {
launchUI(strategy) {
try {
val user = withContext(CommonPool) {
dbManager.userDao().getUser(id = userId)
}
user?.let { u ->
val localDMs = chatRoomByName(name = u.name)
val avatarUrl = u.username?.let { currentServer.avatarUrl(avatar = it) }
val chatRoom: ChatRoom? = if (localDMs.isEmpty()) {
val query = u.username!!
val spotlightResult = retryIO("spotlight($query)") {
client.spotlight(query = query)
}
val matchFromSpotlight = spotlightResult.users.firstOrNull { it.username == query }
if (matchFromSpotlight != null) {
val result = retryIO("createDirectMessage(${matchFromSpotlight.id}") {
client.createDirectMessage(username = matchFromSpotlight.id)
}
with(matchFromSpotlight) {
ChatRoom(
id = result.id,
type = roomTypeOf(RoomType.DIRECT_MESSAGE),
name = u.username ?: u.name.orEmpty(),
fullName = u.name,
favorite = false,
open = false,
alert = false,
status = status,
client = client,
broadcast = false,
archived = false,
default = false,
description = null,
groupMentions = null,
userMentions = null,
lastMessage = null,
lastSeen = null,
topic = null,
announcement = null,
roles = null,
unread = 0,
readonly = false,
muted = null,
subscriptionId = "",
timestamp = null,
updatedAt = null,
user = null
)
}
} else null
} else localDMs.firstOrNull()
view.showUserDetails(
avatarUrl = avatarUrl,
username = u.username,
name = u.name,
utcOffset = u.utcOffset,
status = u.status,
chatRoom = chatRoom
)
}
} catch (ex: Exception) {
Timber.e(ex)
}
}
}
fun createDirectMessage(username: String) {
}
private suspend fun chatRoomByName(name: String? = null): List<ChatRoom> = withContext(CommonPool) {
return@withContext dbManager.chatRoomDao().getAllSync().filter {
if (name == null) {
return@filter true
}
it.chatRoom.name == name || it.chatRoom.fullname == name
}.map {
with(it.chatRoom) {
ChatRoom(
id = id,
subscriptionId = subscriptionId,
type = roomTypeOf(type),
unread = unread,
broadcast = broadcast ?: false,
alert = alert,
fullName = fullname,
name = name ?: "",
favorite = favorite ?: false,
default = isDefault ?: false,
readonly = readonly,
open = open,
lastMessage = null,
archived = false,
status = null,
user = null,
userMentions = userMentions,
client = client,
announcement = null,
description = null,
groupMentions = groupMentions,
roles = null,
topic = null,
lastSeen = this.lastSeen,
timestamp = timestamp,
updatedAt = updatedAt
)
}
}
}
}
package chat.rocket.android.userdetails.presentation
import chat.rocket.core.model.ChatRoom
interface UserDetailsView {
fun showUserDetails(avatarUrl: String?, username: String?, name: String?, utcOffset: Float?, status: String, chatRoom: ChatRoom?)
}
package chat.rocket.android.userdetails.ui
import android.content.Context
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import blurred
import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.chatRoomIntent
import chat.rocket.android.emoji.internal.GlideApp
import chat.rocket.android.userdetails.presentation.UserDetailsPresenter
import chat.rocket.android.userdetails.presentation.UserDetailsView
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.extension.orFalse
import chat.rocket.android.util.extensions.showToast
import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.model.ChatRoom
import chat.rocket.core.model.userId
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.CenterInside
import com.bumptech.glide.load.resource.bitmap.FitCenter
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.activity_user_details.*
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import org.threeten.bp.OffsetDateTime
import org.threeten.bp.ZoneId
import org.threeten.bp.ZoneOffset
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.format.DateTimeFormatter
import timber.log.Timber
import javax.inject.Inject
import kotlin.math.roundToLong
fun Context.userDetailsIntent(userId: String, subscriptionId: String): Intent {
return Intent(this, UserDetailsActivity::class.java).apply {
putExtra(EXTRA_USER_ID, userId)
putExtra(EXTRA_SUBSCRIPTION_ID, subscriptionId)
}
}
const val EXTRA_USER_ID = "EXTRA_USER_ID"
const val EXTRA_SUBSCRIPTION_ID = "EXTRA_USERNAME"
class UserDetailsActivity : AppCompatActivity(), UserDetailsView, HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var presenter: UserDetailsPresenter
private lateinit var subscriptionId: String
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_details)
setupToolbar()
val userId = intent.getStringExtra(EXTRA_USER_ID)
subscriptionId = intent.getStringExtra(EXTRA_SUBSCRIPTION_ID)
showLoadingView(true)
presenter.loadUserDetails(userId = userId)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentDispatchingAndroidInjector
private fun setupToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
toolbar.setNavigationOnClickListener { finish() }
}
override fun showUserDetails(
avatarUrl: String?,
username: String?,
name: String?,
utcOffset: Float?,
status: String,
chatRoom: ChatRoom?
) {
text_view_name.text = name
text_view_username.text = username
text_view_status.text = status.capitalize()
launch(UI) {
val image = withContext(CommonPool) {
val requestOptions = RequestOptions()
.priority(Priority.IMMEDIATE)
.transforms(CenterInside(), FitCenter())
return@withContext GlideApp.with(this@UserDetailsActivity)
.asBitmap()
.load(avatarUrl)
.apply(requestOptions)
.submit()
.get().also { showLoadingView(false) }
}
val blurredBitmap = image.blurred(context = this@UserDetailsActivity,
newWidth = toolbar.measuredWidth, newHeight = toolbar.measuredHeight)
toolbar.background = BitmapDrawable(resources, blurredBitmap)
GlideApp.with(this@UserDetailsActivity)
.asBitmap()
.transforms(RoundedCorners(25), CenterCrop())
.load(avatarUrl)
.into(image_view_avatar)
}
utcOffset?.let {
val offsetLong = it.roundToLong()
val offset = if (it > 0) "+$offsetLong" else offsetLong.toString()
val formatter = DateTimeFormatter.ofPattern("'(GMT$offset)' hh:mm a")
val zoneId = ZoneId.systemDefault()
val timeNow = OffsetDateTime.now(ZoneOffset.UTC).plusHours(offsetLong).toLocalDateTime()
text_view_tz.text = formatter.format(ZonedDateTime.of(timeNow, zoneId))
}
text_view_message.setOnClickListener {
toDirectMessage(chatRoom = chatRoom)
}
image_view_message.setOnClickListener {
toDirectMessage(chatRoom = chatRoom)
}
}
private fun showLoadingView(show: Boolean) {
runOnUiThread {
group_user_details.isVisible = !show
view_loading.isVisible = show
}
}
private fun toDirectMessage(chatRoom: ChatRoom?) {
chatRoom?.let { c ->
finish()
if (c.subscriptionId.isEmpty() || c.subscriptionId != subscriptionId) {
startActivity(
chatRoomIntent(
chatRoomId = c.id,
chatRoomName = c.name,
chatRoomType = c.type.toString(),
isReadOnly = c.readonly.orFalse(),
chatRoomLastSeen = c.lastSeen ?: 0,
isSubscribed = c.open,
isCreator = false,
isFavorite = c.favorite
)
)
}
}
}
}
import android.content.Context
import android.graphics.Bitmap
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
fun Bitmap.blurred(context: Context, intensity: Float = 25f, newWidth: Int = -1, newHeight: Int = -1): Bitmap {
if (intensity <= 0 || intensity > 25) {
throw IllegalStateException("Intensity out of range (0 < intensity <= 25).")
}
val nonScaledBitmap = copy(config, true)
val bitmap = if (newWidth > 0 && newHeight > 0) {
val height = nonScaledBitmap.height
val width = nonScaledBitmap.width
val aspectRadio = width / height
val adjustedWidth = newHeight * aspectRadio
val adjustedHeight = newWidth * height / width
val scaledBitmap = Bitmap.createScaledBitmap(nonScaledBitmap, adjustedWidth, adjustedHeight, false)
Bitmap.createBitmap(scaledBitmap, 0, 0, adjustedWidth, newHeight)
} else nonScaledBitmap
val rs = RenderScript.create(context)
val input = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT)
val output = Allocation.createTyped(rs, input.type)
val script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
script.setRadius(intensity)
script.setInput(input)
script.forEach(output)
output.copyTo(bitmap)
return bitmap
}
...@@ -118,4 +118,4 @@ fun Menu.toList(): List<MenuItem> { ...@@ -118,4 +118,4 @@ fun Menu.toList(): List<MenuItem> {
val menuItems = ArrayList<MenuItem>(this.size()) val menuItems = ArrayList<MenuItem>(this.size())
(0 until this.size()).mapTo(menuItems) { this.getItem(it) } (0 until this.size()).mapTo(menuItems) { this.getItem(it) }
return menuItems return menuItems
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="@android:color/white" />
<corners android:radius="25px" />
</shape>
<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="#1d74f5"
android:fillType="evenOdd"
android:pathData="M10.11,16.546h-0.183c-4.329,0 -7.47,-2.753 -7.47,-6.546 0,-3.61 2.942,-6.547 6.56,-6.547 3.616,0 6.56,2.937 6.56,6.547 0,0.59 -0.276,1.18 -0.567,1.803 -0.1,0.218 -0.2,0.433 -0.278,0.618 -0.756,1.626 0.731,2.41 1.364,2.743 0.098,0.051 0.224,0.117 0.326,0.178 -0.416,0.478 -1.814,1.22 -6.312,1.204m6.666,-2.667c-0.895,-0.473 -0.852,-0.567 -0.71,-0.875 0.081,-0.193 0.172,-0.389 0.264,-0.587 0.33,-0.705 0.703,-1.505 0.703,-2.417 0,-4.412 -3.597,-8 -8.017,-8S1,5.588 1,10c0,4.635 3.755,8 8.927,8h0.382c2.857,0 6.632,-0.256 7.565,-2.237 0.493,-1.046 -0.58,-1.612 -1.098,-1.884" />
</vector>
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
android:orientation="vertical" android:orientation="vertical"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:context=".settings.password.ui.PasswordActivity"> tools:context=".settings.password.ui.PasswordActivity">
<include <include
android:id="@+id/layout_app_bar" android:id="@+id/layout_app_bar"
layout="@layout/app_bar_password" /> layout="@layout/app_bar_password" />
<FrameLayout <FrameLayout
android:id="@+id/fragment_container" android:id="@+id/fragment_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:background="@android:color/white"
android:fitsSystemWindows="true">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
style="@style/Authentication.AVLoadingIndicatorView"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<ImageView
android:id="@+id/image_view_message"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view_username"
app:srcCompat="@drawable/ic_message_24dp" />
<TextView
android:id="@+id/text_view_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/message"
android:textColor="#1d74f5"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="@+id/image_view_message"
app:layout_constraintStart_toStartOf="@+id/image_view_message"
app:layout_constraintTop_toBottomOf="@+id/image_view_message" />
<TextView
android:id="@+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:fontFamily="sans-serif-medium"
android:textColor="@android:color/black"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Karem Flusser" />
<TextView
android:id="@+id/text_view_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textColor="@color/darkGray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view_name"
tools:text="karem.flusser" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:text="@string/status"
android:textColor="@color/darkGray"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view_message" />
<TextView
android:id="@+id/text_view_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:textColor="@android:color/black"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3"
tools:text="Online" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/timezone"
android:textColor="@color/darkGray"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_view_status" />
<TextView
android:id="@+id/text_view_tz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:textColor="@android:color/black"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
tools:text="(UTC-2) 11:08 AM" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_user_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text_view_tz,textView,text_view_status,text_view_message,textView3,text_view_name,text_view_username,image_view_message" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
app:elevation="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@android:color/white"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="?actionBarSize"
app:elevation="0dp"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="?android:attr/homeAsUpIndicator"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<ImageView
android:id="@+id/image_view_avatar"
android:layout_width="98dp"
android:layout_height="98dp"
android:layout_gravity="center_horizontal"
android:layout_marginStart="16dp"
android:layout_marginTop="?actionBarSize"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_round_bounds_white"
tools:srcCompat="@tools:sample/avatars[6]" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
...@@ -329,6 +329,9 @@ ...@@ -329,6 +329,9 @@
<string name="notif_success_sending">Nachricht gesendet nach %1$s!</string> <string name="notif_success_sending">Nachricht gesendet nach %1$s!</string>
<string name="read_by">Gelesen von</string> <string name="read_by">Gelesen von</string>
<string name="message_information_title">Nachricht Information</string> <string name="message_information_title">Nachricht Information</string>
<!--TODO - Add proper translation--> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
</resources> <!-- User Details -->
\ No newline at end of file <string name="message">Message</string> <!--TODO - Add proper translation-->
<string name="timezone">Timezone</string> <!--TODO - Add proper translation-->
</resources>
...@@ -330,6 +330,9 @@ ...@@ -330,6 +330,9 @@
<string name="msg_file_description">Descripción del archivo</string> <string name="msg_file_description">Descripción del archivo</string>
<string name="msg_send">Enviar</string> <string name="msg_send">Enviar</string>
<string name="msg_sent_attachment">Envió un archivo</string> <string name="msg_sent_attachment">Envió un archivo</string>
<!--TODO - Add proper translation--> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<!-- User Details -->
<string name="message">Message</string> <!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string> <!-- TODO - Add proper translation -->
</resources> </resources>
...@@ -334,4 +334,10 @@ ...@@ -334,4 +334,10 @@
<string name="msg_sent_attachment">Envoyé un fichier</string> <string name="msg_sent_attachment">Envoyé un fichier</string>
<!--TODO - Add proper translation--> <!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
\ No newline at end of file
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
<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> <string name="title_create_channel">चैनल बनाएं</string>
<string name="title_licence">Licence</string> <!-- TODO Add translation --> <string name="title_licence">लाइसेंस</string>
<string name="title_are_you_sure">Are you sure?</string> <!-- TODO Add translation --> <string name="title_are_you_sure">क्या आपको यकीन है?</string>
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation --> <string name="title_channel_details">चैनल विवरण</string>
<string name="title_topic">विषय</string> <string name="title_topic">विषय</string>
<string name="title_announcement">घोषणा</string> <string name="title_announcement">घोषणा</string>
<string name="title_description">विवरण</string> <string name="title_description">विवरण</string>
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
<string name="action_create_channel">चैनल बनाएं</string> <string name="action_create_channel">चैनल बनाएं</string>
<string name="action_create">बनाएं</string> <string name="action_create">बनाएं</string>
<string name="action_logout">लोग आउट करें</string> <string name="action_logout">लोग आउट करें</string>
<string name="action_attach_a_files">Attach a file</string> <!-- TODO Add translation --> <string name="action_attach_a_files">एक फ़ाइल जोडो</string>
<string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string> <string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string>
<string name="action_join_chat">चैट में शामिल हों</string> <string name="action_join_chat">चैट में शामिल हों</string>
<string name="action_add_account">खाता जोड़ो</string> <string name="action_add_account">खाता जोड़ो</string>
...@@ -58,17 +58,17 @@ ...@@ -58,17 +58,17 @@
<string name="action_create_server">नया सर्वर बनाएं</string> <string name="action_create_server">नया सर्वर बनाएं</string>
<string name="action_register">रजिस्टर</string> <string name="action_register">रजिस्टर</string>
<string name="action_confirm">पुष्टि करें</string> <string name="action_confirm">पुष्टि करें</string>
<string name="action_delete_account">Delete account</string> <!-- TODO Add translation --> <string name="action_delete_account">खाता हटा दो</string>
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation --> <item name="item_preferences">पसंद</item>
<item name="item_password">Change password</item> <!-- TODO Add translation --> <item name="item_password">पासवर्ड बदलें</item>
<item name="item_share_app">Share app</item> <!-- TODO Add translation --> <item name="item_share_app">ऐप शेयर करें</item>
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation --> <item name="item_rate_us">हमें रेटिंग दें</item>
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation --> <item name="item_contact_us">हमसे संपर्क करें</item>
<item name="item_licence">Licence</item> <!-- TODO Add translation --> <item name="item_licence">लाइसेंस</item>
<item name="item_about">About</item> <!-- TODO Add translation --> <item name="item_about">के बारे में</item>
</string-array> </string-array>
<!-- Regular information messages --> <!-- Regular information messages -->
...@@ -177,18 +177,18 @@ ...@@ -177,18 +177,18 @@
<string name="msg_channel_created_successfully">चैनल सफलतापूर्वक बनाया गया</string> <string name="msg_channel_created_successfully">चैनल सफलतापूर्वक बनाया गया</string>
<string name="msg_view_more">और देखें</string> <string name="msg_view_more">और देखें</string>
<string name="msg_view_less">कम देखें</string> <string name="msg_view_less">कम देखें</string>
<string name="msg_permalink_copied">Permalink copied</string> <!-- TODO - Add proper translation --> <string name="msg_permalink_copied">पर्मलिंक की प्रतिलिपि बनाई गई</string>
<string name="msg_send_email">Send email</string> <!-- TODO - Add proper translation --> <string name="msg_send_email">ईमेल भेजें</string>
<string name="msg_android_app_support">Android app support</string> <!-- TODO - Add proper translation --> <string name="msg_android_app_support">एंड्रॉइड ऐप समर्थन</string>
<string name="msg_muted_on_this_channel">You are muted on this channel</string> <!-- TODO - Add proper translation --> <string name="msg_muted_on_this_channel">आप इस चैनल पर म्यूट कर रहे हैं</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation --> <string name="msg_no_topic">कोई विषय नहीं जोड़ा गया</string>
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation --> <string name="msg_no_announcement">कोई घोषणा नहीं जोड़ा गया</string>
<string name="msg_no_description">No description added</string> <!-- TODO Add translation --> <string name="msg_no_description">कोई विवरण नहीं जोड़ा गया</string>
<plurals name="msg_reacted_with_"> <plurals name="msg_reacted_with_">
<item quantity="one">%1$s reacted with %2$s</item> <!-- TODO - Add proper translation --> <item quantity="one">% 1 $ s ने% 2 $ %d s के साथ प्रतिक्रिया व्यक्त की</item>
<item quantity="few">%1$s reacted with %2$s</item> <!-- TODO - Add proper translation --> <item quantity="few">% 1 $ s ने% 2 $ s के साथ प्रतिक्रिया व्यक्त की</item>
<item quantity="many">%1$s reacted with %2$s</item> <!-- TODO - Add proper translation --> <item quantity="many">% 1 $ s ने% 2 $ s के साथ प्रतिक्रिया व्यक्त की</item>
</plurals> </plurals>
<!-- Preferences messages --> <!-- Preferences messages -->
...@@ -226,8 +226,7 @@ ...@@ -226,8 +226,7 @@
<string name="action_msg_share">शेयर करें</string> <string name="action_msg_share">शेयर करें</string>
<string name="action_title_editing">संपादन संदेश</string> <string name="action_title_editing">संपादन संदेश</string>
<string name="action_msg_add_reaction">प्रतिक्रिया जोड़ें</string> <string name="action_msg_add_reaction">प्रतिक्रिया जोड़ें</string>
<!-- TODO - Add proper translation --> <string name="action_msg_copy_permalink">परमालिंक कॉपी करें</string>
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages --> <!-- Permission messages -->
<string name="permission_editing_not_allowed">संपादन की अनुमति नहीं है</string> <string name="permission_editing_not_allowed">संपादन की अनुमति नहीं है</string>
...@@ -334,4 +333,10 @@ ...@@ -334,4 +333,10 @@
<string name="message_information_title">संदेश की जानकारी</string> <string name="message_information_title">संदेश की जानकारी</string>
<string name="msg_log_out">लॉग आउट कर रहा हूं…</string> <string name="msg_log_out">लॉग आउट कर रहा हूं…</string>
<string name="message_room_changed_privacy">%2$s ने रूम का प्रकार बदलकर %1$s किया </string> <string name="message_room_changed_privacy">%2$s ने रूम का प्रकार बदलकर %1$s किया </string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
...@@ -329,4 +329,9 @@ ...@@ -329,4 +329,9 @@
<string name="message_information_title">Informazioni Messaggio</string> <string name="message_information_title">Informazioni Messaggio</string>
<string name="message_room_changed_privacy">Il tipo di stanza è cambiato in: %1$s da %2$s</string> <string name="message_room_changed_privacy">Il tipo di stanza è cambiato in: %1$s da %2$s</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
...@@ -336,4 +336,9 @@ ...@@ -336,4 +336,9 @@
<string name="message_room_changed_privacy">ルームタイプを %2$s から %1$s に変更しました</string> <string name="message_room_changed_privacy">ルームタイプを %2$s から %1$s に変更しました</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
\ No newline at end of file
...@@ -332,4 +332,10 @@ ...@@ -332,4 +332,10 @@
<string name="msg_log_out">Deslogando…</string> <string name="msg_log_out">Deslogando…</string>
<string name="msg_sent_attachment">Enviou um arquivo</string> <string name="msg_sent_attachment">Enviou um arquivo</string>
<string name="message_room_changed_privacy">O tipo da sala mudou para: %1$s por %2$s</string> <string name="message_room_changed_privacy">O tipo da sala mudou para: %1$s por %2$s</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Mensagem</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Fuso horário</string>
</resources> </resources>
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<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> <string name="title_create_channel">Создать новый канал</string>
<string name="title_channel_details">Channel Details</string> <!-- TODO add translation --> <string name="title_channel_details">О канале</string>
<string name="title_topic">Тема</string> <string name="title_topic">Тема</string>
<string name="title_announcement">Объявление</string> <string name="title_announcement">Объявление</string>
<string name="title_description">Описание</string> <string name="title_description">Описание</string>
...@@ -163,9 +163,9 @@ ...@@ -163,9 +163,9 @@
<string name="msg_view_more">больше</string> <string name="msg_view_more">больше</string>
<string name="msg_view_less">меньше</string> <string name="msg_view_less">меньше</string>
<string name="msg_permalink_copied">Ссылка скопирована</string> <string name="msg_permalink_copied">Ссылка скопирована</string>
<string name="msg_no_topic">No topic added</string> <!-- TODO Add translation --> <string name="msg_no_topic">Нет темы</string>
<string name="msg_no_announcement">No announcement added</string> <!-- TODO Add translation --> <string name="msg_no_announcement">Нет объявления</string>
<string name="msg_no_description">No description added</string> <!-- TODO Add translation --> <string name="msg_no_description">Нет описания</string>
<string name="msg_send_email">Отправить e-mail</string> <string name="msg_send_email">Отправить e-mail</string>
<string name="msg_android_app_support">Поддержка Android-приложения</string> <string name="msg_android_app_support">Поддержка Android-приложения</string>
<string name="msg_muted_on_this_channel">Вы лишены дара речи на этом канале</string> <string name="msg_muted_on_this_channel">Вы лишены дара речи на этом канале</string>
...@@ -330,4 +330,10 @@ ...@@ -330,4 +330,10 @@
<string name="message_information_title">Информация о прочтении</string> <string name="message_information_title">Информация о прочтении</string>
<string name="msg_log_out">Выходим…</string> <string name="msg_log_out">Выходим…</string>
<string name="message_room_changed_privacy">Тип канала изменен на: %1$s пользователем %2$s</string> <string name="message_room_changed_privacy">Тип канала изменен на: %1$s пользователем %2$s</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
...@@ -332,6 +332,9 @@ ...@@ -332,6 +332,9 @@
<string name="notif_success_sending">Mesaj %1$s\'a gönderildi!</string> <string name="notif_success_sending">Mesaj %1$s\'a gönderildi!</string>
<string name="read_by">ile oku</string> <string name="read_by">ile oku</string>
<string name="message_information_title">Mesaj bilgisi</string> <string name="message_information_title">Mesaj bilgisi</string>
<!--TODO - Add proper translation--> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<!-- User Details -->
<string name="message">Message</string> <!--TODO - Add proper translation-->
<string name="timezone">Timezone</string> <!--TODO - Add proper translation-->
</resources> </resources>
...@@ -332,4 +332,10 @@ ...@@ -332,4 +332,10 @@
<string name="msg_sent_attachment">Долучення відправлено</string> <string name="msg_sent_attachment">Долучення відправлено</string>
<!--TODO - Add proper translation--> <!--TODO - Add proper translation-->
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<!-- User Details -->
<!-- TODO - Add proper translation -->
<string name="message">Message</string>
<!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string>
</resources> </resources>
...@@ -203,7 +203,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin ...@@ -203,7 +203,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_view_more">view more</string> <string name="msg_view_more">view more</string>
<string name="msg_view_less">view less</string> <string name="msg_view_less">view less</string>
<string name="msg_muted_on_this_channel">You are muted on this channel</string> <string name="msg_muted_on_this_channel">You are muted on this channel</string>
<!-- Preferences messages --> <!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <string name="msg_analytics_tracking">Analytics tracking</string>
<string name="msg_send_analytics_tracking">Send anonymous statics to help improving this app</string> <string name="msg_send_analytics_tracking">Send anonymous statics to help improving this app</string>
...@@ -346,5 +346,10 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin ...@@ -346,5 +346,10 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="message_information_title">Message information</string> <string name="message_information_title">Message information</string>
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<string name="foss" tools:ignore="MissingTranslation">(FOSS)</string> <string name="foss" translatable="false">(FOSS)</string>
<!-- User Details -->
<string name="message">Message</string>
<string name="timezone">Timezone</string>
<string name="status" translatable="false">Status</string>
</resources> </resources>
\ No newline at end of file
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