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

Merge branch 'develop' into I_1395

parents 49650051 92d3243b
......@@ -2,7 +2,7 @@
# Rocket.Chat Android native application
[![CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop.svg?style=shield)](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop) [![Build Status](https://travis-ci.org/RocketChat/Rocket.Chat.Android.svg?branch=develop)](https://travis-ci.org/RocketChat/Rocket.Chat.Android) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a81156a8682e4649994270d3670c3c83)](https://www.codacy.com/app/matheusjardimb/Rocket.Chat.Android)
[![CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop.svg?style=shield)](https://circleci.com/gh/RocketChat/Rocket.Chat.Android/tree/develop) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a81156a8682e4649994270d3670c3c83)](https://www.codacy.com/app/matheusjardimb/Rocket.Chat.Android)
## Get it from the stores
......@@ -14,20 +14,21 @@ This repository contains all the code related to the Android native application
## How to build
- You need to download the latest [Android Studio Preview](https://developer.android.com/studio/preview/) version since the stable IDE version does not support the [JetPack](https://developer.android.com/jetpack/) that is being used on this application.
- Make sure that you have the latest **gradle** and the **android plugin** versions installed. Go to `File > Project Structure > Project` and make sure that you have the latest versions installed. Refer [this](https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle) to see the compatible versions.
- Make sure that you have the latest **Gradle** and the **Android plugin** versions installed. Go to `File > Project Structure > Project` and make sure that you have the latest versions installed. Refer [this](https://developer.android.com/studio/releases/gradle-plugin.html#updating-gradle) to see the compatible versions.
- Kotlin is already configured in the project. To check, go to `Tools > Kotlin > Configure Kotlin in project`. A message saying kotlin is already configured in the project pops up. You can update kotlin to the latest version by going to `Tools > Kotlin > Configure Kotlin updates` and download the latest version of kotlin.
### SDK Instructions
- This version requires the [Kotlin SDK](https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK) for Rocket.Chat. Clone the Kotlin SDK in by running `git clone https://github.com/RocketChat/Rocket.Chat.Kotlin.SDK.git`.
- First, a build is required for the SDK, so that required jar files are generated. Make sure that the android repository and the kotlin sdk have the same immediate parent directory. Change the current directory to `Rocket.Chat.Android/app` and run the `build-sdk.sh` which will result in creating of the required jar file `core*.jar` and `common*.jar` in `Rocket.Chat.Android/app/libs`,by the following steps in your terminal window:
- First, a build is required for the SDK, so that required jar files are generated. Make sure that the Android repository and the Kotlin SDK have the same immediate parent directory. Change the current directory to `Rocket.Chat.Android/app` and run the `build-sdk.sh` which will result in creating of the required jar file `core*.jar` and `common*.jar` in `Rocket.Chat.Android/app/libs`, by the following steps in your terminal window:
```
cd Rocket.Chat.Android/app
./build-sdk.sh
```
**Note:** *You need to have Java 8 as default Java for the system (project won't build when using a Java 9+ version).*
## How to run
### Command Line
......@@ -38,12 +39,12 @@ cd Rocket.Chat.Android/app
### Android Studio
- After importing the project in android studio, go to `Run > Run app` and then select your device, or create a new virtual device by following the wizard.
- After importing the project in Android Studio, go to `Run > Run app` and then select your device, or create a new virtual device by following the wizard.
## Bug report & Feature request
Are you having a technical issue trying to compile the app, or setting up Push Notifications? Please use our Community Support channel for that: https://forums.rocket.chat/c/community-support. The issues are only suppose to be used for bugs, improvements and features in the native Android application.
Are you having a technical issue trying to compile the app, or setting up Push Notifications? Please use our Community Support channel for that: https://forums.rocket.chat/c/community-support. The issues are only supposed to be used for bugs, improvements, and features in the native Android application.
## Coding Style
Please follow our [coding style](https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md) when contributing.
Please follow the official [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html) when contributing.
......@@ -16,7 +16,7 @@ android {
applicationId "chat.rocket.android"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
versionCode 2055
versionCode 2057
versionName "3.2.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
......@@ -140,6 +140,7 @@ dependencies {
implementation libraries.frescoAnimatedWebP
implementation libraries.glide
implementation libraries.glideTransformations
kapt libraries.kotshiCompiler
implementation libraries.kotshiApi
......
......@@ -78,11 +78,6 @@
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<activity
android:name=".chatdetails.ui.ChatDetailsActivity"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden" />
<activity
android:name=".chatinformation.ui.MessageInfoActivity"
android:theme="@style/AppTheme"
......@@ -93,16 +88,6 @@
android:name=".settings.password.ui.PasswordActivity"
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
android:name=".push.DirectReplyReceiver"
android:enabled="true"
......
......@@ -34,12 +34,16 @@ class AboutFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
setupViews()
analyticsManager.logScreenView(ScreenViewEvent.About)
}
override fun onResume() {
super.onResume()
setupToolbar()
}
private fun setupViews() {
text_version_name.text = BuildConfig.VERSION_NAME
text_build_number.text = getString(
......
......@@ -16,9 +16,9 @@ sealed class ScreenViewEvent(val screenName: String) {
object ChatRoom : ScreenViewEvent("ChatRoomFragment")
object ChatRooms : ScreenViewEvent("ChatRoomsFragment")
object CreateChannel : ScreenViewEvent("CreateChannelFragment")
object UserDetails : ScreenViewEvent("UserDetailsFragment")
object FavoriteMessages : ScreenViewEvent("FavoriteMessagesFragment")
object Files : ScreenViewEvent("FilesFragment")
object MemberBottomSheet : ScreenViewEvent("MemberBottomSheetFragment")
object Members : ScreenViewEvent("MembersFragment")
object Mentions : ScreenViewEvent("MentionsFragment")
object MessageInfo : ScreenViewEvent("MessageInfoFragment")
......
......@@ -5,7 +5,8 @@ import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module abstract class TwoFAFragmentProvider {
@Module
abstract class TwoFAFragmentProvider {
@ContributesAndroidInjector(modules = [TwoFAFragmentModule::class])
@PerFragment
......
package chat.rocket.android.chatdetails.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatdetails.presentation.ChatDetailsView
import chat.rocket.android.chatdetails.ui.ChatDetailsFragment
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.ChatRoomDao
import chat.rocket.android.db.DatabaseManager
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class ChatDetailsFragmentModule {
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun chatDetailsView(frag: ChatDetailsFragment): ChatDetailsView {
......@@ -27,16 +20,4 @@ class ChatDetailsFragmentModule {
@Provides
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: ChatDetailsFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.di
import chat.rocket.android.chatdetails.presentation.ChatDetailsNavigator
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
@Module
class ChatDetailsModule {
@Provides
@PerActivity
fun providesNavigator(activity: ChatDetailsActivity) = ChatDetailsNavigator(activity)
}
\ No newline at end of file
package chat.rocket.android.chatdetails.presentation
import chat.rocket.android.R
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.favoritemessages.ui.TAG_FAVORITE_MESSAGES_FRAGMENT
import chat.rocket.android.files.ui.TAG_FILES_FRAGMENT
import chat.rocket.android.members.ui.TAG_MEMBERS_FRAGMENT
import chat.rocket.android.mentions.ui.TAG_MENTIONS_FRAGMENT
import chat.rocket.android.pinnedmessages.ui.TAG_PINNED_MESSAGES_FRAGMENT
import chat.rocket.android.util.extensions.addFragmentBackStack
class ChatDetailsNavigator(internal val activity: ChatDetailsActivity) {
fun toMembersList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MEMBERS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.members.ui.newInstance(chatRoomId)
}
}
fun toMentions(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MENTIONS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.mentions.ui.newInstance(chatRoomId)
}
}
fun toPinnedMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_PINNED_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId)
}
}
fun toFavoriteMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FAVORITE_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.favoritemessages.ui.newInstance(chatRoomId)
}
}
fun toFileList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FILES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.files.ui.newInstance(chatRoomId)
}
}
}
package chat.rocket.android.chatdetails.presentation
import chat.rocket.android.chatdetails.domain.ChatDetails
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
......@@ -10,11 +11,12 @@ import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.getInfo
import chat.rocket.core.model.Room
import timber.log.Timber
import javax.inject.Inject
class ChatDetailsPresenter @Inject constructor(
private val view: ChatDetailsView,
private val navigator: ChatDetailsNavigator,
private val navigator: ChatRoomNavigator,
private val strategy: CancelStrategy,
serverInteractor: GetCurrentServerInteractor,
factory: ConnectionManagerFactory
......@@ -29,11 +31,11 @@ class ChatDetailsPresenter @Inject constructor(
val room = retryIO("getInfo($chatRoomId, null, $chatRoomType") {
client.getInfo(chatRoomId, null, roomTypeOf(chatRoomType))
}
view.displayDetails(roomToChatDetails(room))
} catch(e: Exception) {
e.message.let {
view.showMessage(it!!)
} catch(exception: Exception) {
Timber.e(exception)
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
......
package chat.rocket.android.chatdetails.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.util.extensions.addFragment
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_chat_details.*
import javax.inject.Inject
fun Context.chatDetailsIntent(
chatRoomId: String,
chatRoomType: String,
isSubscribed: Boolean = true,
isMenuDisabled: Boolean = false
): Intent {
return Intent(this, ChatDetailsActivity::class.java).apply {
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_CHAT_IS_SUBSCRIBED, isSubscribed)
putExtra(INTENT_CHAT_DISABLED_MENU, isMenuDisabled)
}
}
private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed"
private const val INTENT_CHAT_DISABLED_MENU = "is_menu_disabled"
class ChatDetailsActivity: AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_details)
setupToolbar()
val chatRoomId = intent.getStringExtra(INTENT_CHAT_ROOM_ID)
requireNotNull(chatRoomId) { "no chat_room_id provided in Intent extras" }
val chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE)
requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" }
val isSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true)
val disableMenu = intent.getBooleanExtra(INTENT_CHAT_DISABLED_MENU, false)
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_DETAILS_FRAGMENT) == null) {
addFragment(TAG_CHAT_DETAILS_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomType, isSubscribed, disableMenu)
}
}
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> =
fragmentDispatchingAndroidInjector
override fun onBackPressed() {
super.onBackPressed()
overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
}
fun setNavigationIcon(resource: Int) {
toolbar.setNavigationIcon(resource)
}
fun setToolbarTitle(title: String) {
toolbar_title.text = title
}
private fun setupToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false)
setToolbarTitle(getString(R.string.title_channel_details))
setNavigationIcon(R.drawable.ic_close_white_24dp)
toolbar.setNavigationOnClickListener { onBackPressed() }
}
}
\ No newline at end of file
package chat.rocket.android.chatdetails.ui
import DrawableHelper
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
......@@ -15,6 +16,7 @@ import chat.rocket.android.chatdetails.presentation.ChatDetailsPresenter
import chat.rocket.android.chatdetails.presentation.ChatDetailsView
import chat.rocket.android.chatdetails.viewmodel.ChatDetailsViewModel
import chat.rocket.android.chatdetails.viewmodel.ChatDetailsViewModelFactory
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
......@@ -32,7 +34,7 @@ fun newInstance(
disableMenu: Boolean
): ChatDetailsFragment {
return ChatDetailsFragment().apply {
arguments = Bundle(1).apply {
arguments = Bundle(4).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putBoolean(BUNDLE_IS_SUBSCRIBED, isSubscribed)
......@@ -48,14 +50,12 @@ private const val BUNDLE_CHAT_ROOM_TYPE = "BUNDLE_CHAT_ROOM_TYPE"
private const val BUNDLE_IS_SUBSCRIBED = "BUNDLE_IS_SUBSCRIBED"
private const val BUNDLE_DISABLE_MENU = "BUNDLE_DISABLE_MENU"
class ChatDetailsFragment: Fragment(), ChatDetailsView {
class ChatDetailsFragment : Fragment(), ChatDetailsView {
@Inject
lateinit var presenter: ChatDetailsPresenter
@Inject
lateinit var factory: ChatDetailsViewModelFactory
private var adapter: ChatDetailsAdapter? = null
private lateinit var viewModel: ChatDetailsViewModel
private var chatRoomId: String? = null
......@@ -72,13 +72,15 @@ class ChatDetailsFragment: Fragment(), ChatDetailsView {
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
isSubscribed = bundle.getBoolean(BUNDLE_IS_SUBSCRIBED)
disableMenu = bundle.getBoolean(BUNDLE_DISABLE_MENU)
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_chat_details)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
......@@ -94,9 +96,12 @@ class ChatDetailsFragment: Fragment(), ChatDetailsView {
val text = room.name
name.text = text
bindImage(chatRoomType!!)
content_topic.text = if (room.topic.isNullOrEmpty()) getString(R.string.msg_no_topic) else room.topic
content_announcement.text = if (room.announcement.isNullOrEmpty()) getString(R.string.msg_no_announcement) else room.announcement
content_description.text = if (room.description.isNullOrEmpty()) getString(R.string.msg_no_description) else room.description
content_topic.text =
if (room.topic.isNullOrEmpty()) getString(R.string.msg_no_topic) else room.topic
content_announcement.text =
if (room.announcement.isNullOrEmpty()) getString(R.string.msg_no_announcement) else room.announcement
content_description.text =
if (room.description.isNullOrEmpty()) getString(R.string.msg_no_description) else room.description
}
}
......@@ -126,15 +131,24 @@ class ChatDetailsFragment: Fragment(), ChatDetailsView {
it.addOption(getString(R.string.msg_mentions), R.drawable.ic_at_black_20dp) {
presenter.toMentions(chatRoomId!!)
}
it.addOption(getString(R.string.title_members), R.drawable.ic_people_outline_black_24dp) {
it.addOption(
getString(R.string.title_members),
R.drawable.ic_people_outline_black_24dp
) {
presenter.toMembers(chatRoomId!!)
}
}
it.addOption(getString(R.string.title_favorite_messages), R.drawable.ic_star_border_white_24dp) {
it.addOption(
getString(R.string.title_favorite_messages),
R.drawable.ic_star_border_white_24dp
) {
presenter.toFavorites(chatRoomId!!)
}
it.addOption(getString(R.string.title_pinned_messages), R.drawable.ic_action_message_pin_24dp) {
it.addOption(
getString(R.string.title_pinned_messages),
R.drawable.ic_action_message_pin_24dp
) {
presenter.toPinned(chatRoomId!!)
}
}
......@@ -178,9 +192,9 @@ class ChatDetailsFragment: Fragment(), ChatDetailsView {
layoutManager = LinearLayoutManager(it)
addItemDecoration(
DividerItemDecoration(
it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)
it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)
)
)
itemAnimator = DefaultItemAnimator()
......@@ -192,9 +206,9 @@ class ChatDetailsFragment: Fragment(), ChatDetailsView {
}
private fun setupToolbar() {
(activity as ChatDetailsActivity).let {
it.setNavigationIcon(R.drawable.ic_close_white_24dp)
it.setToolbarTitle(getString(R.string.title_channel_details))
with((activity as ChatRoomActivity)) {
hideToolbarChatRoomIcon()
showToolbarTitle(getString(R.string.title_channel_details))
}
}
}
\ No newline at end of file
package chat.rocket.android.chatroom.adapter
import androidx.recyclerview.widget.RecyclerView
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.*
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.chatroom.uimodel.AttachmentUiModel
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.chatroom.uimodel.MessageReplyUiModel
import chat.rocket.android.chatroom.uimodel.MessageUiModel
import chat.rocket.android.chatroom.uimodel.UrlPreviewUiModel
import chat.rocket.android.chatroom.uimodel.toViewType
import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.openTabbedUrl
import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.actions.Action
import chat.rocket.core.model.attachment.actions.ButtonAction
import chat.rocket.core.model.Message
import chat.rocket.core.model.isSystemMessage
import timber.log.Timber
import java.security.InvalidParameterException
......@@ -22,7 +28,8 @@ class ChatRoomAdapter(
private val roomName: String? = null,
private val actionSelectListener: OnActionSelected? = null,
private val enableActions: Boolean = true,
private val reactionListener: EmojiReactionListener? = null
private val reactionListener: EmojiReactionListener? = null,
private val navigator: ChatRoomNavigator? = null
) : RecyclerView.Adapter<BaseViewHolder<*>>() {
private val dataSet = ArrayList<BaseUiModel<*>>()
......@@ -34,7 +41,11 @@ class ChatRoomAdapter(
return when (viewType.toViewType()) {
BaseUiModel.ViewType.MESSAGE -> {
val view = parent.inflate(R.layout.item_message)
MessageViewHolder(view, actionsListener, reactionListener)
MessageViewHolder(
view,
actionsListener,
reactionListener
) { userId -> navigator?.toUserDetails(userId) }
}
BaseUiModel.ViewType.URL_PREVIEW -> {
val view = parent.inflate(R.layout.message_url_preview)
......@@ -42,11 +53,20 @@ class ChatRoomAdapter(
}
BaseUiModel.ViewType.ATTACHMENT -> {
val view = parent.inflate(R.layout.item_message_attachment)
AttachmentViewHolder(view, actionsListener, reactionListener, actionAttachmentOnClickListener)
AttachmentViewHolder(
view,
actionsListener,
reactionListener,
actionAttachmentOnClickListener
)
}
BaseUiModel.ViewType.MESSAGE_REPLY -> {
val view = parent.inflate(R.layout.item_message_reply)
MessageReplyViewHolder(view, actionsListener, reactionListener) { roomName, permalink ->
MessageReplyViewHolder(
view,
actionsListener,
reactionListener
) { roomName, permalink ->
actionSelectListener?.openDirectMessage(roomName, permalink)
}
}
......@@ -117,7 +137,8 @@ class ChatRoomAdapter(
fun prependData(dataSet: List<BaseUiModel<*>>) {
//---At first we will update all already saved elements with received updated ones
val filteredDataSet = dataSet.filter { newItem ->
val matchedIndex = this.dataSet.indexOfFirst { it.messageId == newItem.messageId && it.viewType == newItem.viewType }
val matchedIndex =
this.dataSet.indexOfFirst { it.messageId == newItem.messageId && it.viewType == newItem.viewType }
if (matchedIndex > -1) {
this.dataSet[matchedIndex] = newItem
notifyItemChanged(matchedIndex)
......@@ -266,7 +287,12 @@ class ChatRoomAdapter(
fun showMessageInfo(id: String)
fun citeMessage(roomName: String, roomType: String, messageId: String, mentionAuthor: Boolean)
fun citeMessage(
roomName: String,
roomType: String,
messageId: String,
mentionAuthor: Boolean
)
fun copyMessage(id: String)
......
package chat.rocket.android.chatroom.adapter
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.Spannable
......@@ -11,7 +10,6 @@ import androidx.core.view.isVisible
import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.MessageUiModel
import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.userdetails.ui.userDetailsIntent
import chat.rocket.core.model.isSystemMessage
import com.bumptech.glide.load.resource.gif.GifDrawable
import kotlinx.android.synthetic.main.avatar.view.*
......@@ -20,7 +18,8 @@ import kotlinx.android.synthetic.main.item_message.view.*
class MessageViewHolder(
itemView: View,
listener: ActionsListener,
reactionListener: EmojiReactionListener? = null
reactionListener: EmojiReactionListener? = null,
private val avatarListener: (String) -> Unit
) : BaseViewHolder<MessageUiModel>(itemView, listener, reactionListener), Drawable.Callback {
init {
......@@ -73,24 +72,14 @@ class MessageViewHolder(
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)
data.message.sender?.id?.let { userId ->
avatarListener(userId)
}
}
}
}
private fun toUserDetails(context: Context, userId: String?, subscriptionId: String) {
userId?.let { context.startActivity(context.userDetailsIntent(it, subscriptionId)) }
}
override fun unscheduleDrawable(who: Drawable?, what: Runnable?) {
with(itemView) {
text_content.removeCallbacks(what)
......
......@@ -5,7 +5,6 @@ import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.ui.ChatRoomFragment
import chat.rocket.android.chatrooms.adapter.RoomUiModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.ChatRoomDao
import chat.rocket.android.db.DatabaseManager
......@@ -16,16 +15,11 @@ import chat.rocket.android.server.domain.SettingsRepository
import chat.rocket.android.server.domain.TokenRepository
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
import javax.inject.Named
@Module
class ChatRoomFragmentModule {
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun chatRoomView(frag: ChatRoomFragment): ChatRoomView {
......@@ -38,12 +32,6 @@ class ChatRoomFragmentModule {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
@Provides
@PerFragment
fun provideChatRoomDao(manager: DatabaseManager): ChatRoomDao = manager.chatRoomDao()
......@@ -71,6 +59,12 @@ class ChatRoomFragmentModule {
@Named("currentServer") serverUrl: String,
permissionsInteractor: PermissionsInteractor
): RoomUiModelMapper {
return RoomUiModelMapper(context, repository.get(serverUrl), userInteractor, serverUrl, permissionsInteractor)
return RoomUiModelMapper(
context,
repository.get(serverUrl),
userInteractor,
serverUrl,
permissionsInteractor
)
}
}
package chat.rocket.android.chatroom.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class ChatRoomModule {
@Provides
@PerActivity
fun provideChatRoomNavigator(activity: ChatRoomActivity) = ChatRoomNavigator(activity)
@Provides
@PerActivity
fun provideJob() = Job()
@Provides
@PerActivity
fun provideLifecycleOwner(activity: ChatRoomActivity): LifecycleOwner = activity
@Provides
@PerActivity
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module abstract class MessageServiceProvider {
@ContributesAndroidInjector(modules = [AppModule::class])
abstract fun provideMessageService(): MessageService
}
\ No newline at end of file
package chat.rocket.android.chatroom.presentation
import chat.rocket.android.R
import chat.rocket.android.chatdetails.ui.chatDetailsIntent
import chat.rocket.android.chatdetails.ui.TAG_CHAT_DETAILS_FRAGMENT
import chat.rocket.android.chatinformation.ui.messageInformationIntent
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.ui.chatRoomIntent
......@@ -11,23 +11,92 @@ import chat.rocket.android.members.ui.TAG_MEMBERS_FRAGMENT
import chat.rocket.android.mentions.ui.TAG_MENTIONS_FRAGMENT
import chat.rocket.android.pinnedmessages.ui.TAG_PINNED_MESSAGES_FRAGMENT
import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.android.userdetails.ui.TAG_USER_DETAILS_FRAGMENT
import chat.rocket.android.util.extensions.addFragmentBackStack
class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
fun toUserDetails(userId: String) {
activity.addFragmentBackStack(TAG_USER_DETAILS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.userdetails.ui.newInstance(userId)
}
}
fun toChatRoom(
chatRoomId: String,
chatRoomName: String,
chatRoomType: String,
isReadOnly: Boolean,
chatRoomLastSeen: Long,
isSubscribed: Boolean,
isCreator: Boolean,
isFavorite: Boolean
) {
activity.startActivity(
activity.chatRoomIntent(
chatRoomId,
chatRoomName,
chatRoomType,
isReadOnly,
chatRoomLastSeen,
isSubscribed,
isCreator,
isFavorite
)
)
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
}
fun toChatDetails(
chatRoomId: String,
chatRoomType: String,
isChatRoomSubscribed: Boolean,
isMenuDisabled: Boolean
) {
activity.startActivity(
activity.chatDetailsIntent(
activity.addFragmentBackStack(TAG_CHAT_DETAILS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.chatdetails.ui.newInstance(
chatRoomId,
chatRoomType,
isChatRoomSubscribed,
isMenuDisabled
)
)
}
}
fun toMembersList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MEMBERS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.members.ui.newInstance(chatRoomId)
}
}
fun toMemberDetails(userId: String) {
activity.addFragmentBackStack(TAG_USER_DETAILS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.userdetails.ui.newInstance(userId)
}
}
fun toMentions(chatRoomId: String) {
activity.addFragmentBackStack(TAG_MENTIONS_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.mentions.ui.newInstance(chatRoomId)
}
}
fun toPinnedMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_PINNED_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId)
}
}
fun toFavoriteMessageList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FAVORITE_MESSAGES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.favoritemessages.ui.newInstance(chatRoomId)
}
}
fun toFileList(chatRoomId: String) {
activity.addFragmentBackStack(TAG_FILES_FRAGMENT, R.id.fragment_container) {
chat.rocket.android.files.ui.newInstance(chatRoomId)
}
}
fun toNewServer() {
......
......@@ -316,16 +316,18 @@ class ChatRoomPresenter @Inject constructor(
fun sendMessage(chatRoomId: String, text: String, messageId: String?) {
launchUI(strategy) {
try {
view.disableSendMessageButton()
// ignore message for now, will receive it on the stream
if (messageId == null) {
val id = UUID.randomUUID().toString()
val username = userHelper.username()
val user = userHelper.user()
val newMessage = Message(
id = id,
roomId = chatRoomId,
message = text,
timestamp = Instant.now().toEpochMilli(),
sender = SimpleUser(null, username, username),
sender = SimpleUser(user?.id, user?.username ?: username, user?.name),
attachments = null,
avatar = currentServer.avatarUrl(username ?: ""),
channels = null,
......@@ -1293,9 +1295,7 @@ class ChatRoomPresenter @Inject constructor(
* @param unfinishedMessage The unfinished message to save.
*/
fun saveDraftMessage(unfinishedMessage: String) {
if (unfinishedMessage.isNotBlank()) {
localRepository.save(draftKey, unfinishedMessage)
}
localRepository.save(draftKey, unfinishedMessage)
}
fun clearDraftMessage() {
......
package chat.rocket.android.chatroom.ui
import android.app.Activity
import android.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
......@@ -40,6 +40,7 @@ import chat.rocket.android.chatroom.adapter.EmojiSuggestionsAdapter
import chat.rocket.android.chatroom.adapter.PEOPLE
import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter
import chat.rocket.android.chatroom.adapter.RoomSuggestionsAdapter
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.ui.bottomsheet.MessageActionsBottomSheet
......@@ -68,9 +69,9 @@ import chat.rocket.android.helper.MessageParser
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.clearLightStatusBar
import chat.rocket.android.util.extensions.fadeIn
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.inflate
import chat.rocket.android.util.extensions.isNotNullNorEmpty
......@@ -85,6 +86,7 @@ import dagger.android.support.AndroidSupportInjection
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.emoji_image_row_item.view.*
import kotlinx.android.synthetic.main.emoji_row_item.view.*
import kotlinx.android.synthetic.main.fragment_chat_room.*
......@@ -145,13 +147,14 @@ internal const val MENU_ACTION_SHOW_DETAILS = 2
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiReactionListener,
ChatRoomAdapter.OnActionSelected, Drawable.Callback {
@Inject
lateinit var presenter: ChatRoomPresenter
@Inject
lateinit var parser: MessageParser
@Inject
lateinit var analyticsManager: AnalyticsManager
@Inject
lateinit var navigator: ChatRoomNavigator
private lateinit var adapter: ChatRoomAdapter
internal lateinit var chatRoomId: String
private lateinit var chatRoomName: String
......@@ -196,7 +199,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private var verticalScrollOffset = AtomicInteger(0)
private val dialogView by lazy { View.inflate(context, R.layout.file_attachments_dialog, null) }
internal val alertDialog by lazy { AlertDialog.Builder(activity).setView(dialogView).create() }
internal val alertDialog by lazy { activity?.let { AlertDialog.Builder(it).setView(dialogView).create() } }
internal val imagePreview by lazy { dialogView.findViewById<ImageView>(R.id.image_preview) }
internal val sendButton by lazy { dialogView.findViewById<android.widget.Button>(R.id.button_send) }
internal val cancelButton by lazy { dialogView.findViewById<android.widget.Button>(R.id.button_cancel) }
......@@ -256,7 +259,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_fab.hide()
newMessageCount = 0
} else {
if (dy < 0 && !button_fab.isVisible) {
if (dy < 0 && isAdded && !button_fab.isVisible) {
button_fab.show()
if (newMessageCount != 0) text_count.isVisible = true
}
......@@ -284,7 +287,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, reactionListener = this)
adapter = ChatRoomAdapter(chatRoomId, chatRoomType, chatRoomName, this, reactionListener = this, navigator = navigator)
}
override fun onCreateView(
......@@ -308,6 +311,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
showToolbarChatRoomIcon(chatRoomType)
}
getDraftMessage()
subscribeComposeTextMessage()
analyticsManager.logScreenView(ScreenViewEvent.ChatRoom)
}
......@@ -341,10 +345,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_CODE_FOR_PERFORM_CAMERA -> takenPhotoUri?.let { uri ->
uri.getBitmpap(requireContext())?.let { bitmap ->
presenter.uploadImage(chatRoomId, "image/png", uri, bitmap, "")
}
REQUEST_CODE_FOR_PERFORM_CAMERA -> takenPhotoUri?.let {
showFileAttachmentDialog(it)
}
REQUEST_CODE_FOR_PERFORM_SAF -> resultData?.data?.let {
showFileAttachmentDialog(it)
......@@ -844,7 +846,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
true
)
subscribeComposeTextMessage()
emojiKeyboardPopup = EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container))
emojiKeyboardPopup.listener = this
......@@ -996,12 +997,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
private fun subscribeComposeTextMessage() {
val editTextObservable = text_message.asObservable()
compositeDisposable.addAll(
subscribeComposeButtons(editTextObservable),
subscribeComposeTypingStatus(editTextObservable)
)
text_message.asObservable().let {
compositeDisposable.addAll(
subscribeComposeButtons(it),
subscribeComposeTypingStatus(it)
)
}
}
private fun unsubscribeComposeTextMessage() {
......@@ -1057,7 +1058,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
private fun setupToolbar(toolbarTitle: String) {
(activity as ChatRoomActivity).showToolbarTitle(toolbarTitle)
with(activity as ChatRoomActivity) {
this.clearLightStatusBar()
this.showToolbarTitle(toolbarTitle)
toolbar.isVisible = true
}
}
override fun unscheduleDrawable(who: Drawable?, what: Runnable?) {
......@@ -1114,13 +1119,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
val builder = AlertDialog.Builder(it)
builder.setTitle(it.getString(R.string.msg_delete_message))
.setMessage(it.getString(R.string.msg_delete_description))
.setPositiveButton(it.getString(R.string.msg_ok)) { _, _ ->
.setPositiveButton(it.getString(android.R.string.ok)) { _, _ ->
presenter.deleteMessage(
roomId,
id
)
}
.setNegativeButton(it.getString(R.string.msg_cancel)) { _, _ -> }
.setNegativeButton(it.getString(android.R.string.cancel)) { _, _ -> }
.show()
}
}
......
......@@ -75,10 +75,10 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
(citation ?: "") + description.text.toString()
)
}
alertDialog.dismiss()
alertDialog?.dismiss()
}
cancelButton.setOnClickListener { alertDialog.dismiss() }
alertDialog.show()
cancelButton.setOnClickListener { alertDialog?.dismiss() }
alertDialog?.show()
}
fun ChatRoomFragment.showDrawAttachmentDialog(byteArray: ByteArray) {
......@@ -92,9 +92,9 @@ fun ChatRoomFragment.showDrawAttachmentDialog(byteArray: ByteArray) {
byteArray,
(citation ?: "") + description.text.toString()
)
alertDialog.dismiss()
alertDialog?.dismiss()
}
cancelButton.setOnClickListener { alertDialog.dismiss() }
alertDialog.show()
}
\ No newline at end of file
cancelButton.setOnClickListener { alertDialog?.dismiss() }
alertDialog?.show()
}
......@@ -108,7 +108,7 @@ private fun ChatRoomFragment.setupDetailsMenuItem(menu: Menu) {
Menu.NONE,
MENU_ACTION_SHOW_DETAILS,
Menu.NONE,
"Channel Details"
R.string.title_channel_details
).setIcon(R.drawable.ic_info_outline_white_24dp)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package chat.rocket.android.chatrooms.presentation
import chat.rocket.android.R
import chat.rocket.android.chatrooms.adapter.model.RoomUiModel
import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.model.ChatRoomEntity
......@@ -116,6 +117,7 @@ class ChatRoomsPresenter @Inject constructor(
retryIO("createDirectMessage($name)") {
withTimeout(10000) {
createDirectMessage(name)
FetchChatRoomsInteractor(client, dbManager).refreshChatRooms()
}
}
val fromTo = mutableListOf(myself.id, id).apply {
......
package chat.rocket.android.chatrooms.ui
import android.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.app.ProgressDialog
import android.os.Bundle
import android.os.Handler
......@@ -236,14 +236,16 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
)
}
AlertDialog.Builder(context)
.setTitle(R.string.dialog_sort_title)
.setView(dialogLayout)
.setPositiveButton(R.string.msg_sort) { dialog, _ ->
invalidateQueryOnSearch()
updateSort()
dialog.dismiss()
}.show()
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)
......
......@@ -12,8 +12,6 @@ import chat.rocket.android.authentication.signup.di.SignupFragmentProvider
import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatdetails.di.ChatDetailsFragmentProvider
import chat.rocket.android.chatdetails.di.ChatDetailsModule
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatinformation.di.MessageInfoFragmentProvider
import chat.rocket.android.chatinformation.ui.MessageInfoActivity
import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
......@@ -38,14 +36,14 @@ import chat.rocket.android.server.ui.ChangeServerActivity
import chat.rocket.android.settings.di.SettingsFragmentProvider
import chat.rocket.android.settings.password.di.PasswordFragmentProvider
import chat.rocket.android.settings.password.ui.PasswordActivity
import chat.rocket.android.userdetails.di.UserDetailsModule
import chat.rocket.android.userdetails.ui.UserDetailsActivity
import chat.rocket.android.userdetails.di.UserDetailsFragmentProvider
import chat.rocket.android.webview.adminpanel.di.AdminPanelWebViewFragmentProvider
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
modules = [AuthenticationModule::class,
......@@ -77,17 +75,9 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(
modules = [
ChatRoomModule::class,
ChatRoomFragmentProvider::class
]
)
abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity
@ContributesAndroidInjector(
modules = [
ChatDetailsModule::class,
modules = [ChatRoomModule::class,
ChatRoomFragmentProvider::class,
UserDetailsFragmentProvider::class,
ChatDetailsFragmentProvider::class,
MembersFragmentProvider::class,
MentionsFragmentProvider::class,
......@@ -96,7 +86,7 @@ abstract class ActivityBuilder {
FilesFragmentProvider::class
]
)
abstract fun bindChatDetailsActivity(): ChatDetailsActivity
abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity
@ContributesAndroidInjector(modules = [PasswordFragmentProvider::class])
......@@ -113,8 +103,4 @@ abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(modules = [DrawModule::class])
abstract fun bindDrawingActivity(): DrawingActivity
@PerActivity
@ContributesAndroidInjector(modules = [UserDetailsModule::class])
abstract fun bindUserDetailsActivity(): UserDetailsActivity
}
......@@ -102,6 +102,18 @@ class DatabaseManager(val context: Application, val serverUrl: String) {
}
}
suspend fun insertOrReplaceRoom(chatRoomEntity: ChatRoomEntity) {
retryDB("insertOrReplace($chatRoomEntity)") {
chatRoomDao().insertOrReplace(chatRoomEntity)
}
}
suspend fun getUser(id: String) = withContext(dbManagerContext) {
retryDB("getUser($id)") {
userDao().getUser(id)
}
}
fun processUsersBatch(users: List<User>) {
launch(dbManagerContext) {
val list = ArrayList<BaseUserEntity>(users.size)
......
package chat.rocket.android.favoritemessages.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.DatabaseManagerFactory
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import chat.rocket.android.favoritemessages.ui.FavoriteMessagesFragment
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
import javax.inject.Named
@Module
class FavoriteMessagesFragmentModule {
......@@ -21,20 +14,4 @@ class FavoriteMessagesFragmentModule {
fun provideFavoriteMessagesView(frag: FavoriteMessagesFragment): FavoriteMessagesView {
return frag
}
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: FavoriteMessagesFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
......@@ -12,7 +12,6 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
......@@ -116,9 +115,6 @@ class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
}
private fun setupToolbar() {
(activity as ChatDetailsActivity).let {
it.setToolbarTitle(getString(R.string.title_favorite_messages))
it.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
(activity as ChatRoomActivity).showToolbarTitle(getString(R.string.title_favorite_messages))
}
}
\ No newline at end of file
package chat.rocket.android.files.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.files.presentation.FilesView
import chat.rocket.android.files.ui.FilesFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class FilesFragmentModule {
......@@ -17,20 +14,4 @@ class FilesFragmentModule {
fun provideFilesView(frag: FilesFragment): FilesView {
return frag
}
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: FilesFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
......@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.files.adapter.FilesAdapter
import chat.rocket.android.files.presentation.FilesPresenter
import chat.rocket.android.files.presentation.FilesView
......@@ -152,9 +152,11 @@ class FilesFragment : Fragment(), FilesView {
}
private fun setupToolbar(totalFiles: Long) {
(activity as ChatDetailsActivity).let {
it.setToolbarTitle(getString(R.string.title_files_total, totalFiles))
it.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
(activity as ChatRoomActivity).showToolbarTitle(
(getString(
R.string.title_files_total,
totalFiles
))
)
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@ package chat.rocket.android.main.ui
import DrawableHelper
import android.app.Activity
import android.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.app.ProgressDialog
import android.os.Bundle
import androidx.annotation.IdRes
......@@ -13,6 +13,7 @@ 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
......@@ -37,6 +38,9 @@ import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar.*
import kotlinx.android.synthetic.main.nav_header.view.*
import javax.inject.Inject
import android.app.NotificationManager
import android.content.Context
private const val CURRENT_STATE = "current_state"
......@@ -89,6 +93,9 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
presenter.toChatList(chatRoomId)
isFragmentAdded = true
}
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
notificationManager.cancelAll()
}
override fun onDestroy() {
......@@ -98,6 +105,21 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
}
}
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 supportFragmentInjector(): AndroidInjector<Fragment> =
......@@ -180,7 +202,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
BuildConfig.RECOMMENDED_SERVER_VERSION
)
)
.setPositiveButton(R.string.msg_ok, null)
.setPositiveButton(android.R.string.ok, null)
.create()
.show()
}
......@@ -194,7 +216,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
)
)
.setOnDismissListener { presenter.logout() }
.setPositiveButton(R.string.msg_ok, null)
.setPositiveButton(android.R.string.ok, null)
.create()
.show()
}
......
package chat.rocket.android.members.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.members.presentation.MembersNavigator
import chat.rocket.android.members.presentation.MembersView
import chat.rocket.android.members.ui.MembersFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class MembersFragmentModule {
......@@ -19,24 +14,4 @@ class MembersFragmentModule {
fun membersView(frag: MembersFragment): MembersView {
return frag
}
@Provides
@PerFragment
fun provideChatRoomNavigator(activity: ChatDetailsActivity) = MembersNavigator(activity)
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: MembersFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
package chat.rocket.android.members.di
import chat.rocket.android.members.ui.MembersFragment
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.members.ui.MemberBottomSheetFragment
import chat.rocket.android.members.ui.MembersFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
......@@ -12,9 +11,4 @@ abstract class MembersFragmentProvider {
@ContributesAndroidInjector(modules = [MembersFragmentModule::class])
@PerFragment
abstract fun provideMembersFragment(): MembersFragment
@ContributesAndroidInjector()
@PerFragment
abstract fun provideMemberBottomSheetFragment(): MemberBottomSheetFragment
}
\ No newline at end of file
package chat.rocket.android.members.presentation
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.userdetails.ui.userDetailsIntent
class MembersNavigator(internal val activity: ChatDetailsActivity) {
fun toMemberDetails(userId: String) {
activity.apply {
startActivity(this.userDetailsIntent(userId, ""))
}
}
}
package chat.rocket.android.members.presentation
import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.members.uimodel.MemberUiModelMapper
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extension.launchUI
import chat.rocket.android.util.retryDB
import chat.rocket.common.RocketChatException
import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
......@@ -18,7 +18,7 @@ import javax.inject.Named
class MembersPresenter @Inject constructor(
private val view: MembersView,
private val navigator: MembersNavigator,
private val navigator: ChatRoomNavigator,
private val dbManager: DatabaseManager,
@Named("currentServer") private val currentServer: String,
private val strategy: CancelStrategy,
......
package chat.rocket.android.members.ui
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.textContent
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_member_bottom_sheet.*
import javax.inject.Inject
fun newInstance(
avatarUri: String,
realName: String,
username: String,
email: String,
utcOffset: String
): BottomSheetDialogFragment {
return MemberBottomSheetFragment().apply {
arguments = Bundle(1).apply {
putString(BUNDLE_AVATAR_URI, avatarUri)
putString(BUNDLE_REAL_NAME, realName)
putString(BUNDLE_USERNAME, username)
putString(BUNDLE_EMAIL, email)
putString(BUNDLE_UTC_OFFSET, utcOffset)
}
}
}
internal const val TAG_MEMBER_BOTTOM_SHEET_FRAGMENT = "MemberBottomSheetFragment"
private const val BUNDLE_AVATAR_URI = "avatar_uri"
private const val BUNDLE_REAL_NAME = "real_name"
private const val BUNDLE_USERNAME = "username"
private const val BUNDLE_EMAIL = "email"
private const val BUNDLE_UTC_OFFSET = "utc_offset"
class MemberBottomSheetFragment : BottomSheetDialogFragment() {
@Inject
lateinit var analyticsManager: AnalyticsManager
private lateinit var avatarUri: String
private lateinit var realName: String
private lateinit var username: String
private lateinit var email: String
private lateinit var utcOffset: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) {
avatarUri = bundle.getString(BUNDLE_AVATAR_URI)
realName = bundle.getString(BUNDLE_REAL_NAME)
username = bundle.getString(BUNDLE_USERNAME)
email = bundle.getString(BUNDLE_EMAIL)
utcOffset = bundle.getString(BUNDLE_UTC_OFFSET)
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
inflater.inflate(R.layout.fragment_member_bottom_sheet, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
showMemberDetails()
analyticsManager.logScreenView(ScreenViewEvent.MemberBottomSheet)
}
private fun showMemberDetails() {
image_bottom_sheet_avatar.setImageURI(avatarUri)
text_bottom_sheet_member_name.content = realName
text_bottom_sheet_member_username.content = username
if (email.isNotEmpty()) {
text_member_email_address.textContent = email
} else {
text_email_address.isVisible = false
text_member_email_address.isVisible = false
}
if (utcOffset.isNotEmpty()) {
text_member_utc.content = utcOffset
} else {
text_utc.isVisible = false
text_member_utc.isVisible = false
}
}
}
\ No newline at end of file
......@@ -12,16 +12,18 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.members.adapter.MembersAdapter
import chat.rocket.android.members.presentation.MembersPresenter
import chat.rocket.android.members.presentation.MembersView
import chat.rocket.android.members.uimodel.MemberUiModel
import chat.rocket.android.util.extensions.clearLightStatusBar
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.fragment_members.*
import javax.inject.Inject
......@@ -120,20 +122,26 @@ class MembersFragment : Fragment(), MembersView {
private fun setupRecyclerView() {
ui {
recycler_view.layoutManager = linearLayoutManager
recycler_view.addItemDecoration(DividerItemDecoration(it, DividerItemDecoration.HORIZONTAL))
recycler_view.layoutManager = LinearLayoutManager(context)
recycler_view.addItemDecoration(
DividerItemDecoration(
it,
DividerItemDecoration.HORIZONTAL
)
)
recycler_view.adapter = adapter
}
}
private fun setupToolbar(totalMembers: Long? = null) {
(activity as ChatDetailsActivity).let {
with((activity as ChatRoomActivity)) {
if (totalMembers != null) {
it.setToolbarTitle(getString(R.string.title_counted_members, totalMembers))
showToolbarTitle((getString(R.string.title_counted_members, totalMembers)))
} else {
it.setToolbarTitle(getString(R.string.title_members))
showToolbarTitle((getString(R.string.title_members)))
}
it.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
this.clearLightStatusBar()
toolbar.isVisible = true
}
}
}
\ No newline at end of file
package chat.rocket.android.mentions.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.mentions.presentention.MentionsView
import chat.rocket.android.mentions.ui.MentionsFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class MentionsFragmentModule {
......@@ -17,20 +14,4 @@ class MentionsFragmentModule {
fun provideMentionsView(frag: MentionsFragment): MentionsView {
return frag
}
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: MentionsFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
......@@ -12,8 +12,8 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.mentions.presentention.MentionsPresenter
......@@ -37,13 +37,12 @@ internal const val TAG_MENTIONS_FRAGMENT = "MentionsFragment"
private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
class MentionsFragment : Fragment(), MentionsView {
private lateinit var chatRoomId: String
private val adapter = ChatRoomAdapter(enableActions = false)
@Inject
lateinit var presenter: MentionsPresenter
@Inject
lateinit var analyticsManager: AnalyticsManager
private lateinit var chatRoomId: String
private val adapter = ChatRoomAdapter(enableActions = false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -122,9 +121,6 @@ class MentionsFragment : Fragment(), MentionsView {
}
private fun setupToolbar() {
(activity as ChatDetailsActivity).let {
it.setToolbarTitle(getString(R.string.msg_mentions))
it.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
(activity as ChatRoomActivity).showToolbarTitle((getString(R.string.msg_mentions)))
}
}
\ No newline at end of file
package chat.rocket.android.pinnedmessages.di
import androidx.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import chat.rocket.android.pinnedmessages.ui.PinnedMessagesFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
class PinnedMessagesFragmentModule {
......@@ -17,20 +14,4 @@ class PinnedMessagesFragmentModule {
fun providePinnedMessagesView(frag: PinnedMessagesFragment): PinnedMessagesView {
return frag
}
@Provides
@PerFragment
fun provideJob() = Job()
@Provides
@PerFragment
fun provideLifecycleOwner(frag: PinnedMessagesFragment): LifecycleOwner {
return frag
}
@Provides
@PerFragment
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
\ No newline at end of file
......@@ -12,14 +12,12 @@ import androidx.recyclerview.widget.RecyclerView
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatdetails.ui.ChatDetailsActivity
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.uimodel.BaseUiModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesPresenter
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import chat.rocket.android.server.domain.AnalyticsTrackingInteractor
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
......@@ -123,9 +121,6 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
}
private fun setupToolbar() {
(activity as ChatDetailsActivity).let {
it.setToolbarTitle(getString(R.string.title_pinned_messages))
it.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
}
(activity as ChatRoomActivity).showToolbarTitle((getString(R.string.title_pinned_messages)))
}
}
\ No newline at end of file
......@@ -38,13 +38,17 @@ class PreferencesFragment : Fragment(), PreferencesView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
setupListeners()
presenter.loadAnalyticsTrackingInformation()
analyticsManager.logScreenView(ScreenViewEvent.Preferences)
}
override fun onResume() {
setupToolbar()
super.onResume()
}
override fun setupAnalyticsTrackingView(isAnalyticsTrackingEnabled: Boolean) {
if (BuildConfig.FLAVOR == "foss") {
switch_analytics_tracking.isChecked = false
......
......@@ -82,7 +82,7 @@ class ProfilePresenter @Inject constructor(
view.showLoading()
try {
user?.id?.let { id ->
retryIO { client.updateProfile(id, email, name, username) }
retryIO { client.updateProfile(userId = id, email = email, name = name, username = username) }
view.showProfileUpdateSuccessfullyMessage()
view.showProfile(
serverUrl.avatarUrl(user.username ?: ""),
......@@ -115,7 +115,7 @@ class ProfilePresenter @Inject constructor(
uriInteractor.getInputStream(uri)
}
}
user?.username?.let { view.reloadUserAvatar(it) }
user?.username?.let { view.reloadUserAvatar(serverUrl.avatarUrl(it)) }
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
......@@ -143,7 +143,7 @@ class ProfilePresenter @Inject constructor(
}
}
user?.username?.let { view.reloadUserAvatar(it) }
user?.username?.let { view.reloadUserAvatar(serverUrl.avatarUrl(it)) }
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
......@@ -163,7 +163,7 @@ class ProfilePresenter @Inject constructor(
user?.id?.let { id ->
retryIO { client.resetAvatar(id) }
}
user?.username?.let { view.reloadUserAvatar(it) }
user?.username?.let { view.reloadUserAvatar(serverUrl.avatarUrl(it)) }
} catch (exception: RocketChatException) {
exception.message?.let {
view.showMessage(it)
......@@ -198,4 +198,4 @@ class ProfilePresenter @Inject constructor(
}
}
}
}
\ No newline at end of file
}
......@@ -2,7 +2,7 @@ package chat.rocket.android.profile.ui
import DrawableHelper
import android.app.Activity
import android.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
......@@ -293,17 +293,14 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
fun showDeleteAccountDialog() {
val passwordEditText = EditText(context)
passwordEditText.hint = getString(R.string.msg_password)
val builder = AlertDialog.Builder(context)
builder.setTitle(R.string.title_are_you_sure)
.setView(passwordEditText)
.setPositiveButton(R.string.action_delete_account) { _, _ ->
presenter.deleteAccount(passwordEditText.text.toString())
}
.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.cancel() }
.create()
.show()
context?.let {
val passwordEText = EditText(context);
val mDialogView = LayoutInflater.from(it).inflate(R.layout.item_account_delete, null)
val mBuilder = AlertDialog.Builder(it)
mBuilder.setView(mDialogView).setPositiveButton(R.string.action_delete_account) { _, _ ->
presenter.deleteAccount(passwordEText.text.toString())
}.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.cancel() }.create().show()
}
}
}
......@@ -2,6 +2,7 @@ package chat.rocket.android.settings.ui
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
......@@ -23,6 +24,7 @@ import chat.rocket.android.settings.password.ui.PasswordActivity
import chat.rocket.android.settings.presentation.SettingsView
import chat.rocket.android.util.extensions.addFragmentBackStack
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.webview.ui.webViewIntent
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_settings.*
......@@ -73,20 +75,23 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
resources.getStringArray(R.array.settings_actions)[1] ->
activity?.startActivity(Intent(activity, PasswordActivity::class.java))
resources.getStringArray(R.array.settings_actions)[2] -> shareApp()
// TODO (https://github.com/RocketChat/Rocket.Chat.Android/pull/1918)
resources.getStringArray(R.array.settings_actions)[2] -> showToast("Coming soon")
resources.getStringArray(R.array.settings_actions)[3] -> showAppOnStore()
resources.getStringArray(R.array.settings_actions)[3] -> shareApp()
resources.getStringArray(R.array.settings_actions)[4] -> contactSupport()
resources.getStringArray(R.array.settings_actions)[4] -> showAppOnStore()
resources.getStringArray(R.array.settings_actions)[5] -> activity?.startActivity(
resources.getStringArray(R.array.settings_actions)[5] -> contactSupport()
resources.getStringArray(R.array.settings_actions)[6] -> activity?.startActivity(
context?.webViewIntent(
getString(R.string.license_url),
getString(R.string.title_licence)
)
)
resources.getStringArray(R.array.settings_actions)[6] -> {
resources.getStringArray(R.array.settings_actions)[7] -> {
(activity as AppCompatActivity).addFragmentBackStack(
TAG_ABOUT_FRAGMENT,
R.id.fragment_container
......@@ -124,11 +129,12 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
}
private fun contactSupport() {
with(Intent(Intent.ACTION_SEND)) {
type = "message/rfc822"
putExtra(Intent.EXTRA_EMAIL, arrayOf("support@rocket.chat"))
putExtra(Intent.EXTRA_SUBJECT, getString(R.string.msg_android_app_support))
putExtra(Intent.EXTRA_TEXT, getDeviceAndAppInformation())
val uriText = "mailto:${"support@rocket.chat"}" +
"?subject=" + Uri.encode(getString(R.string.msg_android_app_support)) +
"&body=" + Uri.encode(getDeviceAndAppInformation())
with(Intent(Intent.ACTION_SENDTO)) {
data = uriText.toUri()
try {
startActivity(Intent.createChooser(this, getString(R.string.msg_send_email)))
} catch (ex: ActivityNotFoundException) {
......
package chat.rocket.android.userdetails.di
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.userdetails.presentation.UserDetailsView
import chat.rocket.android.userdetails.ui.UserDetailsFragment
import dagger.Module
import dagger.Provides
@Module
class UserDetailsFragmentModule {
@Provides
@PerFragment
fun provideUserDetailsView(frag: UserDetailsFragment): UserDetailsView = frag
}
\ No newline at end of file
package chat.rocket.android.userdetails.di
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.userdetails.ui.UserDetailsFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class UserDetailsFragmentProvider {
@ContributesAndroidInjector(modules = [UserDetailsFragmentModule::class])
@PerFragment
abstract fun provideUserDetailsFragment(): UserDetailsFragment
}
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.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.db.model.ChatRoomEntity
import chat.rocket.android.db.model.UserEntity
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.common.model.userStatusOf
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.createDirectMessage
import chat.rocket.core.model.ChatRoom
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.DefaultDispatcher
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import javax.inject.Inject
......@@ -23,141 +23,98 @@ class UserDetailsPresenter @Inject constructor(
private val view: UserDetailsView,
private val dbManager: DatabaseManager,
private val strategy: CancelStrategy,
private val navigator: ChatRoomNavigator,
serverInteractor: GetConnectingServerInteractor,
factory: ConnectionManagerFactory
) {
private var currentServer = serverInteractor.get()!!
private val manager = factory.create(currentServer)
private val client = manager.client
private val interactor = FetchChatRoomsInteractor(client,dbManager)
private val interactor = FetchChatRoomsInteractor(client, dbManager)
private lateinit var userEntity: UserEntity
fun loadUserDetails(userId: String) {
launchUI(strategy) {
try {
val user = withContext(CommonPool) {
dbManager.userDao().getUser(id = userId)
}
user?.let { u ->
val openedChatRooms = chatRoomByName(name = u.name)
val avatarUrl = u.username?.let { currentServer.avatarUrl(avatar = it) }
val chatRoom: ChatRoom? = openedChatRooms.firstOrNull()
view.showLoading()
dbManager.getUser(userId)?.let {
userEntity = it
val avatarUrl =
userEntity.username?.let { currentServer.avatarUrl(avatar = it) }
val username = userEntity.username
val name = userEntity.name
val utcOffset =
userEntity.utcOffset // TODO Convert UTC and display like the mockup
view.showUserDetails(
avatarUrl = avatarUrl,
username = u.username,
name = u.name,
utcOffset = u.utcOffset,
status = u.status,
chatRoom = chatRoom
)
if (avatarUrl != null && username != null && name != null && utcOffset != null) {
view.showUserDetails(
avatarUrl = avatarUrl,
name = name,
username = username,
status = userEntity.status,
utcOffset = utcOffset.toString()
)
} else {
throw Exception()
}
}
} catch (ex: Exception) {
Timber.e(ex)
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
fun createDirectMessage(id: String) = launchUI(strategy) {
try {
val result = retryIO("createDirectMessage($id") {
client.createDirectMessage(username = id)
}
fun createDirectMessage(username: String) {
launchUI(strategy) {
try {
view.showLoading()
interactor.refreshChatRooms()
withContext(DefaultDispatcher) {
val directMessage = retryIO("createDirectMessage($username") {
client.createDirectMessage(username)
}
val userEntity = withContext(CommonPool) {
dbManager.userDao().getUser(id = id)
}
val chatRoomEntity = ChatRoomEntity(
id = directMessage.id,
name = userEntity.username ?: userEntity.name.orEmpty(),
description = null,
type = RoomType.DIRECT_MESSAGE,
fullname = userEntity.name,
subscriptionId = "",
updatedAt = directMessage.updatedAt
)
if (userEntity != null) {
val chatRoom = ChatRoom(
id = result.id,
type = roomTypeOf(RoomType.DIRECT_MESSAGE),
name = userEntity.username ?: userEntity.name.orEmpty(),
fullName = userEntity.name,
favorite = false,
open = false,
alert = false,
status = userStatusOf(userEntity.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 = result.updatedAt,
user = null
)
dbManager.insertOrReplaceRoom(chatRoomEntity)
withContext(CommonPool + strategy.jobs) {
dbManager.chatRoomDao().insertOrReplace(chatRoom = ChatRoomEntity(
id = chatRoom.id,
name = chatRoom.name,
description = chatRoom.description,
type = chatRoom.type.toString(),
fullname = chatRoom.fullName,
subscriptionId = chatRoom.subscriptionId,
updatedAt = chatRoom.updatedAt
))
}
interactor.refreshChatRooms()
view.toDirectMessage(chatRoom = chatRoom)
}
} catch (ex: Exception) {
Timber.e(ex)
view.onOpenDirectMessageError()
}
}
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
)
navigator.toChatRoom(
chatRoomId = chatRoomEntity.id,
chatRoomName = chatRoomEntity.name,
chatRoomType = chatRoomEntity.type,
isReadOnly = false,
chatRoomLastSeen = -1,
isSubscribed = chatRoomEntity.open,
isCreator = true,
isFavorite = false
)
}
} catch (ex: Exception) {
Timber.e(ex)
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
} finally {
view.hideLoading()
}
}
}
......
package chat.rocket.android.userdetails.presentation
import chat.rocket.core.model.ChatRoom
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
interface UserDetailsView {
interface UserDetailsView : LoadingView, MessageView {
fun showUserDetails(avatarUrl: String?, username: String?, name: String?, utcOffset: Float?, status: String, chatRoom: ChatRoom?)
fun toDirectMessage(chatRoom: ChatRoom)
fun onOpenDirectMessageError()
/**
* Shows user detail.
*
* @param avatarUrl The user avatar URL.
* @param name The user's name.
* @param username The user's username.
* @param status The user's status.
* @param utcOffset The user's UTC offset.
*/
fun showUserDetails(
avatarUrl: String,
name: String,
username: String,
status: String,
utcOffset: String
)
}
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.android.util.retryIO
import chat.rocket.common.model.roomTypeOf
import chat.rocket.core.internal.rest.createDirectMessage
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.engine.DiskCacheStrategy
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 com.google.android.material.snackbar.Snackbar
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
private lateinit var userId: String
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_details)
setupToolbar()
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()
try {
launch(UI) {
val image = withContext(CommonPool) {
try {
val requestOptions = RequestOptions()
.priority(Priority.IMMEDIATE)
.transforms(CenterInside(), FitCenter())
return@withContext GlideApp.with(this@UserDetailsActivity)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.load(avatarUrl)
.apply(requestOptions)
.submit()
.get()
} catch (ex: Exception) {
Timber.e(ex)
return@withContext null
} finally {
showLoadingView(false)
}
}
image?.let {
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(image)
.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 {
if (chatRoom == null) {
presenter.createDirectMessage(id = userId)
} else {
toDirectMessage(chatRoom)
}
}
image_view_message.setOnClickListener {
if (chatRoom == null) {
presenter.createDirectMessage(id = userId)
} else {
toDirectMessage(chatRoom)
}
}
} catch (ex: Exception) {
Timber.e(ex)
}
}
private fun showLoadingView(show: Boolean) {
runOnUiThread {
group_user_details.isVisible = !show
view_loading.isVisible = show
}
}
override fun onOpenDirectMessageError() {
Snackbar.make(root_layout, R.string.error_opening_dm, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.retry) {
presenter.createDirectMessage(userId)
}.show()
}
override fun toDirectMessage(chatRoom: ChatRoom) {
finish()
if (chatRoom.subscriptionId.isEmpty() || chatRoom.subscriptionId != subscriptionId) {
startActivity(
chatRoomIntent(
chatRoomId = chatRoom.id,
chatRoomName = chatRoom.name,
chatRoomType = chatRoom.type.toString(),
isReadOnly = chatRoom.readonly.orFalse(),
chatRoomLastSeen = chatRoom.lastSeen ?: 0,
isSubscribed = chatRoom.open,
isCreator = false,
isFavorite = chatRoom.favorite
)
)
}
}
}
package chat.rocket.android.userdetails.ui
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager
import chat.rocket.android.analytics.event.ScreenViewEvent
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.userdetails.presentation.UserDetailsPresenter
import chat.rocket.android.userdetails.presentation.UserDetailsView
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setLightStatusBar
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import com.bumptech.glide.Glide
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import dagger.android.support.AndroidSupportInjection
import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.android.synthetic.main.app_bar_chat_room.*
import kotlinx.android.synthetic.main.fragment_user_details.*
import javax.inject.Inject
fun newInstance(userId: String): Fragment {
return UserDetailsFragment().apply {
arguments = Bundle(1).apply {
putString(BUNDLE_USER_ID, userId)
}
}
}
internal const val TAG_USER_DETAILS_FRAGMENT = "UserDetailsFragment"
private const val BUNDLE_USER_ID = "user_id"
class UserDetailsFragment : Fragment(), UserDetailsView {
@Inject
lateinit var presenter: UserDetailsPresenter
@Inject
lateinit var analyticsManager: AnalyticsManager
private lateinit var userId: String
private val handler = Handler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) {
userId = bundle.getString(BUNDLE_USER_ID)
} else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_user_details)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
setupListeners()
presenter.loadUserDetails(userId)
analyticsManager.logScreenView(ScreenViewEvent.UserDetails)
}
override fun onDestroyView() {
handler.removeCallbacksAndMessages(null)
super.onDestroyView()
}
override fun showUserDetails(
avatarUrl: String,
name: String,
username: String,
status: String,
utcOffset: String
) {
val requestBuilder = Glide.with(this).load(avatarUrl)
requestBuilder.apply(
RequestOptions.bitmapTransform(MultiTransformation(BlurTransformation(), CenterCrop()))
).into(image_blur)
requestBuilder.apply(RequestOptions.bitmapTransform(RoundedCorners(14)))
.into(image_avatar)
text_name.text = name
text_username.text = username
text_description_status.text = status.substring(0, 1).toUpperCase() + status.substring(1)
text_description_timezone.text = utcOffset
// We should also setup the user details listeners.
text_message.setOnClickListener { presenter.createDirectMessage(username) }
}
override fun showLoading() {
group_user_details.isVisible = false
view_loading.isVisible = true
}
override fun hideLoading() {
group_user_details.isVisible = true
view_loading.isVisible = false
}
override fun showMessage(resId: Int) {
ui { showToast(resId) }
}
override fun showMessage(message: String) {
ui { showToast(message) }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
private fun setupToolbar() {
handler.postDelayed({
with(activity as ChatRoomActivity) {
view?.let {
setLightStatusBar(
it,
ContextCompat.getColor(this, R.color.whitesmoke)
)
}
toolbar.isVisible = false
}
}, 400)
}
private fun setupListeners() {
image_arrow_back.setOnClickListener { activity?.onBackPressed() }
}
}
\ No newline at end of file
......@@ -7,8 +7,6 @@ import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.internal.http.HttpHeaders
import okhttp3.internal.platform.Platform
import okhttp3.internal.platform.Platform.INFO
import okio.Buffer
import okio.GzipSource
import java.io.EOFException
......
......@@ -11,6 +11,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import androidx.annotation.MenuRes
import androidx.annotation.StringRes
......@@ -22,12 +23,16 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import chat.rocket.android.R
fun FragmentActivity.setLightStatusBar(view: View) {
fun FragmentActivity.setLightStatusBar(view: View, @ColorInt color: Int = 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
var flags = view.systemUiVisibility
flags = flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
view.systemUiVisibility = flags
window.statusBarColor = ContextCompat.getColor(this, R.color.colorWhite)
window.statusBarColor = if (color == 0) {
ContextCompat.getColor(this, R.color.colorWhite)
} else {
color
}
}
}
......
......@@ -3,12 +3,12 @@
android:shape="rectangle">
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp" />
<solid android:color="@android:color/white" />
<solid android:color="@color/color_white" />
<corners android:radius="25px" />
<corners android:radius="6dp" />
</shape>
<vector android:height="24dp" android:viewportHeight="100"
android:viewportWidth="100" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ededed" android:pathData="M50,100q-24.66,0 -49.32,0c-0.57,0 -0.68,-0.11 -0.68,-0.68Q0,50 0,0.68C0,0.11 0.11,0 0.68,0Q50,0 99.32,0c0.57,0 0.68,0.11 0.68,0.68q0,49.32 0,98.64c0,0.57 -0.11,0.68 -0.68,0.68Q74.66,100 50,100Z"/>
<path android:fillColor="#afafae" android:pathData="M49.42,90C41.72,90 34,90 26.34,90a13.82,13.82 0,0 1,-8.55 -2.75A11.18,11.18 0,0 1,13.22 79a46.76,46.76 0,0 1,3 -21.44,17.06 17.06,0 0,1 6.56,-8.48 15.67,15.67 0,0 1,7.3 -2.28,4.52 4.52,0 0,1 2.84,1c1.62,1 3.18,2.14 4.86,3.05a23.24,23.24 0,0 0,20.34 1.5A25.39,25.39 0,0 0,65 48.51c2.81,-2.26 5.65,-1.76 8.61,-0.71 3.73,1.32 6.24,4 8.11,7.39A35.18,35.18 0,0 1,85.31 67,54.2 54.2,0 0,1 86,77.31a12.47,12.47 0,0 1,-4 9.28,12.65 12.65,0 0,1 -7.33,3.22c-3.9,0.4 -7.82,0.13 -11.73,0.17C58.41,90 53.92,90 49.42,90Z"/>
<path android:fillColor="#afafae" android:pathData="M69.35,30.28c0.4,10.36 -8.74,20 -19.89,19.93s-19.92,-9.58 -19.89,-20 8.81,-19.93 20,-19.88C60.64,10.35 69.77,19.87 69.35,30.28Z"/>
</vector>
......@@ -3,6 +3,7 @@
android:height="24dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#1d74f5"
android:fillType="evenOdd"
......
<?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:orientation="vertical"
tools:context=".chatdetails.ui.ChatDetailsActivity">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar_chat_details" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</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:id="@+id/root_layout"
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>
<?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:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="@drawable/ic_close_white_24dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="@dimen/text_view_drawable_padding"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
tools:text="@string/title_channel_details" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
\ No newline at end of file
......@@ -10,6 +10,7 @@
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:background="@drawable/bg_empty_user_avatar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
......
......@@ -98,7 +98,7 @@
app:layout_constraintEnd_toStartOf="@id/button_send"
android:layout_margin="16dp"
style="@style/Base.Widget.AppCompat.Button.Borderless"
android:text="@string/msg_cancel" />
android:text="@android:string/cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/member_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
tools:context=".members.ui.MemberBottomSheetFragment">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_bottom_sheet_avatar"
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/name_and_username_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorBackgroundMemberContainer"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
app:layout_constraintBottom_toBottomOf="@+id/image_bottom_sheet_avatar"
app:layout_constraintLeft_toLeftOf="parent">
<TextView
android:id="@+id/text_bottom_sheet_member_name"
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
tools:text="Ronald Perkins" />
<TextView
android:id="@+id/text_bottom_sheet_member_username"
style="@style/Sender.Name.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="@color/colorWhite"
tools:text="\@ronaldPerkins" />
</LinearLayout>
<TextView
android:id="@+id/text_email_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/msg_email_address"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_bottom_sheet_avatar" />
<TextView
android:id="@+id/text_member_email_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:textColor="@color/colorPrimaryText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_email_address"
tools:text="ronald@perkins.com" />
<TextView
android:id="@+id/text_utc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/msg_utc_offset"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_member_email_address" />
<TextView
android:id="@+id/text_member_utc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:textColor="@color/colorPrimaryText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_utc"
tools:text="+01:00" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white">
<ImageView
android:id="@+id/image_blur"
android:layout_width="match_parent"
android:layout_height="120dp" />
<ImageView
android:id="@+id/image_arrow_back"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="@dimen/screen_edge_left_and_right_margins"
android:src="@drawable/ic_arrow_back_white_24dp"
android:tint="@color/color_black"
app:layout_constraintStart_toStartOf="@+id/image_blur"
app:layout_constraintTop_toTopOf="@+id/image_blur" />
<ImageView
android:id="@+id/image_avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/bg_border_user_details_avatar"
app:layout_constraintBottom_toBottomOf="@+id/image_blur"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_blur"
tools:srcCompat="@tools:sample/avatars[6]" />
<TextView
android:id="@+id/text_name"
style="@style/UserDetails.TextView.Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_avatar"
tools:text="Karem Flusser" />
<TextView
android:id="@+id/text_username"
style="@style/UserDetails.TextView.Username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_name"
tools:text="karem.flusser" />
<TextView
android:id="@+id/text_message"
style="@style/UserDetails.TextView.Actions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:drawableTop="@drawable/ic_message_24dp"
android:text="@string/msg_message"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_username" />
<TextView
android:id="@+id/text_title_status"
style="@style/UserDetails.TextView.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="20dp"
android:text="@string/status"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_message" />
<TextView
android:id="@+id/text_description_status"
style="@style/UserDetails.TextView.Description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_title_status"
tools:text="Online" />
<TextView
android:id="@+id/text_title_timezone"
style="@style/UserDetails.TextView.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:text="@string/timezone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_description_status" />
<TextView
android:id="@+id/text_description_timezone"
style="@style/UserDetails.TextView.Description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_title_timezone"
tools:text="(UTC-2) 11:08 AM" />
<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" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_user_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image_blur, image_avatar, text_name, text_username, text_message, text_title_status, text_description_status, text_title_timezone, text_description_timezone" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<?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">
<TextView
android:id="@+id/text_reset_password"
style="@style/Authentication.TextView.Headline"
android:text="@string/title_are_you_sure"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/text_delete_account_password"
style="@style/Authentication.EditText.Border"
android:layout_marginTop="16dp"
android:drawableStart="@drawable/ic_key_black_20dp"
android:hint="@string/msg_password"
android:imeOptions="actionDone"
android:inputType="textPassword"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_reset_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -34,8 +34,8 @@
android:id="@+id/day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/Message.DayMarker"
tools:text="Wednesday" />
......@@ -51,7 +51,7 @@
layout="@layout/avatar"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/message_header" />
<LinearLayout
......@@ -95,17 +95,16 @@
android:layout_marginStart="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toRightOf="@+id/layout_avatar"
app:layout_constraintStart_toEndOf="@+id/layout_avatar"
app:layout_constraintTop_toBottomOf="@+id/day_marker_layout">
<TextView
android:id="@+id/text_sender"
style="@style/Sender.Name.TextView"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:maxLength="22"
tools:text="User Name with long name" />
<TextView
......@@ -123,7 +122,7 @@
android:layout_marginStart="4dp"
android:text="@string/msg_edited"
android:textStyle="italic"
android:visibility="gone"
android:visibility="invisible"
tools:visibility="visible" />
<ImageView
......@@ -133,7 +132,7 @@
android:layout_gravity="center_vertical"
android:layout_marginStart="4dp"
android:layout_marginTop="2dp"
android:visibility="gone"
android:visibility="invisible"
app:srcCompat="@drawable/ic_action_message_star_24dp"
tools:visibility="visible" />
......@@ -141,7 +140,7 @@
android:id="@+id/read_receipt_view"
android:layout_width="24dp"
android:layout_height="24dp"
android:visibility="gone"
android:visibility="invisible"
app:srcCompat="@drawable/ic_check_unread_24dp"
tools:visibility="visible" />
</LinearLayout>
......
......@@ -21,6 +21,7 @@
android:id="@+id/image_avatar"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/bg_empty_user_avatar"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
......
......@@ -14,15 +14,18 @@
<string name="title_members">Benutzer</string>
<string name="title_counted_members">Benutzer (%d)</string>
<string name="title_settings">Einstellungen</string>
<string name="title_preferences">Einstellungen</string>
<string name="title_preferences">Eigenschaften</string>
<string name="title_change_password">Ändere Passwort</string>
<string name="title_rate_us">Bewerten Sie uns</string>
<string name="title_admin_panel">Administrationsmenü</string>
<string name="title_password">Ändere Passwort</string>
<string name="title_update_profile">Update Profil</string>
<string name="title_about">Über</string>
<string name="title_create_channel">Erstelle Raum</string>
<string name="title_are_you_sure">Bist du sicher?</string>
<string name="title_are_you_sure">Sind Sie sicher?</string>
<string name="title_channel_details">Channel-Details</string>
<string name="title_topic">Thema</string>
<string name="title_announcement">Ankündigung</string>
......@@ -49,24 +52,25 @@
<string name="action_busy">Beschäftigt</string>
<string name="action_invisible">Unsichtbar</string>
<string name="action_drawing">Zeichnung</string>
<string name="action_save_to_gallery">Sichern in Gallerie</string>
<string name="action_save_to_gallery">Sichern in Galerie</string>
<string name="action_select_photo_from_gallery">Foto aus der Galerie auswählen</string>
<string name="action_take_a_photo">Mach ein Foto</string>
<string name="action_take_a_photo">Ein Foto aufnehmen und senden</string>
<string name="action_reset_avatar">Avatar zurücksetzen</string>
<string name="action_connect_server">Verbinden Sie sich mit einem Server</string>
<string name="action_join_community">Trete der Community bei</string>
<string name="action_create_server">Erstellen Sie einen neuen Server</string>
<string name="action_join_community">Der Community beitreten</string>
<string name="action_create_server">Einen eigenen Server erstellen</string>
<string name="action_register">Registrieren</string>
<string name="action_confirm">Bestätigen</string>
<string name="action_delete_account">Konto löschen</string>
<!-- Settings List -->
<string-array name="settings_actions">
<item name="item_preferences">Einstellungen</item>
<item name="item_password">Ändere das Passwort</item>
<item name="item_share_app">App teilen</item>
<item name="item_preferences">Eigenschaften</item>
<item name="item_password">Passwort ändern</item>
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_share_app">Link zur App teilen</item>
<item name="item_rate_us">Bewerten Sie uns</item>
<item name="item_contact_us">Kontaktiere uns</item>
<item name="item_contact_us">Kontaktieren Sie uns</item>
<item name="item_licence">Lizenz</item>
<item name="item_about">Über</item>
</string-array>
......@@ -106,7 +110,9 @@
<string name="msg_content_description_log_in_using_gitlab">Login mit Gitlab</string>
<string name="msg_content_description_log_in_using_wordpress">Login mit WordPress</string>
<string name="msg_content_description_send_message">Sende Nachricht</string>
<string name="msg_content_description_show_more_login_options">Show more login options</string>
<string name="msg_content_description_show_more_login_options">Zeige mehr Login-Optionen</string>
<string name="msg_content_description_show_attachment_options">Zeige Anhang Optionen</string>
<string name="msg_you">Du</string>
<string name="msg_unknown">Unbekannt</string>
......@@ -122,17 +128,16 @@
<string name="msg_preview_photo">Bild</string>
<string name="msg_preview_file">Datei</string>
<string name="msg_no_messages_yet">Noch keine Nachrichten</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">Server Version veraltet. Bitte kontaktieren Sie ihren Server Administrator.</string>
<string name="msg_ver_not_recommended">Die Server Version scheint älter als die empfolene Version %1$s zu sein.\nSie können sich trotzdem einloggen, aber es kann zu einem unerwartetem Verhalten kommen.</string>
<string name="msg_ver_not_minimum">Die Server Version scheint älter als die minimale Version %1$s zu sein.\nBitte updaten Sie Ihren Server um sich einloggen zu können!</string>
<string name="msg_no_chat_title">Keine Chat Nachrichten</string>
<string name="msg_no_chat_description">Starte die Konversation um Ihre \nNachrichten hier zu sehen.</string>
<string name="msg_cancel">ABBRUCH</string>
<string name="msg_http_insecure">Bei HTTP verbinden Sie sich usicher zu einem Server. Wir empfehlen HTTPS zu benutzen.</string>
<string name="msg_error_checking_server_version">Ein Fehler ist aufgetreten beim prüfen der Server Version, bitte versuchen Sie es noch einmal</string>
<string name="msg_invalid_server_protocol">Das ausgewählte Protokoll wird vom Server nicht akzeptiert, versuchen Sie HTTPS</string>
<string name="msg_image_saved_successfully">Bild wurde in der Gallerie gespeichert</string>
<string name="msg_image_saved_successfully">Bild wurde in der Galerie gespeichert</string>
<string name="msg_image_saved_failed">Bild speichern fehlgeschlagen</string>
<string name="msg_edited">(bearbeitet)</string>
<string name="msg_and">\u0020und\u0020</string>
......@@ -145,29 +150,31 @@
<string name="msg_file_description">Datei Beschreibung</string>
<string name="msg_send">Sende</string>
<string name="msg_sent_attachment">Sende Anhang</string>
<string name="msg_welcome_to_rocket_chat">Willkommen bei Rocket.Chat</string>
<string name="msg_team_communication">Team Communication</string> <!-- TODO Translate -->
<string name="msg_login_with_email">Einloggen mit <b>e-mail</b></string>
<string name="msg_create_account">Ein Konto erstellen</string>
<string name="msg_continue_with_facebook">Weitermachen mit <b>Facebook</b></string>
<string name="msg_continue_with_github">Weitermachen mit <b>Github</b></string>
<string name="msg_continue_with_google">Weitermachen mit <b>Google</b></string>
<string name="msg_continue_with_linkedin">Weitermachen mit <b>Linkedin</b></string>
<string name="msg_continue_with_gitlab">Weitermachen mit <b>GitLab</b></string>
<string name="msg_continue_with_wordpress">Weitermachen mit <b>WordPress</b></string>
<string name="msg_welcome_to_rocket_chat">Wilkommen bei Rocket.Chat</string>
<string name="msg_team_communication">Team Kommunikation</string>
<string name="msg_login_with_email">Mit <b>e-mail</b> einloggen</string>
<string name="msg_create_account">Einen Account erstellen</string>
<string name="msg_continue_with_facebook">Mit <b>Facebook</b> einloggen</string>
<string name="msg_continue_with_github">Mit <b>Github</b> einloggen</string>
<string name="msg_continue_with_google">Mit <b>Google</b> einloggen</string>
<string name="msg_continue_with_linkedin">Mit <b>Linkedin</b> einloggen</string>
<string name="msg_continue_with_gitlab">Mit <b>GitLab</b> einloggen</string>
<string name="msg_continue_with_wordpress">Mit <b>WordPress</b> einloggen</string>
<string name="msg_two_factor_authentication">Zwei-Faktor-Authentifizierung</string>
<string name="msg__your_2fa_code">Wie lautet Ihr 2FA-Code?</string>
<string name="msg__your_2fa_code">Wie lautet Ihr F2A Code?</string>
<string name="msg_muted_on_this_channel">Sie sind auf diesem Kanal stummgeschaltet</string>
<string name="msg_no_topic">Kein Thema hinzugefügt</string>
<string name="msg_no_announcement">Keine Ankündigung hinzugefügt</string>
<string name="msg_no_description">Keine Beschreibung hinzugefügt</string>
<string name="msg_unable_to_update_password">Unable to update password. Error message: %1$s</string> <!-- TODO - Add proper translation -->
<string name="msg_password_updated_successfully">Password updated successfully</string> <!-- TODO - Add proper translation -->
<string name="msg_unable_to_update_password">Änderung des Passworts nicht möglich. Fehlermeldung: %1$s</string>
<string name="msg_password_updated_successfully">Passwort erfolgreich geändert</string>
<plurals name="msg_reacted_with_">
<item quantity="one">%1$ s reagierte mit %2$s</item>
<item quantity="other">%1$s reagierte mit %2$s</item>
</plurals>
<!-- Create channel messages -->
<string name="msg_private_channel">Privat</string>
<string name="msg_public_channel">Öffentlich</string>
......@@ -182,17 +189,19 @@
<string name="msg_message_copied">Nachricht kopiert</string>
<string name="msg_delete_message">Lösche Nachricht</string>
<string name="msg_delete_description">Sind Sie sicher, dass Sie diese Nachricht löschen wollen?</string>
<string name="msg_view_more">mehr sehen</string>
<string name="msg_view_less">weniger anzeigen</string>
<string name="msg_permalink_copied">Permalink kopiert</string>
<string name="msg_view_more">Zeige mehr</string>
<string name="msg_view_less">Zeige weniger</string>
<string name="msg_permalink_copied">Permanenter Link kopiert</string>
<string name="msg_send_email">E-Mail senden</string>
<string name="msg_android_app_support">Android App-Unterstützung</string>
<!-- Preferences messages -->
<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_do_not_send_analytics_tracking">Do not send anonymous statics to help improving this app</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">Not applicable since it is a FOSS version</string>
<string name="msg_analytics_tracking">Daten für Analysezwecke</string>
<string name="msg_send_analytics_tracking">Anonyme Statistiken senden um diese App weiter zu verbessern</string>
<string name="msg_do_not_send_analytics_tracking">KEINE anonymen Statistiken senden um diese App weiter zu verbessern</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">Nicht anwendbar, da es sich um eine FOSS version handelt</string>
<!-- System messages -->
<string name="message_room_name_changed">Raum Namen geändert zu: %1$s von %2$s</string>
......@@ -303,7 +312,7 @@
<!-- Emoji message-->
<string name="msg_no_recent_emoji">Keine letzten Emojis</string>
<string name="alert_title_default_skin_tone">Standart Hautton</string>
<string name="alert_title_default_skin_tone">Standard Hautton</string>
<!-- Sorting and grouping-->
<string name="msg_sort">Sortiere</string>
......@@ -329,15 +338,14 @@
<string name="notif_success_sending">Nachricht gesendet nach %1$s!</string>
<string name="read_by">Gelesen von</string>
<string name="message_information_title">Nachricht Information</string>
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string>
<string name="message_room_changed_privacy">Raumtyp geändert zu: %1$s durch %2$s</string>
<!-- User Details -->
<string name="message">Botschaft</string>
<string name="timezone">Zeitzone</string>
<string name="error_opening_dm">Etwas ist schiefgegangen, als wir dieses Gespräch erstellt haben…</string>
<string name="retry">Wiederholen</string>
<!-- Report -->
<string name="submit">einreichen</string>
<string name="submit">Senden</string>
<string name="required">*erforderlich</string>
<string name="report_sent">Ihr Bericht wurde gesendet!</string>
</resources>
<resources>
<!-- Titles -->
<string name="title_sign_in_your_server">Inicia sesión en tu servidor</string>
<string name="title_log_in">Iniciar sesión</string>
......@@ -63,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation -->
<item name="item_password">Change password</item> <!-- TODO Add translation -->
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_share_app">Share app</item> <!-- TODO Add translation -->
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation -->
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation -->
......@@ -103,7 +105,7 @@
<string name="msg_content_description_log_in_using_meteor">Inicia sesión usando Meteor</string>
<string name="msg_content_description_log_in_using_twitter">Inicia sesión usando Twitter</string>
<string name="msg_content_description_log_in_using_gitlab">Inicia sesión usando Gitlab</string>
<string name="msg_content_description_log_in_using_wordpress">Login using WordPress</string> <!-- TODO Translate-->
<string name="msg_content_description_log_in_using_wordpress">Inicia sesión usando WordPress</string>
<string name="msg_content_description_send_message">Enviar mensaje</string>
<string name="msg_content_description_show_more_login_options">Show more login options</string> <!-- TODO Translate-->
<string name="msg_content_description_show_attachment_options">Mostrar opciones de archivo adjunto</string>
......@@ -119,14 +121,13 @@
<string name="msg_preview_photo">Foto</string>
<string name="msg_preview_file">Fichero</string>
<string name="msg_no_messages_yet">Aún no hay mensajes</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">Versión del servidor actualizada. Póngase en contacto con el administrador del servidor para actualizar la versión del servidor y continuar.</string>
<string name="msg_ver_not_recommended">
Parece que la versión de tu servidor está por debajo de la versión recomendada %1$s.\nAún puede iniciar sesión, pero puede experimentar comportamientos inesperados.</string>
<string name="msg_ver_not_minimum">
Parece que la versión del servidor está por debajo de la versión mínima requerida %1$s.\nActualice su servidor para iniciar sesión!
</string>
<string name="msg_cancel">CANCELAR</string>
<string name="msg_http_insecure">Al usar HTTP, te estás conectando a un servidor inseguro. No te recomendamos que hagas eso.</string>
<string name="msg_error_checking_server_version">Se ha producido un error al verificar la versión de su servidor, intente de nuevo</string>
<string name="msg_invalid_server_protocol">El protocolo seleccionado no es aceptado por este servidor, intente usar HTTPS</string>
......@@ -336,10 +337,7 @@
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<!-- User Details -->
<string name="message">Message</string> <!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string> <!-- TODO - Add proper translation -->
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string> <!-- TODO - Add proper translation -->
<string name="retry">Retry</string> <!-- TODO - Add proper translation -->
<!-- Report -->
<string name="submit">Submit</string> <!--TODO - Add proper translation-->
......
<resources>
<!-- Titles -->
<string name="title_sign_in_your_server">به سرور خود متصل شوید</string>
<string name="title_log_in">ورود</string>
<string name="title_share_the_app">به اشتراک‌گذاری اپلیکیشن</string>
<string name="title_register_username">ثبت شناسه‌ی کاربری</string>
<string name="title_reset_password">تعویض گذرواژه</string>
<string name="title_sign_up">ثبت‌‌نام کنید</string>
<string name="title_authentication">تایید هویت</string>
<string name="title_legal_terms">شروط حقوقی</string>
<string name="title_chats">گفت‌وگوها</string>
<string name="title_profile">نمایه</string>
<string name="title_members">اعضاء</string>
<string name="title_counted_members">(%d) اعضاء</string>
<string name="title_settings">تنظیمات</string>
<string name="title_preferences">ترجیحات</string>
<string name="title_change_password">تغییر گذرواژه</string>
<string name="title_rate_us">به ما امتیاز دهید</string>
<string name="title_admin_panel">Admin panel</string> <!-- TODO Add translation -->
<string name="title_password">تغییر گذرواژه</string>
<string name="title_update_profile">به روزرسانی نمایه</string>
<string name="title_about">درباره</string>
<string name="title_create_channel">ایجاد کانال</string>
<string name="title_licence">مجوز</string>
<string name="title_are_you_sure">آیا مطمئن هستید؟</string>
<string name="title_channel_details">جزئیات کانال</string>
<string name="title_topic">موضوع</string>
<string name="title_announcement">اعلان</string>
<string name="title_description">توضیح</string>
<!-- Actions -->
<string name="action_connect">متصل</string>
<string name="action_use_this_username">از این شناسه‌ی کاربری استفاده کنید</string>
<string name="action_terms_of_service">شرایط خدمات رسانی</string>
<string name="action_privacy_policy">سیاست حفظ جریم خصوصی</string>
<string name="action_search">جست‌وجو</string>
<string name="action_update">به روزرسانی</string>
<string name="action_settings">تنظیمات</string>
<string name="action_create_channel">ایجاد کانال</string>
<string name="action_create">ایجاد</string>
<string name="action_logout">خروج</string>
<string name="action_attach_a_files">ضمیمه کردن پرونده</string>
<string name="action_confirm_password">موافقت با تغییر گذرواژه</string>
<string name="action_join_chat">به گفت‌وگو بپیوندید</string>
<string name="action_add_account">اضافه کردن حساب کاربری</string>
<string name="action_online">آنلاین</string>
<string name="action_away">Away</string> <!-- TODO Add translation -->
<string name="action_busy">مشغول</string>
<string name="action_invisible">نامرئی</string>
<string name="action_drawing">کشیدن</string>
<string name="action_save_to_gallery">ذخیره در آلبوم</string>
<string name="action_select_photo_from_gallery">انتخاب عکس از آلبوم</string>
<string name="action_take_a_photo">گرفتن عکس</string>
<string name="action_reset_avatar">تعویض تصویر نمایه</string>
<string name="action_connect_server">اتصال به سرور</string>
<string name="action_join_community">به انجمن بپیوندید</string>
<string name="action_create_server">ایجاد سرور جدید</string>
<string name="action_register">ثبت‌نام</string>
<string name="action_confirm">تایید</string>
<string name="action_delete_account">حذف حساب کاربری</string>
<!-- Settings List -->
<string-array name="settings_actions">
<item name="item_preferences">ترجیحات</item>
<item name="item_password">تغییر گذرواژه</item>
<item name="item_share_app">به اشتراک‌گذاری اپلیکیشن</item>
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_rate_us">به ما امتیاز دهید</item>
<item name="item_contact_us">تماس با ما</item>
<item name="item_licence">مجوز</item>
<item name="item_about">درباره</item>
</string-array>
<!-- Regular information messages -->
<string name="msg_generic_error">متاسفانه مشکلی رخ داد، لطفا دوباره تلاش کنید</string>
<string name="msg_no_data_to_display">اطلاعاتی برای نمایش وجود نداد</string>
<string name="msg_check_this_out">اینجا را ببینید</string>
<string name="msg_share_using">تغییر کاربری</string>
<string name="msg_profile_update_successfully">نمایه با موفقیت به روزرسانی شد</string>
<string name="msg_username">شناسه‌ی کاربری</string>
<string name="msg_username_or_email">حساب‌کاربری یا ایمیل</string>
<string name="msg_password">گذرواژه</string>
<string name="msg_name">نام</string>
<string name="msg_email">ایمیل</string>
<string name="msg_avatar_url">URL تصویر نمایه</string>
<string name="msg_or_continue_using_social_accounts">یا به استفاده از سرورهای اجتماعی ادامه دهید</string>
<string name="msg_new_user">%1$s کاربر جدید?</string>
<string name="msg_forgot__your_password">گذرواژه‌تان را فراموش کردید؟</string>
<string name="msg_reset">راه اندازی مجدد</string>
<string name="msg_check_your_email_to_reset_your_password">ایمیل فرستاده شد. صندوق ورودی خود را برای تعویض گذرواژه چک کنید</string>
<string name="msg_invalid_email">لطفا یک ایمیل معتبر را بنویسید</string>
<string name="msg_new_user_agreement">By proceeding you are agreeing to our\n%1$s and %2$s</string> <!-- TODO Add translation -->
<string name="msg_yesterday">دیروز</string>
<string name="msg_today">امروز</string>
<string name="msg_message">پیام</string>
<string name="msg_this_room_is_read_only">این اتاق فقط خواندنی است</string>
<string name="msg_invalid_2fa_code">Invalid 2FA Code</string> <!-- TODO Add translation -->
<string name="msg_invalid_file">پرونده‌ی نامعتبر</string>
<string name="msg_invalid_server_url">سرور نامعتبر URL</string>
<string name="msg_content_description_log_in_using_facebook">با فیس‌بوک وارد شوید</string>
<string name="msg_content_description_log_in_using_github">با گیت‌هاب وارد شوید</string>
<string name="msg_content_description_log_in_using_google">با گوگل وارد شوید</string>
<string name="msg_content_description_log_in_using_linkedin">با لینکدین وارد شوید</string>
<string name="msg_content_description_log_in_using_meteor">با میتور وارد شوید</string>
<string name="msg_content_description_log_in_using_twitter">با توییتر وارد شوید</string>
<string name="msg_content_description_log_in_using_gitlab">با گیت‌لب وارد شوید</string>
<string name="msg_content_description_log_in_using_wordpress">با وردپرس وارد شوید</string>
<string name="msg_content_description_send_message">ارسال پیام</string>
<string name="msg_content_description_show_more_login_options">نمایش گزینه‌های ورود بیشتر</string>
<string name="msg_content_description_show_attachment_options">نمایش گزینه‌های ضمیمه</string>
<string name="msg_you">شما</string>
<string name="msg_unknown">ناشناس</string>
<string name="msg_email_address">آدرس ایمیل</string>
<string name="msg_utc_offset">UTC offset</string> <!-- TODO Add translation -->
<string name="msg_new_password">گذرواژه‌ی جدید را وارد کنید</string>
<string name="msg_confirm_password">گذرواژه‌ی جدید را تصدیق کنید</string>
<string name="msg_channel_name">نام کانال</string>
<string name="msg_search">جست‌وجو</string>
<string name="msg_unread_messages">پیام خوانده‌نشده</string>
<string name="msg_preview_video">ویدیو</string>
<string name="msg_preview_audio">صدا</string>
<string name="msg_preview_photo">تصویر</string>
<string name="msg_preview_file">پرونده</string>
<string name="msg_no_messages_yet">هنوز پیامی ندارید</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">نسخه‌ی سرور منسوخ شده است. لطفا برای ادامه دادن با مدیر سرور خود تماس بگیرید تا سرور را به روز کند.</string>
<string name="msg_ver_not_recommended">
Looks like your server version is below the recommended version %1$s.\nYou can still login but you may experience unexpected behaviors.</string>
<string name="msg_ver_not_minimum"> <!-- TODO Add translation -->
Looks like your server version is below the minimum required version %1$s.\nPlease upgrade your server to login!
</string> <!-- TODO Add translation -->
<string name="msg_no_chat_title">هیچ پیام گفت‌وگویی نیست</string>
<string name="msg_no_chat_description">لطفا گفت‌و گو را شروع کنید تا پیام‌ها را اینجا\messages ببینید.</string> <!-- TODO Add translation -->
<string name="msg_http_insecure">زمانی که از HTTP استفاده می‌کنید در حال وصل شدن به یک سرور ناامن هستید. ما این کار را پیشنهاد نمی‌کنیم.</string>
<string name="msg_error_checking_server_version">موقع چک کردن نسخه‌ی سرور شما اشکالی رخ داد. لطفا دوباره تلاش کنید</string>
<string name="msg_invalid_server_protocol">پروتکل انتخاب شده برای این سرور قابل‌قبول نیست. لطفا از HTTPS استفاده کنید</string>
<string name="msg_image_saved_successfully">تصویر در آلبوم ذخیره شد</string>
<string name="msg_image_saved_failed">ذخیره‌ی تصویر انجام نشد</string>
<string name="msg_edited">(ویرایش‌شده)</string>
<string name="msg_and">\u0020و\u0020</string>
<string name="msg_is_typing">\u0020is در حال تایپ…</string> <!-- TODO Add translation -->
<string name="msg_are_typing">\u0020are درحال تایپ…</string> <!-- TODO Add translation -->
<string name="msg_several_users_are_typing">چند کاربر در حال تایپ کردن…</string>
<string name="msg_no_search_found">نتیجه‌ای یافت نشد</string>
<string name="msg_log_out">در حال خروج…</string>
<string name="msg_upload_file">بارگذاری پرونده</string>
<string name="msg_file_description">توضیحات پرونده</string>
<string name="msg_send">ارسال</string>
<string name="msg_sent_attachment">ارسال ضمیمه</string>
<string name="msg_welcome_to_rocket_chat">به پیام‌رسان راکت خوش آمدید!</string>
<string name="msg_team_communication">ارتباط تیمی</string>
<string name="msg_login_with_email">ورود با <b>ایمیل</b></string>
<string name="msg_create_account">ایجاد حساب کاربری</string>
<string name="msg_continue_with_facebook">ادامه دادن با <b>فیس‌بوک</b></string>
<string name="msg_continue_with_github">ادامه دادن با <b>گیت‌هاب</b></string>
<string name="msg_continue_with_google">ادامه دادن با <b>گوگل</b></string>
<string name="msg_continue_with_linkedin">ادامه دادن با <b>لینکدین</b></string>
<string name="msg_continue_with_gitlab">ادامه دادن با <b>گیت‌لب</b></string>
<string name="msg_continue_with_wordpress">ادامه دادن با <b>وردپرس</b></string>
<string name="msg_two_factor_authentication">تایید هویت دو فاکتوره</string>
<string name="msg__your_2fa_code">کد 2FA تان چیست؟</string>
<string name="msg_permalink_copied">پیوند کپی شد</string>
<string name="msg_no_topic">هیچ موضوعی اضافه نشد</string>
<string name="msg_no_announcement">هیچ اعلانی اضافه نشد</string>
<string name="msg_no_description">هیچ توضیحی اضافه نشد</string>
<string name="msg_send_email">ارسال ایمیل</string>
<string name="msg_android_app_support">حمایت از اپ اندروید</string>
<string name="msg_unable_to_update_password">Unable to update password. Error message: %1$s</string> <!-- TODO Add translation -->
<string name="msg_password_updated_successfully">گذرواژه با موفقیت به روزرسانی شد</string>
<plurals name="msg_reacted_with_">
<item quantity="one">%1$s reacted with %2$s</item>
<item quantity="other">%1$s reacted with %2$s</item>
</plurals> <!-- TODO Add translation -->
<!-- Create channel messages -->
<string name="msg_private_channel">خصوصی</string>
<string name="msg_public_channel">عمومی</string>
<string name="msg_private_channel_description">فقط شما و اعضای دعوت‌شده می‌توانند به این کاال دسترسی داشته باشند</string>
<string name="msg_public_channel_description">همه می‌توانند به این کانال دسترسی داشته باشند</string>
<string name="msg_ready_only_channel">کانال فقط خواندنی</string>
<string name="msg_ready_only_channel_description">تنها مدیر می‌تواند پیام جدیدی بنویسد</string>
<string name="msg_invite_members">دعوت اعضا به کانال</string>
<string name="msg_member_already_added">شما قبلا این کاربر را انتخاب کرده بودید</string>
<string name="msg_member_not_found">عضو پیدا نشد</string>
<string name="msg_channel_created_successfully">کانال با موفقیت ایجاد شد</string>
<string name="msg_message_copied">پیام کپی شد</string>
<string name="msg_delete_message">پاک کردن پیام</string>
<string name="msg_delete_description">آیا مطمئنید که می‌خواهید این پیام را پاک کنید؟</string>
<string name="msg_view_more">مشاهده‌ی بیشتر</string>
<string name="msg_view_less">مشاهده‌ی کمتر</string>
<string name="msg_muted_on_this_channel">آیا این کانال را بی‌صدا کردید؟</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">ردگیری تحلیلی</string>
<string name="msg_send_analytics_tracking">برای بهبود این کاره آمار ناشناس بفرستید</string>
<string name="msg_do_not_send_analytics_tracking">برای بهبود این کاره آمار ناشناس نفرستید</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">قابل اجرا نیست زیرا نسخه‌ی FOSS است</string>
<!-- System messages -->
<string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string> <!-- TODO Add translation -->
<string name="message_user_added_by">User %1$s added by %2$s</string> <!-- TODO Add translation -->
<string name="message_user_removed_by">User %1$s removed by %2$s</string> <!-- TODO Add translation -->
<string name="message_user_left">کانال را ترک کرد</string>
<string name="message_user_joined_channel">به کانال پیوست</string>
<string name="message_welcome">%s خوش‌آمدی</string>
<string name="message_removed">پیام پاک شد</string>
<string name="message_pinned">پیام سوزن شده:</string>
<string name="message_muted">User %1$s muted by %2$s</string> <!-- TODO Add translation -->
<string name="message_unmuted">User %1$s unmuted by %2$s</string> <!-- TODO Add translation -->
<string name="message_role_add">%1$s was set %2$s by %3$s</string> <!-- TODO Add translation -->
<string name="message_role_removed">%1$s is no longer %2$s by %3$s</string> <!-- TODO Add translation -->
<string name="message_credentials_saved_successfully">اختیارها با موفقیت ذخیره شد</string>
<!-- Message actions -->
<string name="action_msg_reply">جواب</string>
<string name="action_msg_info">مشخصات پیام</string>
<string name="action_msg_edit">ویرایش</string>
<string name="action_msg_copy">کپی</string>
<string name="action_msg_quote">نقل قول</string>
<string name="action_msg_delete">حذف</string>
<string name="action_msg_pin">سوزن کردن پیام</string>
<string name="action_msg_unpin">از سوزن دراوردن پیام</string>
<string name="action_msg_star">ستاره‌دار کردن پیام</string>
<string name="action_msg_unstar">از ستاره دراوردن پیام</string>
<string name="action_msg_share">اشتراک</string>
<string name="action_title_editing">ویرایش پیام</string>
<string name="action_msg_add_reaction">اضافه کردن واکنش</string>
<string name="action_msg_copy_permalink">Copy permalink</string> <!-- TODO Add translation -->
<string name="action_msg_report">گزارش</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">اجازه‌ی ویرایش نیست</string>
<string name="permission_deleting_not_allowed">اجازه‌ی حذف نیست</string>
<string name="permission_pinning_not_allowed">اجازه‌ی سوزن کردن نیست</string>
<string name="permission_starring_not_allowed">اجازه‌ی ستاره‌دار شدن نیست</string>
<!-- Search message -->
<string name="title_search_message">جست‌وجوی پیام</string>
<!-- Favorite/Unfavorite chat room -->
<string name="title_favorite_chat">مورد علاقه کردن گفت‌وگو</string>
<string name="title_unfavorite_chat">از مورد علاقه دراوردن گفت‌وگو</string>
<!-- Members List -->
<string name="title_members_list">اعضاء</string>
<!-- Mentions -->
<string name="msg_mentions">صدا زدن</string>
<string name="msg_no_mention">صدا زدنی موجود نیست</string>
<string name="msg_all_the_mentions_appear_here">All the mentions\nappear here</string> <!-- TODO Add translation -->
<!-- Pinned Messages -->
<string name="title_pinned_messages">پیام سوزن شده</string>
<string name="no_pinned_messages">پیام سوزن‌شده‌ای موجود نیست</string>
<string name="no_pinned_description">All the pinned messages\nappear here</string> <!-- TODO Add translation -->
<!-- Favorite Messages -->
<string name="title_favorite_messages">پیام‌های مورد علاقه</string>
<string name="no_favorite_messages">هیچ پیام موردعلاقه‌ای موجود نیست</string>
<string name="no_favorite_description">All the favorite messages\nappear here</string> <!-- TODO Add translation -->
<!-- Files -->
<string name="title_files">پروندها</string>
<string name="title_files_total">(%d) پرونده‌ها</string>
<string name="msg_no_files">هیچ پرونده‌ای موجود نیست</string>
<string name="msg_all_files_appear_here">تمام پرونده‌ها اینجا نمایش داده شده‌اند</string>
<!-- Upload Messages -->
<string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string> <!-- TODO Add translation -->
<!-- Socket status -->
<string name="status_connected">متصل</string>
<string name="status_disconnected">قطع شده</string>
<string name="status_connecting">درحال اتصال</string>
<string name="status_authenticating">تصدیق کردن</string>
<string name="status_disconnecting">درحال قطع شده</string>
<string name="status_waiting">Connecting in %d seconds</string> <!-- TODO Add translation -->
<!--Suggestions-->
<string name="suggest_all_description">به همه در این اتاق خبر بده</string>
<string name="suggest_here_description">به کاربران فعال در این اتاق خبر بده</string>
<!-- Slash Commands -->
<string name="Slash_Gimme_Description"> ༼ つ ◕_◕ ༽つ را قبل از پیامتان نمایش می‌دهد</string>
<string name="Slash_LennyFace_Description"> ( ͡° ͜ʖ ͡°) را بعد از پیامتان نمایش می‌دهد</string>
<string name="Slash_Shrug_Description">¯\_(ツ)_/¯ را بعد از پیامتان نمایش می‌دهد</string>
<string name="Slash_Tableflip_Description"> (╯°□°)╯︵ ┻━┻ را نمایش می‌دهد</string>
<string name="Slash_TableUnflip_Description"> ┬─┬ ノ( ゜-゜ノ) را نمایش می‌دهد</string>
<string name="Create_A_New_Channel">ایجاد کانال جدید</string>
<string name="Show_the_keyboard_shortcut_list">نمایش لیست میانبر کیبورد</string>
<string name="Invite_user_to_join_channel_all_from">دعوت کردن تمام اعضاء از کانال [#channel] تا به این کانال بپیوندند</string> <!-- TODO Add translation -->
<string name="Invite_user_to_join_channel_all_to">دعوت از تمامی اعضای این کانال برای پیوستن به کانال [#channel]</string> <!-- TODO Add translation -->
<string name="Archive">بایگانی</string>
<string name="Remove_someone_from_room">حذف کردن کسی از این کانال</string>
<string name="Leave_the_current_channel">کانال کنونی را ترک نمایید</string>
<string name="Displays_action_text">نمایش فعالیت متن</string>
<string name="Direct_message_someone">ارسال پیام مستقیم به کسی</string>
<string name="Mute_someone_in_room">صامت کردن کسی در اتاق</string>
<string name="Unmute_someone_in_room">صدا دار کردن کسی در این اتاق</string>
<string name="Invite_user_to_join_channel">دعوت از یک کاربر برای پیوستن به این کانال</string>
<string name="Unarchive">Unarchive</string> <!-- TODO Add translation -->
<string name="Join_the_given_channel">پیوستن به کانال داده شده</string>
<string name="Guggy_Command_Description">ساخت یک gif بر اساس متن آماده‌شده</string>
<string name="Slash_Topic_Description">تعیین موضوع</string>
<!-- Emoji message-->
<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>
<!--ChatRooms Headers-->
<string name="header_channel">کانال‌ها</string>
<string name="header_private_groups">گروه‌های خصوصی</string>
<string name="header_direct_messages">پیام‌های خصوصی</string>
<string name="header_live_chats">گفت‌وگوهای زنده</string>
<string name="header_unknown">ناشناس</string>
<!--Notifications-->
<string name="share_label">ویراش پیام به اشتراک گذاشته شده</string>
<string name="notif_action_reply_hint">جواب دادن</string>
<string name="notif_error_sending">جواب با شکست مواجه شد. لطفا دوباره تلاش کنید.</string>
<string name="notif_success_sending">Message sent to %1$s!</string> <!-- TODO Add translation -->
<string name="read_by">خوانده شده توسط</string>
<string name="message_information_title">اطلاعات پیام</string>
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!-- TODO Add translation -->
<!-- User Details -->
<string name="timezone">منطقه‌ی زمانی</string>
<!-- Report -->
<string name="submit">واگذاری</string>
<string name="required">*required</string> <!-- TODO Add translation -->
<string name="report_sent">گزارش شما فرستاده شد</string>
</resources>
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation -->
<item name="item_password">Change password</item> <!-- TODO Add translation -->
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_share_app">Share app</item> <!-- TODO Add translation -->
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation -->
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation -->
......@@ -120,14 +121,13 @@
<string name="msg_preview_photo">Photo</string>
<string name="msg_preview_file">Fichier</string>
<string name="msg_no_messages_yet">Aucun message pour le moment</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">La version du serveur est trop ancienne. Veuillez contacter l\'administateur pour mettre à jour le serveur afin de pouvoir vous y connecter.</string>
<string name="msg_ver_not_recommended">
On dirait que la version de votre serveur est en dessous de la version recommandée %1$s.\nVous pouvez toujours vous connecter mais vous pouvez rencontrer des comportements inattendus.</string>
<string name="msg_ver_not_minimum">
On dirait que la version de votre serveur est inférieure à la version minimale requise %1$s.\nVeuillez mettre à jour votre serveur pour vous connecter!
</string>
<string name="msg_cancel">ANNULER</string>
<string name="msg_http_insecure">Lorsque vous utilisez HTTP, vous vous connectez à un serveur non sécurisé. Nous ne vous recommandons pas de le faire.</string>
<string name="msg_error_checking_server_version">Une erreur est survenue lors de la vérification de la version de votre serveur, veuillez réessayer</string>
<string name="msg_invalid_server_protocol">Le protocole sélectionné n\'est pas accepté par ce serveur, essayez d\'utiliser HTTPS</string>
......@@ -335,14 +335,11 @@
<string name="message_information_title">Informations sur le message</string>
<string name="msg_log_out">Déconnecter…</string>
<string name="msg_sent_attachment">Envoyé un fichier</string>
<!--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> <!--TODO - Add proper translation-->
<!-- User Details -->
<string name="message">Message</string> <!-- TODO - Add proper translation -->
<string name="timezone">Timezone</string> <!-- TODO - Add proper translation -->
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string> <!-- TODO - Add proper translation -->
<string name="retry">Retry</string> <!-- TODO - Add proper translation -->
<!-- Report -->
<string name="submit">Submit</string> <!-- TODO - Add proper translation -->
......
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">पसंद</item>
<item name="item_password">पासवर्ड बदलें</item>
<item name="change_language">भाषा बदलें</item>
<item name="item_share_app">ऐप शेयर करें</item>
<item name="item_rate_us">हमें रेटिंग दें</item>
<item name="item_contact_us">हमसे संपर्क करें</item>
......@@ -120,15 +121,14 @@
<string name="msg_preview_file">फ़ाइल</string>
<string name="msg_unread_messages">अपठित संदेश</string>
<string name="msg_no_messages_yet">अभी तक कोई पोस्ट नहीं</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">पुराना सर्वर वर्शन। जारी रखने के लिए सर्वर वर्शन को अद्यतन करने के लिए कृपया सर्वर व्यवस्थापक से संपर्क करें।</string>
<string name="msg_ok">ठीक है</string>
<string name="msg_ver_not_recommended">
ऐसा लगता है कि आपका सर्वर संस्करण अनुशंसित संस्करण %1$s के नीचे है।\nआप अभी भी लॉगिन कर सकते हैं लेकिन आप अप्रत्याशित व्यवहार का अनुभव कर सकते हैं
</string>
<string name="msg_ver_not_minimum">
ऐसा लगता है कि आपका सर्वर संस्करण न्यूनतम आवश्यक संस्करण %1$s से कम है।\nकृपया लॉगिन करने के लिए अपने सर्वर को अपग्रेड करें!
</string>
<string name="msg_cancel">रद्द करना</string>
<string name="msg_http_insecure">HTTP का उपयोग करते समय, आप एक असुरक्षित सर्वर से कनेक्ट हो रहे हैं। हम आपको ऐसा करने की सलाह नहीं देते हैं।</string>
<string name="msg_error_checking_server_version">आपके सर्वर संस्करण की जांच करते समय एक त्रुटि आई है, कृपया पुनः प्रयास करें</string>
<string name="msg_invalid_server_protocol">चयनित प्रोटोकॉल इस सर्वर द्वारा स्वीकार नहीं किया गया है, HTTPS का उपयोग करने का प्रयास करें</string>
......@@ -152,7 +152,7 @@
<string name="msg_delete_message">संदेश को हटाएं</string>
<string name="msg_delete_description">क्या आप निश्चित रूप से यह संदेश हटाना चाहते हैं</string>
<string name="msg_welcome_to_rocket_chat">Rocket.Chat में आपका स्वागत है</string>
<string name="msg_team_communication">Team Communication</string> <!-- TODO Translate -->
<string name="msg_team_communication">टीम संचार</string>
<string name="msg_login_with_email">ई-मेल के साथ लॉगिन करें</string>
<string name="msg_create_account">खाता बनाएं</string>
<string name="msg_continue_with_facebook"><b>Facebook</b> के साथ जारी रखें</string>
......@@ -337,10 +337,7 @@
<string name="message_room_changed_privacy">%2$s ने रूम का प्रकार बदलकर %1$s किया </string>
<!-- User Details -->
<string name="message">संदेश</string>
<string name="timezone">समय क्षेत्र</string>
<string name="error_opening_dm">जब हम इस बातचीत को बना रहे थे तो कुछ गड़बड़ हुई …</string>
<string name="retry">पुन: प्रयास करें</string>
<!-- Report -->
<string name="submit">जमा करें</string>
......
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferenze</item>
<item name="item_password">Cambia password</item>
<item name="change_language">Cambia lingua</item>
<item name="item_share_app">Condividi app</item>
<item name="item_rate_us">Votaci</item>
<item name="item_contact_us">Contattaci</item>
......@@ -122,13 +123,12 @@
<string name="msg_preview_photo">Foto</string>
<string name="msg_preview_file">Documento</string>
<string name="msg_no_messages_yet">Nessun nuovo messaggio</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Versione %1$d - %2$s - %3$s</string>
<string name="msg_update_app_version_in_order_to_continue">Versione server non aggiornata. Si prega di contattare l\'amministratore del server per aggiornare la versione del server per continuare.</string>
<string name="msg_ver_not_recommended">Sembra che la versione del tuo server sia inferiore alla versione consigliata %1$s.\nÈ ancora possibile accedere ma è possibile che si verifichino comportamenti imprevisti.</string>
<string name="msg_ver_not_minimum">Sembra che la versione del tuo server sia inferiore alla versione minima richiesta %1$s.\nSi prega di aggiornare il server per accedere!</string>
<string name="msg_no_chat_title">Nessun messaggio chat</string>
<string name="msg_no_chat_description">Inizia a conversare per vedere i tuoi\nmessagggi qui.</string>
<string name="msg_cancel">CANCELLARE</string>
<string name="msg_http_insecure">Quando si utilizza HTTP, ci si connette a un server non sicuro. Non ti consigliamo di farlo.</string>
<string name="msg_error_checking_server_version">Si è verificato un errore durante il controllo della versione del server, riprovare</string>
<string name="msg_invalid_server_protocol">Il protocollo selezionato non è accettato da questo server, prova a utilizzare HTTPS</string>
......@@ -146,7 +146,7 @@
<string name="msg_send">Inviare</string>
<string name="msg_sent_attachment">Inviato allegato</string>
<string name="msg_welcome_to_rocket_chat">Benvenuto in Rocket.Chat </string>
<string name="msg_team_communication">Team Communication</string> <!-- TODO Translate -->
<string name="msg_team_communication">Comunicazione dei Gruppi</string>
<string name="msg_login_with_email">Accedi con <b>e-mail</b></string>
<string name="msg_create_account">Crea un utente</string>
<string name="msg_continue_with_facebook">Continua con <b>Facebook</b></string>
......@@ -163,8 +163,8 @@
<string name="msg_no_description">Nessuna descrizione aggiunta</string>
<string name="msg_send_email">Invia una email</string>
<string name="msg_android_app_support">Supporto per le app Android</string>
<string name="msg_unable_to_update_password">Unable to update password. Error message: %1$s</string> <!-- TODO - Add proper translation -->
<string name="msg_password_updated_successfully">Password updated successfully</string> <!-- TODO - Add proper translation -->
<string name="msg_unable_to_update_password">Impossibile aggiornare la password. Messaggio di errore: %1$s</string>
<string name="msg_password_updated_successfully">Password aggiornata con successo</string>
<plurals name="msg_reacted_with_">
<item quantity="one">%1$s ha reagito con %2$s</item>
<item quantity="other">%1$s ha reagito con %2$s</item>
......@@ -332,10 +332,7 @@
<string name="message_room_changed_privacy">Il tipo di stanza è cambiato in: %1$s da %2$s</string>
<!-- User Details -->
<string name="message">Messaggio</string>
<string name="timezone">Fuso Orario</string>
<string name="error_opening_dm">È successo qualcosa di sbagliato durante la creazione di questa conversazione...</string>
<string name="retry">Riprova</string>
<!-- Report -->
<string name="submit">Invia</string>
......
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<string name="app_name" translatable="false">Rocket.Chat</string>
<!-- Titles -->
<string name="title_sign_in_your_server">サーバーに接続</string>
......@@ -22,7 +20,7 @@
<string name="title_admin_panel">管理パネル</string>
<string name="title_password">パスワードの変更</string>
<string name="title_update_profile">プロフィールの更新</string>
<string name="title_about">About</string>
<string name="title_about">About</string><!-- TODO Add translation -->
<string name="title_licence">Licence</string> <!-- TODO Add translation -->
<string name="title_create_channel">新しいチャネルを作成</string>
<string name="title_are_you_sure">本気ですか?</string>
......@@ -66,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation -->
<item name="item_password">Change password</item> <!-- TODO Add translation -->
<item name="change_language">Change language </item><!-- TODO Add translation -->
<item name="item_share_app">Share app</item> <!-- TODO Add translation -->
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation -->
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation -->
......@@ -124,7 +123,7 @@
<string name="msg_preview_photo">写真</string>
<string name="msg_preview_file">ファイル</string>
<string name="msg_no_messages_yet">メッセージはまだありません</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">古いバージョンのサーバーを使用しています。続行するには、管理者にサーバーのバージョンを更新するよう連絡してください。</string>
<string name="msg_ver_not_recommended">
ご使用のサーバーのバージョンは推薦バージョン %1$s よりも古いものです。\nログインは可能ですが、予期しない動作が発生する可能性があります。</string>
......@@ -133,7 +132,6 @@
</string>
<string name="msg_no_chat_title">メッセージがまだありません</string>
<string name="msg_no_chat_description">ここから会話を始めましょう</string>
<string name="msg_cancel">キャンセル</string>
<string name="msg_http_insecure">HTTPを使用している場合、安全ではないサーバーに接続します。安全なサーバーに接続することをお勧めします。</string>
<string name="msg_error_checking_server_version">サーバーのバージョンを確認中にエラーが発生しました。もう一度お試しください。</string>
<string name="msg_invalid_server_protocol">選択したプロトコルはこのサーバーでは使用できません。HTTPSを選択してください。</string>
......@@ -229,8 +227,7 @@
<string name="action_title_editing">メッセージの編集</string>
<string name="action_msg_add_reaction">リアクションする</string>
<string name="action_msg_copy_permalink">パーマリンクのコピー</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_report">Report</string>
<string name="action_msg_report">Report</string> <!-- TODO - Add proper translation -->
<!-- Permission messages -->
<string name="permission_editing_not_allowed">編集は許可されていません</string>
......@@ -340,13 +337,10 @@
<string name="message_room_changed_privacy">ルームタイプを %2$s から %1$s に変更しました</string>
<!-- User Details -->
<string name="message">Message</string> <!--TODO - Add proper translation-->
<string name="timezone">Timezone</string> <!--TODO - Add proper translation-->
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string> <!-- TODO - Add proper translation -->
<string name="retry">Retry</string> <!-- TODO - Add proper translation -->
<!-- Report -->
<string name="submit">Submit</string> <!--TODO - Add proper translation-->
<string name="required">*required</string> <!--TODO - Add proper translation-->
<string name="report_sent">Your report has been sent!</string> <!--TODO - Add proper translation-->
</resources>
</resources>
\ No newline at end of file
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferências</item>
<item name="item_password">Alterar senha</item>
<item name="change_language">Alterar idioma</item>
<item name="item_share_app">Compartilhar app</item>
<item name="item_rate_us">Classifique-nos</item>
<item name="item_contact_us">Contate-nos</item>
......@@ -120,7 +121,7 @@
<string name="msg_preview_photo">Foto</string>
<string name="msg_preview_file">Arquivo</string>
<string name="msg_no_messages_yet">Nenhuma mensagem ainda</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Versão %1$d - %2$s - %3$s</string>
<string name="msg_update_app_version_in_order_to_continue">Versão do servidor desatualizada. Por favor, entre em contato com o administrador do sistema para continuar.</string>
<string name="msg_ver_not_recommended">
Parece que a versão do seu servidor está abaixo da recomendada %1$s.\nVocê ainda assim pode logar e continuar mas podem ocorrer alguns problemas inesperados.
......@@ -130,7 +131,6 @@
</string>
<string name="msg_no_chat_title">Nenhuma mensagem de chat</string>
<string name="msg_no_chat_description">Comece a conversar para ver suas\nmensagens aqui.</string>
<string name="msg_cancel">CANCELAR</string>
<string name="msg_http_insecure">Usando HTTP, você estará conectando a um servidor não seguro, não recomendamos sua utilização.</string>
<string name="msg_error_checking_server_version">Ocorreu um erro verificando a versão do servidor, por favor tente novamente</string>
<string name="msg_invalid_server_protocol">O protocolo selecionado não é suportado pelo servidor, por favor utilize HTTPS e tente novamente</string>
......@@ -205,13 +205,12 @@
<string name="message_user_joined_channel">Entrou na sala</string>
<string name="message_welcome">Bem-vindo, %s</string>
<string name="message_removed">Mensagem removida</string>
<string name="message_pinned">Pinou uma mensagem:</string>
<string name="message_pinned">Fixou uma mensagem:</string>
<string name="message_muted">Usuário %1$s foi silenciado por %2$s</string>
<string name="message_unmuted">Usuário %1$s saiu do modo silenciado por %2$s</string>
<string name="message_role_add">%1$s foi definido %2$s por %3$s</string>
<string name="message_role_removed">%1$s não é mais %2$s por %3$s</string>
// TODO:Add proper translation.
<string name="message_credentials_saved_successfully">Credentials saved successfully</string>
<string name="message_credentials_saved_successfully">Credenciais salvas com sucesso</string>
<!-- Message actions -->
<string name="action_msg_reply">Responder</string>
......@@ -233,7 +232,7 @@
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Edição não permitida</string>
<string name="permission_deleting_not_allowed">Remoção não permitida</string>
<string name="permission_pinning_not_allowed">Pinagem não permitida</string>
<string name="permission_pinning_not_allowed">Fixagem não permitida</string>
<string name="permission_starring_not_allowed">Marcar como favorita não permitido</string>
<!-- Search message -->
......@@ -252,13 +251,13 @@
<string name="msg_all_the_mentions_appear_here">Todas menções\naparecerão aqui</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">Mensagens Pinadas</string>
<string name="no_pinned_messages">Nenhuma mensagem pinada</string>
<string name="no_pinned_description">Todas mensagens pinadas\naparecerão aqui</string>
<string name="title_pinned_messages">Mensagens Fixadas</string>
<string name="no_pinned_messages">Nenhuma mensagem fixada</string>
<string name="no_pinned_description">Todas mensagens fixadas\naparecerão aqui</string>
<!-- Favorite Messages -->
<string name="title_favorite_messages">Messagens Favoritas</string>
<string name="no_favorite_messages">Nenhuma messagem favorita</string>
<string name="title_favorite_messages">Mensagens Favoritas</string>
<string name="no_favorite_messages">Nenhuma mensagem favorita</string>
<string name="no_favorite_description">Todas mensagens favoritas\naparecerão aqui</string>
<!-- Files -->
......@@ -337,10 +336,7 @@
<string name="message_room_changed_privacy">O tipo da sala mudou para: %1$s por %2$s</string>
<!-- User Details -->
<string name="message">Mensagem</string>
<string name="timezone">Fuso horário</string>
<string name="error_opening_dm">Algo deu errado quando tentamos abrir esta conversa…</string>
<string name="retry">Retentar</string>
<!-- Report -->
<string name="submit">Enviar</string>
......
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Персональные</item>
<item name="item_password">Изменить пароль</item>
<item name="change_language">Изменить язык</item>
<item name="item_share_app">Поделиться приложением</item>
<item name="item_rate_us">Оцените нас</item>
<item name="item_contact_us">Связаться с нами</item>
......@@ -121,13 +122,11 @@
<string name="msg_preview_file">Файл</string>
<string name="msg_no_messages_yet">Нет сообщений</string>
<string name="msg_build">Сборка %1$d - %2$s - %3$s</string>
<string name="msg_ok">OK</string>
<string name="msg_update_app_version_in_order_to_continue">Версия сервера устарела. Пожалуйста, свяжитесь с администратором, чтобы обновить сервер.</string>
<string name="msg_ver_not_recommended">Похоже, версия сервера меньше рекомендуемой %1$s.\nМожно войти, но могут возникнуть те или иные проблемы при работе.\n</string>
<string name="msg_ver_not_minimum">Похоже, версия сервера меньше минимально необходимой %1$s.\nДля работы потребуется обновить сервер!</string>
<string name="msg_no_chat_title">Нет сообщений</string>
<string name="msg_no_chat_description">Начните общаться, чтобы увидеть\nтут сообщения.</string>
<string name="msg_cancel">ОТМЕНА</string>
<string name="msg_http_insecure">При использовании HTTP вы подключаетесь к небезопасному серверу. Мы не рекомендуем вам это делать.</string>
<string name="msg_error_checking_server_version">При проверке версии вашего сервера произошла ошибка, повторите попытку.</string>
<string name="msg_invalid_server_protocol">Выбранный протокол не разрешен на этом сервере, попробуйте использовать HTTPS</string>
......@@ -334,10 +333,7 @@
<string name="message_room_changed_privacy">Тип канала изменен на: %1$s пользователем %2$s</string>
<!-- User Details -->
<string name="message">Сообщение</string>
<string name="timezone">Часовой пояс</string>
<string name="error_opening_dm">При создании этого диалога что-то пошло не так...</string>
<string name="retry">Повторить</string>
<!-- Report -->
<string name="submit">Отправить</string>
......
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation -->
<item name="item_password">Change password</item> <!-- TODO Add translation -->
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_share_app">Share app</item> <!-- TODO Add translation -->
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation -->
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation -->
......@@ -90,7 +91,6 @@
<string name="msg_check_your_email_to_reset_your_password">Eposta gönderilmiştir! Şifrenizi sıfırlamak için eposta kutunuzu kontrol ediniz.</string>
<string name="msg_invalid_email">Lütfen, geçerli bir eposta adresi giriniz</string>
<string name="msg_new_user_agreement">Devam ederek \n%1$s ve %2$s kabul ediyorsunuz</string>
<string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string>
<string name="msg_yesterday">Dün</string>
<string name="msg_today">Bugün</string>
<string name="msg_message">Mesaj</string>
......@@ -123,7 +123,7 @@
<string name="msg_preview_photo">Fotoğraf</string>
<string name="msg_preview_file">Dosya</string>
<string name="msg_no_messages_yet">Henüz mesaj gönderilmedi</string>
<string name="msg_ok">Tamam</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string> <!-- TODO Add translation -->
<string name="msg_update_app_version_in_order_to_continue">Geçerliliğini yitirmiş uygulamanızın sürümü. Lütfen, sistem yöneticisine bildiriniz.</string>
<string name="msg_ver_not_recommended">
Görünüşe göre uygulamanızın sürümü önerilen %1$s sürümünden daha düşük.\nBuna rağmen sisteme giriş yapıp kullanabilirsiniz, fakat beklenmeyen hatalarla karşılaşabilirsiniz.</string>
......@@ -132,7 +132,6 @@
</string>
<string name="msg_no_chat_title">Mesaj bulunmamaktadır</string>
<string name="msg_no_chat_description">Mesajlarınızı burada görmek için \nyazışmaya başlayın.</string>
<string name="msg_cancel">İPTAL</string>
<string name="msg_http_insecure">HTTP kullanırken güvensiz bir sunucuya bağlanıyorsunuz, bunu önermiyoruz.</string>
<string name="msg_error_checking_server_version">Sunucu sürümünüzü kontrol ederken bir hata oluştu, lütfen tekrar deneyiniz</string>
<string name="msg_invalid_server_protocol">Seçilen protokol bu sunucu tarafından kabul edilmiyor, lütfen HTTPS kullanın</string>
......@@ -338,10 +337,7 @@
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!--TODO - Add proper translation-->
<!-- User Details -->
<string name="message">Message</string> <!--TODO - Add proper translation-->
<string name="timezone">Timezone</string> <!--TODO - Add proper translation-->
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string> <!-- TODO - Add proper translation -->
<string name="retry">Retry</string> <!-- TODO - Add proper translation -->
<!-- Report -->
<string name="submit">Submit</string> <!--TODO - Add proper translation-->
......
......@@ -64,6 +64,7 @@
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item> <!-- TODO Add translation -->
<item name="item_password">Change password</item> <!-- TODO Add translation -->
<item name="change_language">Change language</item> <!-- TODO Add translation -->
<item name="item_share_app">Share app</item> <!-- TODO Add translation -->
<item name="item_rate_us">Rate us</item> <!-- TODO Add translation -->
<item name="item_contact_us">Contact us</item> <!-- TODO Add translation -->
......@@ -119,13 +120,11 @@
<string name="msg_preview_audio">Аудіо</string>
<string name="msg_preview_photo">Фото</string>
<string name="msg_preview_file">Файл</string>
<string name="msg_no_messages_yet">"Немає повідомлень "</string>
<string name="msg_no_messages_yet">"Немає повідомлень"</string>
<string name="msg_build">Збірка %1$d - %2$s - %3$s</string>
<string name="msg_ok">ОК</string>
<string name="msg_update_app_version_in_order_to_continue">Версія сервера застаріла. Будь ласка, зв\'яжіться з адміністратором, щоб оновити сервер.</string>
<string name="msg_ver_not_recommended">Здається, версія сервера менше ніж рекомендована %1$s. \nМожна увійти, але можуть виникнути ті чи інші проблеми під час роботи.</string>
<string name="msg_ver_not_minimum">Здається, версія сервера менше ніж мінімально необхідна %1$s.\nДля роботи потрібно оновити сервер!</string>
<string name="msg_cancel">ВІДМІНА</string>
<string name="msg_http_insecure">При використанні HTTP ви підключаєтеся до потенційно небезпечного сервера. Ми не радимо вам це робити.</string>
<string name="msg_error_checking_server_version">Під час перевірки версії вашого сервера сталася помилка, спробуйте ще раз.</string>
<string name="msg_invalid_server_protocol">Використання обраного протоколу не дозволено на цьому сервері, спробуйте використати HTTPS</string>
......@@ -336,10 +335,7 @@
<string name="message_room_changed_privacy">Room type changed to: %1$s by %2$s</string> <!-- TODO - Add proper translation -->
<!-- User Details -->
<string name="message">Message</string>
<string name="timezone">Timezone</string>
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string> <!-- TODO - Add proper translation -->
<string name="retry">Retry</string> <!-- TODO - Add proper translation -->
<!-- Report -->
<string name="submit">Submit</string> <!-- TODO - Add proper translation -->
......
<resources>
<!-- Titles -->
<string name="title_sign_in_your_server">登录您的服务器</string>
<string name="title_log_in">登录</string>
<string name="title_share_the_app">分享App</string>
<string name="title_register_username">注册用户</string>
<string name="title_reset_password">重置密码</string>
<string name="title_sign_up">登录</string>
<string name="title_authentication">认证</string>
<string name="title_legal_terms">法律条款</string>
<string name="title_chats">聊天</string>
<string name="title_profile">资料</string>
<string name="title_members">成员</string>
<string name="title_counted_members">成员(%d)</string>
<string name="title_settings">设置</string>
<string name="title_preferences">首选项</string>
<string name="title_change_password">修改密码</string>
<string name="title_rate_us">给我们打分</string>
<string name="title_admin_panel">管理面板</string>
<string name="title_password">修改密码</string>
<string name="title_update_profile">更新资料</string>
<string name="title_about">关于</string>
<string name="title_create_channel">新建频道</string>
<string name="title_licence">许可证</string>
<string name="title_are_you_sure">你确定?</string>
<string name="title_channel_details">频道信息</string>
<string name="title_topic">主题</string>
<string name="title_announcement">公告</string>
<string name="title_description">描述</string>
<!-- Actions -->
<string name="action_connect">连接</string>
<string name="action_use_this_username">使用这个用户名</string>
<string name="action_terms_of_service">服务条款</string>
<string name="action_privacy_policy">隐私政策</string>
<string name="action_search">搜索</string>
<string name="action_update">更新</string>
<string name="action_settings">设置</string>
<string name="action_create_channel">新建频道</string>
<string name="action_create">新建</string>
<string name="action_logout">登出</string>
<string name="action_attach_a_files">添加附件</string>
<string name="action_confirm_password">确认修改密码</string>
<string name="action_join_chat">加入聊天</string>
<string name="action_add_account">添加账户</string>
<string name="action_online">在线</string>
<string name="action_away">离开</string>
<string name="action_busy">忙碌</string>
<string name="action_invisible">隐身</string>
<string name="action_drawing">绘画</string>
<string name="action_save_to_gallery">保存到图库</string>
<string name="action_select_photo_from_gallery">从图库选照片</string>
<string name="action_take_a_photo">拍照</string>
<string name="action_reset_avatar">重置头像</string>
<string name="action_connect_server">连接到服务器</string>
<string name="action_join_community">加入社区</string>
<string name="action_create_server">新建一个新服务器</string>
<string name="action_register">注册</string>
<string name="action_confirm">确定</string>
<string name="action_delete_account">删除账户</string>
<!-- Settings List -->
<string-array name="settings_actions">
<item name="item_preferences">首选项</item>
<item name="item_password">修改密码</item>
<item name="change_language">更改语言</item>
<item name="item_share_app">分享app</item>
<item name="item_rate_us">给我们打分</item>
<item name="item_contact_us">联系我们</item>
<item name="item_licence">许可证</item>
<item name="item_about">关于</item>
</string-array>
<!-- Regular information messages -->
<string name="msg_generic_error">对不起发生了错误,请重试</string>
<string name="msg_no_data_to_display">没有数据显示</string>
<string name="msg_check_this_out">检查这里</string>
<string name="msg_share_using">分享使用</string>
<string name="msg_profile_update_successfully">资料更新成功</string>
<string name="msg_username">用户名</string>
<string name="msg_username_or_email">用户名或邮箱</string>
<string name="msg_password">密码</string>
<string name="msg_name">名字</string>
<string name="msg_email">邮箱</string>
<string name="msg_avatar_url">头像网址</string>
<string name="msg_or_continue_using_social_accounts">或继续使用社交账号</string>
<string name="msg_new_user">新用户? %1$s</string>
<string name="msg_forgot__your_password">忘记密码?</string>
<string name="msg_reset">重置</string>
<string name="msg_check_your_email_to_reset_your_password">邮件已发送!请根据邮件提示重置密码.</string>
<string name="msg_invalid_email">请输入有效邮箱地址</string>
<string name="msg_new_user_agreement">如果继续表示您同意我们的\n%1$s 和 %2$s</string>
<string name="msg_yesterday">昨天</string>
<string name="msg_today">今天</string>
<string name="msg_message">消息</string>
<string name="msg_this_room_is_read_only">这个频道只读</string>
<string name="msg_invalid_2fa_code">无效的2FA码</string>
<string name="msg_invalid_file">无效文件</string>
<string name="msg_invalid_server_url">无效的服务器地址</string>
<string name="msg_content_description_log_in_using_facebook">使用Facebook账户登录</string>
<string name="msg_content_description_log_in_using_github">使用Github账户登录</string>
<string name="msg_content_description_log_in_using_google">使用Google账户登录</string>
<string name="msg_content_description_log_in_using_linkedin">使用Linkedin账户登录</string>
<string name="msg_content_description_log_in_using_meteor">使用Meteor账户登录</string>
<string name="msg_content_description_log_in_using_twitter">使用Twitter账户登录</string>
<string name="msg_content_description_log_in_using_gitlab">使用Gitlab账户登录</string>
<string name="msg_content_description_log_in_using_wordpress">使用WordPress账户登录</string>
<string name="msg_content_description_send_message">发送消息</string>
<string name="msg_content_description_show_more_login_options">显示更多登录选项</string>
<string name="msg_content_description_show_attachment_options">显示附件选项</string>
<string name="msg_you"></string>
<string name="msg_unknown">未知</string>
<string name="msg_email_address">邮箱地址</string>
<string name="msg_utc_offset">时区</string>
<string name="msg_new_password">输入新密码</string>
<string name="msg_confirm_password">确认新密码</string>
<string name="msg_channel_name">频道名称</string>
<string name="msg_search">搜索</string>
<string name="msg_unread_messages">未读消息</string>
<string name="msg_preview_video">视频</string>
<string name="msg_preview_audio">音频</string>
<string name="msg_preview_photo">照片</string>
<string name="msg_preview_file">文件</string>
<string name="msg_no_messages_yet">尚无消息</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string>
<string name="msg_update_app_version_in_order_to_continue">服务器版本过老。请联系服务器管理员更新服务器版本。</string>
<string name="msg_ver_not_recommended">您的服务器版本低于建议的版本%1$s.\n仍然可以登录,但是可能存在部分功能不正常的情况.</string>
<string name="msg_ver_not_minimum">您的服务器版本低于建议的版本%1$s.\n必须更新服务器才能登录!</string>
<string name="msg_no_chat_title">没有聊天信息</string>
<string name="msg_no_chat_description">开始您的对话\n消息在此.</string>
<string name="msg_http_insecure">您正在使用HTTP方式不加密连接到服务器. 我们不建议您这么做.</string>
<string name="msg_error_checking_server_version">检查服务器版本时发生错误,请重试</string>
<string name="msg_invalid_server_protocol">您选择的协议被服务器拒绝,请使用HTTPS</string>
<string name="msg_image_saved_successfully">图片已保存到图库</string>
<string name="msg_image_saved_failed">保存图片失败</string>
<string name="msg_edited">(已编辑)</string>
<string name="msg_and">\u0020和\u0020</string>
<string name="msg_is_typing">\u0020正在输入…</string>
<string name="msg_are_typing">\u0020正在输入…</string>
<string name="msg_several_users_are_typing">好几个用户正在输入…</string>
<string name="msg_no_search_found">没有搜索到结果</string>
<string name="msg_log_out">登出…</string>
<string name="msg_upload_file">上传文件</string>
<string name="msg_file_description">文件描述</string>
<string name="msg_send">发送</string>
<string name="msg_sent_attachment">发送一个附件</string>
<string name="msg_welcome_to_rocket_chat">欢迎来到Rocket.Chat</string>
<string name="msg_team_communication">团队连线</string>
<string name="msg_login_with_email">使用<b>邮箱</b>登录</string>
<string name="msg_create_account">新建账户</string>
<string name="msg_continue_with_facebook">使用<b>Facebook</b>账号继续</string>
<string name="msg_continue_with_github">使用<b>Github</b>账号继续</string>
<string name="msg_continue_with_google">使用<b>Google</b>账号继续</string>
<string name="msg_continue_with_linkedin">使用<b>Linkedin</b>账号继续</string>
<string name="msg_continue_with_gitlab">使用<b>GitLab</b>账号继续</string>
<string name="msg_continue_with_wordpress">使用<b>WordPress</b>账号继续</string>
<string name="msg_two_factor_authentication">两步认证</string>
<string name="msg__your_2fa_code">什么是2FA 码?</string>
<string name="msg_permalink_copied">永久链接已拷贝</string>
<string name="msg_no_topic">没有添加主题</string>
<string name="msg_no_announcement">没有添加公告</string>
<string name="msg_no_description">没有添加描述</string>
<string name="msg_send_email">发送邮件</string>
<string name="msg_android_app_support">安卓app支持</string>
<string name="msg_unable_to_update_password">无法更新密码,错误信息: %1$s</string>
<string name="msg_password_updated_successfully">密码更新成功</string>
<plurals name="msg_reacted_with_">
<item quantity="one">%1$s 使用了 %2$s</item>
<item quantity="other">%1$s 使用了 %2$s</item>
</plurals>
<!-- Create channel messages -->
<string name="msg_private_channel">隐私</string>
<string name="msg_public_channel">公共</string>
<string name="msg_private_channel_description">只有你和被邀请的用户可以进入频道</string>
<string name="msg_public_channel_description">所有人都可以进入频道</string>
<string name="msg_ready_only_channel">只读频道</string>
<string name="msg_ready_only_channel_description">只有管理员可以发信息</string>
<string name="msg_invite_members">邀请用户</string>
<string name="msg_member_already_added">您已经选择了这个用户</string>
<string name="msg_member_not_found">找不到用户</string>
<string name="msg_channel_created_successfully">成功建立频道</string>
<string name="msg_message_copied">消息已拷贝</string>
<string name="msg_delete_message">删除消息</string>
<string name="msg_delete_description">您确定要删除这条消息吗</string>
<string name="msg_view_more">显示更多</string>
<string name="msg_view_less">显示更少</string>
<string name="msg_muted_on_this_channel">您被禁言了</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">跟踪分析</string>
<string name="msg_send_analytics_tracking">发送匿名统计信息来帮助改善App</string>
<string name="msg_do_not_send_analytics_tracking">不要发送匿名统计信息,我不想帮组改善App</string>
<string name="msg_not_applicable_since_it_is_a_foss_version">不适用,因为这事开源软件</string>
<!-- System messages -->
<string name="message_room_name_changed">频道名改为: %1$s by %2$s</string>
<string name="message_user_added_by">%2$s增加了用户%1$s </string>
<string name="message_user_removed_by">%2$s移除了用户%1$s </string>
<string name="message_user_left">离开了频道.</string>
<string name="message_user_joined_channel">加入了频道.</string>
<string name="message_welcome">欢迎 %s</string>
<string name="message_removed">消息被删除</string>
<string name="message_pinned">固定的消息:</string>
<string name="message_muted">用户%1$s被%2$s禁言</string>
<string name="message_unmuted">用户 %1$s被%2$s取消禁言</string>
<string name="message_role_add">%1$s被设置为%2$s 由%3$s操作</string>
<string name="message_role_removed">%1$s不在是%2$s 由%3$s操作</string>
<string name="message_credentials_saved_successfully">凭证成功保存</string>
<!-- Message actions -->
<string name="action_msg_reply">回复</string>
<string name="action_msg_info">消息通知</string>
<string name="action_msg_edit">编辑</string>
<string name="action_msg_copy">拷贝</string>
<string name="action_msg_quote">引用</string>
<string name="action_msg_delete">删除</string>
<string name="action_msg_pin">固定消息</string>
<string name="action_msg_unpin">取消固定</string>
<string name="action_msg_star">标记消息</string>
<string name="action_msg_unstar">取消标记</string>
<string name="action_msg_share">分享消息</string>
<string name="action_title_editing">编辑消息</string>
<string name="action_msg_add_reaction">增加操作</string>
<string name="action_msg_copy_permalink">拷贝永久链接</string>
<string name="action_msg_report">报告</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">没有编辑权限</string>
<string name="permission_deleting_not_allowed">没有删除权限</string>
<string name="permission_pinning_not_allowed">没有固定权限</string>
<string name="permission_starring_not_allowed">没有标记权限</string>
<!-- Search message -->
<string name="title_search_message">搜索消息</string>
<!-- Favorite/Unfavorite chat room -->
<string name="title_favorite_chat">收藏</string>
<string name="title_unfavorite_chat">取消收藏</string>
<!-- Members List -->
<string name="title_members_list">成员</string>
<!-- Mentions -->
<string name="msg_mentions">提及的消息</string>
<string name="msg_no_mention">没有提及的消息</string>
<string name="msg_all_the_mentions_appear_here">所有提及\n在此显示</string>
<!-- Pinned Messages -->
<string name="title_pinned_messages">已固定消息</string>
<string name="no_pinned_messages">没有固定消息</string>
<string name="no_pinned_description">所有提及的\n在此显示</string>
<!-- Favorite Messages -->
<string name="title_favorite_messages">收藏的消息</string>
<string name="no_favorite_messages">没有收藏的消息</string>
<string name="no_favorite_description">所有收藏的消失\n在此显示</string>
<!-- Files -->
<string name="title_files">文件</string>
<string name="title_files_total">文件 (%d)</string>
<string name="msg_no_files">没有文件</string>
<string name="msg_all_files_appear_here">所有文件在此显示</string>
<!-- Upload Messages -->
<string name="max_file_size_exceeded">文件大小 %1$d bytes 超过最大允许大小 %2$d bytes</string>
<!-- Socket status -->
<string name="status_connected">已连接</string>
<string name="status_disconnected">已断线</string>
<string name="status_connecting">连接中</string>
<string name="status_authenticating">认证</string>
<string name="status_disconnecting">断线中</string>
<string name="status_waiting">连接持续了 %d 秒</string>
<!--Suggestions-->
<string name="suggest_all_description">提醒频道内所有人</string>
<string name="suggest_here_description">提醒频道内在线的人</string>
<!-- Slash Commands -->
<string name="Slash_Gimme_Description">在您的消息前显示 ༼ つ ◕_◕ ༽つ </string>
<string name="Slash_LennyFace_Description">在您的消息后显示 ( ͡° ͜ʖ ͡°) </string>
<string name="Slash_Shrug_Description">在您的消息后显示 ¯\_(ツ)_/¯ </string>
<string name="Slash_Tableflip_Description">显示 (╯°□°)╯︵ ┻━┻</string>
<string name="Slash_TableUnflip_Description">显示 ┬─┬ ノ( ゜-゜ノ)</string>
<string name="Create_A_New_Channel">新建频道</string>
<string name="Show_the_keyboard_shortcut_list">显示键盘快捷列表</string>
<string name="Invite_user_to_join_channel_all_from">邀请 [#channel] 内所有成员加入这个频道</string>
<string name="Invite_user_to_join_channel_all_to">邀请这个频道内所有成员加入 [#channel]</string>
<string name="Archive">归档</string>
<string name="Remove_someone_from_room">从频道内移除用户</string>
<string name="Leave_the_current_channel">离开频道</string>
<string name="Displays_action_text">显示操作</string>
<string name="Direct_message_someone">与某人直接对话</string>
<string name="Mute_someone_in_room">禁言某人</string>
<string name="Unmute_someone_in_room">取消禁言某人</string>
<string name="Invite_user_to_join_channel">邀请一个用户进入频道</string>
<string name="Unarchive">取消归档</string>
<string name="Join_the_given_channel">加入频道</string>
<string name="Guggy_Command_Description">根据文本生成GIF</string>
<string name="Slash_Topic_Description">设定主题</string>
<!-- Emoji message-->
<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>
<!--ChatRooms Headers-->
<string name="header_channel">频道</string>
<string name="header_private_groups">私人组</string>
<string name="header_direct_messages">直接对话</string>
<string name="header_live_chats">Live 对话</string>
<string name="header_unknown">未知</string>
<!--Notifications-->
<string name="share_label">编辑分享的消息</string>
<string name="notif_action_reply_hint">回复</string>
<string name="notif_error_sending">回复失败,请重试.</string>
<string name="notif_success_sending">消息发送给 %1$s!</string>
<string name="read_by">阅读</string>
<string name="message_information_title">消息信息</string>
<string name="message_room_changed_privacy">频道类型更改为: %1$s by %2$s</string>
<string name="foss" translatable="false">(开源)</string>
<!-- User Details -->
<string name="timezone">时区</string>
<string name="status" translatable="false">状态</string>
<!-- Report -->
<string name="submit">提交</string>
<string name="required">*必须</string>
<string name="report_sent">您的报告已提交!</string>
</resources>
......@@ -13,6 +13,8 @@
<color name="colorTimestampText">#FF9DA2A9</color>
<color name="colorTimestampTextUnread">#FF5699FF</color>
<color name="colorLastMessageText">#99000000</color>
<color name="colorUserDetailsNameText">#FF0C0D0F</color>
<color name="colorUserDetailsUsernameText">#8B000000</color>
<!-- User status colors -->
<color name="colorUserStatusOnline">#2FE1A8</color>
......
......@@ -9,7 +9,7 @@ Please, follow the rules as shown here (by adding a new string in the correct se
Coding style:
https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strings
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<resources>
<string name="app_name" translatable="false">Rocket.Chat</string>
<!-- Titles -->
......@@ -76,6 +76,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string-array name="settings_actions">
<item name="item_preferences">Preferences</item>
<item name="item_password">Change password</item>
<item name="change_language">Change language</item>
<item name="item_share_app">Share app</item>
<item name="item_rate_us">Rate us</item>
<item name="item_contact_us">Contact us</item>
......@@ -113,7 +114,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_content_description_log_in_using_facebook">Login using Facebook</string>
<string name="msg_content_description_log_in_using_github">Login using Github</string>
<string name="msg_content_description_log_in_using_google">Login using Google</string>
<string name="msg_content_description_log_in_using_linkedin">Login using Linkedin</string>
<string name="msg_content_description_log_in_using_linkedin">Login using LinkedIn</string>
<string name="msg_content_description_log_in_using_meteor">Login using Meteor</string>
<string name="msg_content_description_log_in_using_twitter">Login using Twitter</string>
<string name="msg_content_description_log_in_using_gitlab">Login using Gitlab</string>
......@@ -135,8 +136,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_preview_photo">Photo</string>
<string name="msg_preview_file">File</string>
<string name="msg_no_messages_yet">No messages yet</string>
<string name="msg_build" tools:ignore="MissingTranslation">Build %1$d - %2$s - %3$s</string>
<string name="msg_ok">OK</string>
<string name="msg_build">Build %1$d - %2$s - %3$s</string>
<string name="msg_update_app_version_in_order_to_continue">Out to date server version. Please contact the server admin to update the server version in order to continue.</string>
<string name="msg_ver_not_recommended">
Looks like your server version is below the recommended version %1$s.\nYou can still login but you may experience unexpected behaviors.</string>
......@@ -145,7 +145,6 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
</string>
<string name="msg_no_chat_title">No chat messages</string>
<string name="msg_no_chat_description">Start conversing to see your\nmessages here.</string>
<string name="msg_cancel">CANCEL</string>
<string name="msg_http_insecure">When using HTTP you\'re connecting to an insecure server. We don\'t recommend you doing that.</string>
<string name="msg_error_checking_server_version">An error has occurred while checking your server version, please try again</string>
<string name="msg_invalid_server_protocol">The selected protocol is not accepted by this server, try using HTTPS</string>
......@@ -351,11 +350,8 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<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>
<string name="error_opening_dm">Something went wrong while we were creating this conversation…</string>
<string name="retry">Retry</string>
<!-- Report -->
<string name="submit">Submit</string>
......
......@@ -155,6 +155,43 @@
</style>
<!-- End chat list -->
<!-- User details -->
<style name="UserDetails.TextView.Name" parent="TextAppearance.AppCompat">
<item name="android:textSize">18sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/colorUserDetailsNameText</item>
</style>
<style name="UserDetails.TextView.Username" parent="TextAppearance.AppCompat">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/colorUserDetailsUsernameText</item>
</style>
<style name="UserDetails.TextView.Actions" parent="TextAppearance.AppCompat">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/colorAccent</item>
</style>
<style name="UserDetails.TextView.Title" parent="TextAppearance.AppCompat">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/colorAuthenticationSecondaryText</item>
</style>
<style name="UserDetails.TextView.Description" parent="TextAppearance.AppCompat">
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">@color/colorPrimary</item>
</style>
<!-- End user details-->
<style name="EditText.Password" parent="TextAppearance.AppCompat">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">@color/colorPrimaryDark</item>
......
......@@ -51,6 +51,7 @@ ext {
markwon : '2.0.0',
aVLoadingIndicatorView: '2.1.3',
glide : '4.8.0',
glideTransformations : '4.0.0',
// For wearable
wear : '2.3.0',
......@@ -118,6 +119,7 @@ ext {
frescoImageViewer : "com.github.luciofm:FrescoImageViewer:${versions.frescoImageViewer}",
glide : "com.github.bumptech.glide:glide:${versions.glide}",
glideProcessor : "com.github.bumptech.glide:compiler:${versions.glide}",
glideTransformations : "jp.wasabeef:glide-transformations:${versions.glideTransformations}",
markwon : "ru.noties:markwon:${versions.markwon}",
......
......@@ -53,8 +53,15 @@ class DrawingActivity : DaggerAppCompatActivity(), DrawView {
}
private fun setupDrawTools() {
image_draw_eraser.setOnClickListener {
image_draw_eraser.setOnLongClickListener{
custom_draw_view.clearCanvas()
return@setOnLongClickListener true
}
image_draw_eraser.setOnClickListener {
custom_draw_view.setColor(
ResourcesCompat.getColor(resources, R.color.color_white, null)
)
toggleDrawTools(draw_tools, false)
}
......@@ -111,6 +118,13 @@ class DrawingActivity : DaggerAppCompatActivity(), DrawView {
}
private fun colorSelector() {
image_color_black.setOnClickListener {
custom_draw_view.setColor(
ResourcesCompat.getColor(resources, R.color.color_black, null)
)
scaleColorView(image_color_black)
}
image_color_red.setOnClickListener {
custom_draw_view.setColor(
ResourcesCompat.getColor(resources, R.color.color_red, null)
......
......@@ -42,7 +42,6 @@ class CustomDrawView(context: Context, attrs: AttributeSet) : View(context, attr
fun undo() {
if (mPaths.isEmpty() && mLastPaths.isNotEmpty()) {
mPaths = mLastPaths.clone() as LinkedHashMap<MyPath, PaintOptions>
mLastPaths.clear()
invalidate()
return
}
......
......@@ -74,7 +74,7 @@ class SuggestionsView : FrameLayout, TextWatcher {
// If we don't have any adapter bound to any token bail out.
if (adaptersByToken.isEmpty()) return
if (editor?.get() != null && editor?.get()?.selectionStart ?: 0 <= completionOffset.get()) {
if (editor?.get() != null && editor?.get()?.selectionStart ?: 0 < completionOffset.get()) {
completionOffset.set(NO_STATE_INDEX)
collapse()
}
......
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