Unverified Commit 2cc54dac authored by divyanshu bhargava's avatar divyanshu bhargava Committed by GitHub

Merge pull request #16 from RocketChat/develop

merge
parents c97f822e f3e08765
...@@ -15,7 +15,6 @@ import java.security.InvalidParameterException ...@@ -15,7 +15,6 @@ import java.security.InvalidParameterException
class ChatRoomAdapter( class ChatRoomAdapter(
private val roomType: String, private val roomType: String,
private val roomName: String,
private val presenter: ChatRoomPresenter?, private val presenter: ChatRoomPresenter?,
private val enableActions: Boolean = true, private val enableActions: Boolean = true,
private val reactionListener: EmojiReactionListener? = null private val reactionListener: EmojiReactionListener? = null
...@@ -98,15 +97,24 @@ class ChatRoomAdapter( ...@@ -98,15 +97,24 @@ class ChatRoomAdapter(
} }
when (holder) { when (holder) {
is MessageViewHolder -> holder.bind(dataSet[position] as MessageViewModel) is MessageViewHolder ->
is ImageAttachmentViewHolder -> holder.bind(dataSet[position] as ImageAttachmentViewModel) holder.bind(dataSet[position] as MessageViewModel)
is AudioAttachmentViewHolder -> holder.bind(dataSet[position] as AudioAttachmentViewModel) is ImageAttachmentViewHolder ->
is VideoAttachmentViewHolder -> holder.bind(dataSet[position] as VideoAttachmentViewModel) holder.bind(dataSet[position] as ImageAttachmentViewModel)
is UrlPreviewViewHolder -> holder.bind(dataSet[position] as UrlPreviewViewModel) is AudioAttachmentViewHolder ->
is MessageAttachmentViewHolder -> holder.bind(dataSet[position] as MessageAttachmentViewModel) holder.bind(dataSet[position] as AudioAttachmentViewModel)
is AuthorAttachmentViewHolder -> holder.bind(dataSet[position] as AuthorAttachmentViewModel) is VideoAttachmentViewHolder ->
is ColorAttachmentViewHolder -> holder.bind(dataSet[position] as ColorAttachmentViewModel) holder.bind(dataSet[position] as VideoAttachmentViewModel)
is GenericFileAttachmentViewHolder -> holder.bind(dataSet[position] as GenericFileAttachmentViewModel) is UrlPreviewViewHolder ->
holder.bind(dataSet[position] as UrlPreviewViewModel)
is MessageAttachmentViewHolder ->
holder.bind(dataSet[position] as MessageAttachmentViewModel)
is AuthorAttachmentViewHolder ->
holder.bind(dataSet[position] as AuthorAttachmentViewModel)
is ColorAttachmentViewHolder ->
holder.bind(dataSet[position] as ColorAttachmentViewModel)
is GenericFileAttachmentViewHolder ->
holder.bind(dataSet[position] as GenericFileAttachmentViewModel)
} }
} }
......
...@@ -37,11 +37,11 @@ import timber.log.Timber ...@@ -37,11 +37,11 @@ import timber.log.Timber
import java.io.File import java.io.File
class ImageAttachmentViewHolder(itemView: View, class ImageAttachmentViewHolder(
listener: ActionsListener, itemView: View,
reactionListener: EmojiReactionListener? = null) listener: ActionsListener,
: BaseViewHolder<ImageAttachmentViewModel>(itemView, listener, reactionListener) { reactionListener: EmojiReactionListener? = null
) : BaseViewHolder<ImageAttachmentViewModel>(itemView, listener, reactionListener) {
private var cacheKey: CacheKey? = null private var cacheKey: CacheKey? = null
init { init {
...@@ -63,16 +63,19 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -63,16 +63,19 @@ class ImageAttachmentViewHolder(itemView: View,
// TODO - implement a proper image viewer with a proper Transition // TODO - implement a proper image viewer with a proper Transition
// TODO - We should definitely write our own ImageViewer // TODO - We should definitely write our own ImageViewer
var imageViewer: ImageViewer? = null var imageViewer: ImageViewer? = null
val request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(data.attachmentUrl)) val request =
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.DISK_CACHE) ImageRequestBuilder.newBuilderWithSource(Uri.parse(data.attachmentUrl))
.build() .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.DISK_CACHE)
.build()
cacheKey = DefaultCacheKeyFactory.getInstance() cacheKey = DefaultCacheKeyFactory.getInstance()
.getEncodedCacheKey(request, null) .getEncodedCacheKey(request, null)
val pad = context.resources val pad = context.resources
.getDimensionPixelSize(R.dimen.viewer_toolbar_padding) .getDimensionPixelSize(R.dimen.viewer_toolbar_padding)
val lparams = AppBarLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, val lparams = AppBarLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT) ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
val toolbar = Toolbar(context).also { val toolbar = Toolbar(context).also {
it.inflateMenu(R.menu.image_actions) it.inflateMenu(R.menu.image_actions)
it.overflowIcon?.setTint(Color.WHITE) it.overflowIcon?.setTint(Color.WHITE)
...@@ -98,7 +101,7 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -98,7 +101,7 @@ class ImageAttachmentViewHolder(itemView: View,
val backArrowView = ImageView(context).also { val backArrowView = ImageView(context).also {
it.setImageResource(R.drawable.ic_arrow_back_white_24dp) it.setImageResource(R.drawable.ic_arrow_back_white_24dp)
it.setOnClickListener { imageViewer?.onDismiss() } it.setOnClickListener { imageViewer?.onDismiss() }
it.setPadding(0, pad ,pad, pad) it.setPadding(0, pad, pad, pad)
} }
val layoutParams = AppBarLayout.LayoutParams( val layoutParams = AppBarLayout.LayoutParams(
...@@ -113,10 +116,12 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -113,10 +116,12 @@ class ImageAttachmentViewHolder(itemView: View,
val appBarLayout = AppBarLayout(context).also { val appBarLayout = AppBarLayout(context).also {
it.layoutParams = lparams it.layoutParams = lparams
it.setBackgroundColor(Color.BLACK) it.setBackgroundColor(Color.BLACK)
it.addView(toolbar, AppBarLayout.LayoutParams( it.addView(
AppBarLayout.LayoutParams.MATCH_PARENT, toolbar, AppBarLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT AppBarLayout.LayoutParams.MATCH_PARENT,
)) ViewGroup.LayoutParams.WRAP_CONTENT
)
)
} }
val builder = ImageViewer.createPipelineDraweeControllerBuilder() val builder = ImageViewer.createPipelineDraweeControllerBuilder()
...@@ -144,12 +149,17 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -144,12 +149,17 @@ class ImageAttachmentViewHolder(itemView: View,
val imageFormat = ImageFormatChecker.getImageFormat(resource.openStream()) val imageFormat = ImageFormatChecker.getImageFormat(resource.openStream())
val imageDir = "${Environment.DIRECTORY_PICTURES}/Rocket.Chat Images/" val imageDir = "${Environment.DIRECTORY_PICTURES}/Rocket.Chat Images/"
val imagePath = Environment.getExternalStoragePublicDirectory(imageDir) val imagePath = Environment.getExternalStoragePublicDirectory(imageDir)
val imageFile = File(imagePath, "${cachedFile.nameWithoutExtension}.${imageFormat.fileExtension}") val imageFile =
File(imagePath, "${cachedFile.nameWithoutExtension}.${imageFormat.fileExtension}")
imagePath.mkdirs() imagePath.mkdirs()
imageFile.createNewFile() imageFile.createNewFile()
try { try {
cachedFile.copyTo(imageFile, true) cachedFile.copyTo(imageFile, true)
MediaScannerConnection.scanFile(context, arrayOf(imageFile.absolutePath), null) { path, uri -> MediaScannerConnection.scanFile(
context,
arrayOf(imageFile.absolutePath),
null
) { path, uri ->
Timber.i("Scanned $path:") Timber.i("Scanned $path:")
Timber.i("-> uri=$uri") Timber.i("-> uri=$uri")
} }
...@@ -166,16 +176,21 @@ class ImageAttachmentViewHolder(itemView: View, ...@@ -166,16 +176,21 @@ class ImageAttachmentViewHolder(itemView: View,
} }
private fun canWriteToExternalStorage(): Boolean { private fun canWriteToExternalStorage(): Boolean {
return AndroidPermissionsHelper.checkPermission(itemView.context, Manifest.permission.WRITE_EXTERNAL_STORAGE) return AndroidPermissionsHelper.checkPermission(
itemView.context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
} }
private fun checkWritingPermission() { private fun checkWritingPermission() {
val context = itemView.context val context = itemView.context
if (context is ContextThemeWrapper && context.baseContext is Activity) { if (context is ContextThemeWrapper && context.baseContext is Activity) {
val activity = context.baseContext as Activity val activity = context.baseContext as Activity
AndroidPermissionsHelper.requestPermission(activity, AndroidPermissionsHelper.requestPermission(
activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
AndroidPermissionsHelper.WRITE_EXTERNAL_STORAGE_CODE) AndroidPermissionsHelper.WRITE_EXTERNAL_STORAGE_CODE
)
} }
} }
} }
\ No newline at end of file
...@@ -15,8 +15,14 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) { ...@@ -15,8 +15,14 @@ class ChatRoomNavigator(internal val activity: ChatRoomActivity) {
} }
fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) { fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) {
activity.addFragmentBackStack("PinnedMessages", R.id.fragment_container){ activity.addFragmentBackStack("PinnedMessages", R.id.fragment_container) {
chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId,chatRoomType) chat.rocket.android.pinnedmessages.ui.newInstance(chatRoomId, chatRoomType)
}
}
fun toFavoriteMessageList(chatRoomId: String, chatRoomType: String) {
activity.addFragmentBackStack("FavoriteMessages", R.id.fragment_container) {
chat.rocket.android.favoritemessages.ui.newInstance(chatRoomId, chatRoomType)
} }
} }
......
...@@ -568,9 +568,14 @@ class ChatRoomPresenter @Inject constructor( ...@@ -568,9 +568,14 @@ class ChatRoomPresenter @Inject constructor(
} }
} }
fun toMembersList(chatRoomId: String, chatRoomType: String) = navigator.toMembersList(chatRoomId, chatRoomType) fun toMembersList(chatRoomId: String, chatRoomType: String) =
navigator.toMembersList(chatRoomId, chatRoomType)
fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) = navigator.toPinnedMessageList(chatRoomId,chatRoomType) fun toPinnedMessageList(chatRoomId: String, chatRoomType: String) =
navigator.toPinnedMessageList(chatRoomId, chatRoomType)
fun toFavoriteMessageList(chatRoomId: String, chatRoomType: String) =
navigator.toFavoriteMessageList(chatRoomId, chatRoomType)
fun loadChatRooms() { fun loadChatRooms() {
launchUI(strategy) { launchUI(strategy) {
......
package chat.rocket.android.chatroom.ui package chat.rocket.android.chatroom.ui
import DrawableHelper
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
...@@ -11,14 +10,11 @@ import chat.rocket.android.chatroom.presentation.ChatRoomNavigator ...@@ -11,14 +10,11 @@ import chat.rocket.android.chatroom.presentation.ChatRoomNavigator
import chat.rocket.android.server.domain.GetCurrentServerInteractor import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.util.extensions.addFragment import chat.rocket.android.util.extensions.addFragment
import chat.rocket.android.util.extensions.textContent
import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_chat_room.* import kotlinx.android.synthetic.main.app_bar.*
import javax.inject.Inject import javax.inject.Inject
fun Context.chatRoomIntent( fun Context.chatRoomIntent(
...@@ -50,12 +46,16 @@ private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen" ...@@ -50,12 +46,16 @@ private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed" private const val INTENT_CHAT_IS_SUBSCRIBED = "is_chat_room_subscribed"
class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment> @Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
// TODO - workaround for now... We will move to a single activity // TODO - workaround for now... We will move to a single activity
@Inject lateinit var serverInteractor: GetCurrentServerInteractor @Inject
@Inject lateinit var navigator: ChatRoomNavigator lateinit var serverInteractor: GetCurrentServerInteractor
@Inject lateinit var managerFactory: ConnectionManagerFactory @Inject
lateinit var navigator: ChatRoomNavigator
@Inject
lateinit var managerFactory: ConnectionManagerFactory
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
...@@ -102,8 +102,10 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -102,8 +102,10 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) { if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) {
addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) { addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen, newInstance(
isChatRoomSubscribed, isChatRoomOwner) chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen,
isChatRoomSubscribed, isChatRoomOwner
)
} }
} }
} }
...@@ -116,47 +118,15 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -116,47 +118,15 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
return fragmentDispatchingAndroidInjector return fragmentDispatchingAndroidInjector
} }
fun showRoomTypeIcon(showRoomTypeIcon: Boolean) {
if (showRoomTypeIcon) {
val roomType = roomTypeOf(chatRoomType)
val drawable = when (roomType) {
is RoomType.Channel -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_room_channel, this)
}
is RoomType.PrivateGroup -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_room_lock, this)
}
is RoomType.DirectMessage -> {
DrawableHelper.getDrawableFromId(R.drawable.ic_room_dm, this)
}
else -> null
}
drawable?.let {
val wrappedDrawable = DrawableHelper.wrapDrawable(it)
val mutableDrawable = wrappedDrawable.mutate()
DrawableHelper.tintDrawable(mutableDrawable, this, R.color.white)
DrawableHelper.compoundDrawable(text_room_name, mutableDrawable)
}
} else {
text_room_name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
}
}
private fun setupToolbar() { private fun setupToolbar() {
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false) toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp)
text_room_name.textContent = chatRoomName toolbar.title = chatRoomName
toolbar.setNavigationOnClickListener { finishActivity() }
showRoomTypeIcon(true)
toolbar.setNavigationOnClickListener {
finishActivity()
}
} }
fun setupToolbarTitle(toolbarTitle: String) { fun setupToolbarTitle(toolbarTitle: String) {
text_room_name.textContent = toolbarTitle supportActionBar?.title = toolbarTitle
} }
private fun finishActivity() { private fun finishActivity() {
......
...@@ -117,6 +117,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -117,6 +117,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
setHasOptionsMenu(true)
val bundle = arguments val bundle = arguments
if (bundle != null) { if (bundle != null) {
...@@ -131,7 +132,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -131,7 +132,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} else { } else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
setHasOptionsMenu(true)
} }
override fun onCreateView( override fun onCreateView(
...@@ -153,9 +153,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -153,9 +153,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
setupFab() setupFab()
setupSuggestionsView() setupSuggestionsView()
setupActionSnackbar() setupActionSnackbar()
activity?.apply {
(this as? ChatRoomActivity)?.showRoomTypeIcon(true)
}
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
...@@ -198,7 +195,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -198,7 +195,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
presenter.toMembersList(chatRoomId, chatRoomType) presenter.toMembersList(chatRoomId, chatRoomType)
} }
R.id.action_pinned_messages -> { R.id.action_pinned_messages -> {
presenter.toPinnedMessageList(chatRoomId,chatRoomType) presenter.toPinnedMessageList(chatRoomId, chatRoomType)
}
R.id.action_favorite_messages -> {
presenter.toFavoriteMessageList(chatRoomId, chatRoomType)
} }
} }
return true return true
...@@ -228,8 +228,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -228,8 +228,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
if (recycler_view.adapter == null) { if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(chatRoomType, chatRoomName, presenter, adapter = ChatRoomAdapter(
reactionListener = this@ChatRoomFragment) chatRoomType, presenter,
reactionListener = this@ChatRoomFragment
)
recycler_view.adapter = adapter recycler_view.adapter = adapter
if (dataSet.size >= 30) { if (dataSet.size >= 30) {
recycler_view.addOnScrollListener(endlessRecyclerViewScrollListener) recycler_view.addOnScrollListener(endlessRecyclerViewScrollListener)
...@@ -254,30 +256,31 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -254,30 +256,31 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
private fun toggleNoChatView(size: Int) { private fun toggleNoChatView(size: Int) {
if (size == 0){ if (size == 0) {
image_chat_icon.setVisible(true) image_chat_icon.setVisible(true)
text_chat_title.setVisible(true) text_chat_title.setVisible(true)
text_chat_description.setVisible(true) text_chat_description.setVisible(true)
}else{ } else {
image_chat_icon.setVisible(false) image_chat_icon.setVisible(false)
text_chat_title.setVisible(false) text_chat_title.setVisible(false)
text_chat_description.setVisible(false) text_chat_description.setVisible(false)
} }
} }
private val layoutChangeListener = View.OnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom -> private val layoutChangeListener =
val y = oldBottom - bottom View.OnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom ->
if (Math.abs(y) > 0 && isAdded) { val y = oldBottom - bottom
// if y is positive the keyboard is up else it's down if (Math.abs(y) > 0 && isAdded) {
recycler_view.post { // if y is positive the keyboard is up else it's down
if (y > 0 || Math.abs(verticalScrollOffset.get()) >= Math.abs(y)) { recycler_view.post {
ui { recycler_view.scrollBy(0, y) } if (y > 0 || Math.abs(verticalScrollOffset.get()) >= Math.abs(y)) {
} else { ui { recycler_view.scrollBy(0, y) }
ui { recycler_view.scrollBy(0, verticalScrollOffset.get()) } } else {
ui { recycler_view.scrollBy(0, verticalScrollOffset.get()) }
}
} }
} }
} }
}
private lateinit var endlessRecyclerViewScrollListener: EndlessRecyclerViewScrollListener private lateinit var endlessRecyclerViewScrollListener: EndlessRecyclerViewScrollListener
...@@ -420,7 +423,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -420,7 +423,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun showReplyingAction(username: String, replyMarkdown: String, quotedMessage: String) { override fun showReplyingAction(
username: String,
replyMarkdown: String,
quotedMessage: String
) {
ui { ui {
citation = replyMarkdown citation = replyMarkdown
actionSnackbar.title = username actionSnackbar.title = username
...@@ -565,11 +572,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -565,11 +572,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
connection_status_text.text = getString(R.string.status_connected) connection_status_text.text = getString(R.string.status_connected)
handler.postDelayed(dismissStatus, 2000) handler.postDelayed(dismissStatus, 2000)
} }
is State.Disconnected -> connection_status_text.text = getString(R.string.status_disconnected) is State.Disconnected -> connection_status_text.text =
is State.Connecting -> connection_status_text.text = getString(R.string.status_connecting) getString(R.string.status_disconnected)
is State.Authenticating -> connection_status_text.text = getString(R.string.status_authenticating) is State.Connecting -> connection_status_text.text =
is State.Disconnecting -> connection_status_text.text = getString(R.string.status_disconnecting) getString(R.string.status_connecting)
is State.Waiting -> connection_status_text.text = getString(R.string.status_waiting, state.seconds) is State.Authenticating -> connection_status_text.text =
getString(R.string.status_authenticating)
is State.Disconnecting -> connection_status_text.text =
getString(R.string.status_disconnecting)
is State.Waiting -> connection_status_text.text =
getString(R.string.status_waiting, state.seconds)
} }
} }
} }
...@@ -625,7 +637,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -625,7 +637,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_show_attachment_options.setVisible(true) button_show_attachment_options.setVisible(true)
subscribeComposeTextMessage() subscribeComposeTextMessage()
emojiKeyboardPopup = EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container)) emojiKeyboardPopup =
EmojiKeyboardPopup(activity!!, activity!!.findViewById(R.id.fragment_container))
emojiKeyboardPopup.listener = this emojiKeyboardPopup.listener = this
text_message.listener = object : ComposerEditText.ComposerEditTextListener { text_message.listener = object : ComposerEditText.ComposerEditTextListener {
override fun onKeyboardOpened() { override fun onKeyboardOpened() {
......
...@@ -10,6 +10,7 @@ import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider ...@@ -10,6 +10,7 @@ import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import chat.rocket.android.authentication.ui.AuthenticationActivity import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider import chat.rocket.android.chatroom.di.ChatRoomFragmentProvider
import chat.rocket.android.chatroom.di.ChatRoomModule import chat.rocket.android.chatroom.di.ChatRoomModule
import chat.rocket.android.chatroom.di.FavoriteMessagesFragmentProvider
import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider import chat.rocket.android.chatroom.di.PinnedMessagesFragmentProvider
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider import chat.rocket.android.chatrooms.di.ChatRoomsFragmentProvider
...@@ -47,10 +48,15 @@ abstract class ActivityBuilder { ...@@ -47,10 +48,15 @@ abstract class ActivityBuilder {
abstract fun bindMainActivity(): MainActivity abstract fun bindMainActivity(): MainActivity
@PerActivity @PerActivity
@ContributesAndroidInjector(modules = [ChatRoomModule::class, @ContributesAndroidInjector(
ChatRoomFragmentProvider::class, modules = [
MembersFragmentProvider::class, ChatRoomModule::class,
PinnedMessagesFragmentProvider::class]) ChatRoomFragmentProvider::class,
MembersFragmentProvider::class,
PinnedMessagesFragmentProvider::class,
FavoriteMessagesFragmentProvider::class
]
)
abstract fun bindChatRoomActivity(): ChatRoomActivity abstract fun bindChatRoomActivity(): ChatRoomActivity
@PerActivity @PerActivity
......
package chat.rocket.android.chatroom.di
import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import chat.rocket.android.favoritemessages.ui.FavoriteMessagesFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class FavoriteMessagesFragmentModule {
@Provides
fun provideLifecycleOwner(frag: FavoriteMessagesFragment): LifecycleOwner {
return frag
}
@Provides
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
@Provides
fun provideFavoriteMessagesView(frag: FavoriteMessagesFragment): FavoriteMessagesView {
return frag
}
}
\ No newline at end of file
package chat.rocket.android.chatroom.di
import chat.rocket.android.favoritemessages.ui.FavoriteMessagesFragment
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class FavoriteMessagesFragmentProvider {
@ContributesAndroidInjector(modules = [FavoriteMessagesFragmentModule::class])
abstract fun provideFavoriteMessageFragment(): FavoriteMessagesFragment
}
\ No newline at end of file
package chat.rocket.android.favoritemessages.presentation
import chat.rocket.android.chatroom.viewmodel.ViewModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.GetChatRoomsInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.getFavoriteMessages
import timber.log.Timber
import javax.inject.Inject
class FavoriteMessagesPresenter @Inject constructor(
private val view: FavoriteMessagesView,
private val strategy: CancelStrategy,
private val serverInteractor: GetCurrentServerInteractor,
private val roomsInteractor: GetChatRoomsInteractor,
private val mapper: ViewModelMapper,
factory: RocketChatClientFactory
) {
private val client = factory.create(serverInteractor.get()!!)
private var offset: Int = 0
/**
* Loads all favorite messages for room. the given room id.
*
* @param roomId The id of the room to get its favorite messages.
*/
fun loadFavoriteMessages(roomId: String) {
launchUI(strategy) {
try {
val serverUrl = serverInteractor.get()!!
val chatRoom = roomsInteractor.getById(serverUrl, roomId)
chatRoom?.let { room ->
view.showLoading()
val favoriteMessages =
client.getFavoriteMessages(roomId, room.type, offset)
offset = favoriteMessages.offset.toInt()
val messageList = mapper.map(favoriteMessages.result)
view.showFavoriteMessages(messageList)
view.hideLoading()
}.ifNull {
Timber.e("Couldn't find a room with id: $roomId at current server.")
}
} catch (e: RocketChatException) {
Timber.e(e)
}
}
}
}
\ No newline at end of file
package chat.rocket.android.favoritemessages.presentation
import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
interface FavoriteMessagesView : MessageView, LoadingView {
/**
* Shows the list of favorite messages for the current room.
*
* @param favoriteMessages The list of favorite messages to show.
*/
fun showFavoriteMessages(favoriteMessages: List<BaseViewModel<*>>)
}
\ No newline at end of file
package chat.rocket.android.favoritemessages.ui
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
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.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesPresenter
import chat.rocket.android.favoritemessages.presentation.FavoriteMessagesView
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
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.fragment_favorite_messages.*
import javax.inject.Inject
fun newInstance(chatRoomId: String, chatRoomType: String): Fragment {
return FavoriteMessagesFragment().apply {
arguments = Bundle(1).apply {
putString(INTENT_CHAT_ROOM_ID, chatRoomId)
putString(INTENT_CHAT_ROOM_TYPE, chatRoomType)
}
}
}
private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
class FavoriteMessagesFragment : Fragment(), FavoriteMessagesView {
private lateinit var chatRoomId: String
private lateinit var chatRoomType: String
private lateinit var adapter: ChatRoomAdapter
@Inject
lateinit var presenter: FavoriteMessagesPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
val bundle = arguments
if (bundle != null) {
chatRoomId = bundle.getString(INTENT_CHAT_ROOM_ID)
chatRoomType = bundle.getString(INTENT_CHAT_ROOM_TYPE)
} 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_favorite_messages)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupToolbar()
presenter.loadFavoriteMessages(chatRoomId)
}
override fun showFavoriteMessages(favoriteMessages: List<BaseViewModel<*>>) {
ui {
if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(chatRoomType, null, false)
recycler_view.adapter = adapter
val linearLayoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recycler_view.layoutManager = linearLayoutManager
recycler_view.itemAnimator = DefaultItemAnimator()
if (favoriteMessages.size > 10) {
recycler_view.addOnScrollListener(object :
EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(
page: Int,
totalItemsCount: Int,
recyclerView: RecyclerView?
) {
presenter.loadFavoriteMessages(chatRoomId)
}
})
}
no_messages_view.isVisible = favoriteMessages.isEmpty()
}
adapter.appendData(favoriteMessages)
}
}
override fun showMessage(resId: Int) {
ui { showToast(resId) }
}
override fun showMessage(message: String) {
ui { showToast(message) }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showLoading() {
ui { view_loading.isVisible = true }
}
override fun hideLoading() {
ui { view_loading.isVisible = false }
}
private fun setupToolbar() {
(activity as ChatRoomActivity).setupToolbarTitle(getString(R.string.title_favorite_messages))
}
}
\ No newline at end of file
...@@ -6,7 +6,6 @@ import android.support.v7.app.AppCompatActivity ...@@ -6,7 +6,6 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import chat.rocket.android.R import chat.rocket.android.R
...@@ -38,9 +37,12 @@ private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id" ...@@ -38,9 +37,12 @@ private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type" private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
class MembersFragment : Fragment(), MembersView { class MembersFragment : Fragment(), MembersView {
@Inject lateinit var presenter: MembersPresenter @Inject
private val adapter: MembersAdapter = MembersAdapter { memberViewModel -> presenter.toMemberDetails(memberViewModel) } lateinit var presenter: MembersPresenter
private val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) private val adapter: MembersAdapter =
MembersAdapter { memberViewModel -> presenter.toMemberDetails(memberViewModel) }
private val linearLayoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
...@@ -58,13 +60,15 @@ class MembersFragment : Fragment(), MembersView { ...@@ -58,13 +60,15 @@ class MembersFragment : Fragment(), MembersView {
} }
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = container?.inflate(R.layout.fragment_members) override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_members)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
(activity as AppCompatActivity).supportActionBar?.title = ""
setupRecyclerView() setupRecyclerView()
presenter.loadChatRoomsMembers(chatRoomId, chatRoomType) presenter.loadChatRoomsMembers(chatRoomId, chatRoomType)
} }
...@@ -75,8 +79,13 @@ class MembersFragment : Fragment(), MembersView { ...@@ -75,8 +79,13 @@ class MembersFragment : Fragment(), MembersView {
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
adapter.prependData(dataSet) adapter.prependData(dataSet)
if (dataSet.size >= 59) { // TODO Check why the API retorns the specified count -1 if (dataSet.size >= 59) { // TODO Check why the API retorns the specified count -1
recycler_view.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager) { recycler_view.addOnScrollListener(object :
override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) { EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(
page: Int,
totalItemsCount: Int,
recyclerView: RecyclerView?
) {
presenter.loadChatRoomsMembers(chatRoomId, chatRoomType, page * 60L) presenter.loadChatRoomsMembers(chatRoomId, chatRoomType, page * 60L)
} }
}) })
...@@ -84,18 +93,7 @@ class MembersFragment : Fragment(), MembersView { ...@@ -84,18 +93,7 @@ class MembersFragment : Fragment(), MembersView {
} else { } else {
adapter.appendData(dataSet) adapter.appendData(dataSet)
} }
if (it is ChatRoomActivity) {
it.showRoomTypeIcon(false)
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
(activity as ChatRoomActivity).showRoomTypeIcon(true)
return super.onOptionsItemSelected(item)
} }
return super.onOptionsItemSelected(item)
} }
override fun showLoading() { override fun showLoading() {
...@@ -129,6 +127,8 @@ class MembersFragment : Fragment(), MembersView { ...@@ -129,6 +127,8 @@ class MembersFragment : Fragment(), MembersView {
} }
private fun setupToolbar(totalMembers: Long) { private fun setupToolbar(totalMembers: Long) {
(activity as ChatRoomActivity?)?.setupToolbarTitle(getString(R.string.title_members, totalMembers)) (activity as ChatRoomActivity?)?.setupToolbarTitle(
getString(R.string.title_members, totalMembers)
)
} }
} }
\ No newline at end of file
...@@ -2,13 +2,13 @@ package chat.rocket.android.pinnedmessages.ui ...@@ -2,13 +2,13 @@ package chat.rocket.android.pinnedmessages.ui
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
...@@ -17,14 +17,13 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener ...@@ -17,14 +17,13 @@ import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesPresenter import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesPresenter
import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView import chat.rocket.android.pinnedmessages.presentation.PinnedMessagesView
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_pinned_messages.* import kotlinx.android.synthetic.main.fragment_pinned_messages.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String, chatRoomType: String) : Fragment { fun newInstance(chatRoomId: String, chatRoomType: String): Fragment {
return PinnedMessagesFragment().apply { return PinnedMessagesFragment().apply {
arguments = Bundle(1).apply { arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
...@@ -49,15 +48,19 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -49,15 +48,19 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
AndroidSupportInjection.inject(this) AndroidSupportInjection.inject(this)
val bundle = arguments val bundle = arguments
if (bundle != null){ if (bundle != null) {
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
}else{ } else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } 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_pinned_messages) override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = container?.inflate(R.layout.fragment_pinned_messages)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
...@@ -69,21 +72,27 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -69,21 +72,27 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) { override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) {
ui { ui {
if (recycler_view_pinned.adapter == null){ if (recycler_view_pinned.adapter == null) {
adapter = ChatRoomAdapter(chatRoomType,"",null,false) adapter = ChatRoomAdapter(chatRoomType, null, false)
recycler_view_pinned.adapter = adapter recycler_view_pinned.adapter = adapter
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL,false) val linearLayoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recycler_view_pinned.layoutManager = linearLayoutManager recycler_view_pinned.layoutManager = linearLayoutManager
recycler_view_pinned.itemAnimator = DefaultItemAnimator() recycler_view_pinned.itemAnimator = DefaultItemAnimator()
if (pinnedMessages.size > 10){ if (pinnedMessages.size > 10) {
recycler_view_pinned.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager){ recycler_view_pinned.addOnScrollListener(object :
override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) { EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(
page: Int,
totalItemsCount: Int,
recyclerView: RecyclerView?
) {
presenter.loadPinnedMessages(chatRoomId) presenter.loadPinnedMessages(chatRoomId)
} }
}) })
} }
togglePinView(pinnedMessages.size) pin_view.isVisible = pinnedMessages.isEmpty()
} }
adapter.appendData(pinnedMessages) adapter.appendData(pinnedMessages)
} }
...@@ -104,22 +113,14 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -104,22 +113,14 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showLoading() { override fun showLoading() {
ui{ view_loading.setVisible(true) } ui { view_loading.isVisible = true }
} }
override fun hideLoading() { override fun hideLoading() {
ui { view_loading.setVisible(false) } ui { view_loading.isVisible = false }
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as ChatRoomActivity).setupToolbarTitle(getString(R.string.title_pinned_messages)) (activity as ChatRoomActivity).setupToolbarTitle(getString(R.string.title_pinned_messages))
} }
private fun togglePinView(size : Int){
if (size == 0){
pin_view.setVisible(true)
}else{
pin_view.setVisible(false)
}
}
} }
\ No newline at end of file
<vector android:autoMirrored="true" android:height="24dp" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF" android:viewportHeight="24.0" android:width="24dp"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:height="24dp"
<path android:fillColor="#FF000000" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/> android:tint="#FFFFFF"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="13dp"
android:height="16dp"
android:viewportWidth="13.0"
android:viewportHeight="16.0">
<path
android:pathData="M6.626,11.495L4.505,11.495L3.714,16L1.703,16L2.495,11.495L0,11.495L0,9.604L2.824,9.604L3.374,6.484L0.824,6.484L0.824,4.571L3.714,4.571L4.516,0L6.516,0L5.714,4.571L7.846,4.571L8.648,0L10.659,0L9.857,4.571L12.264,4.571L12.264,6.484L9.516,6.484L8.967,9.604L11.429,9.604L11.429,11.495L8.637,11.495L7.846,16L5.835,16L6.626,11.495ZM4.835,9.604L6.956,9.604L7.505,6.484L5.374,6.484L4.835,9.604Z"
android:strokeColor="#00000000"
android:fillType="evenOdd"
android:fillColor="#000000"
android:strokeWidth="1"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22.548,9l0.452,-2h-5.364l1.364,-6h-2l-1.364,6h-5l1.364,-6h-2l-1.364,6h-6.184l-0.452,2h6.182l-1.364,6h-5.36l-0.458,2h5.364l-1.364,6h2l1.364,-6h5l-1.364,6h2l1.364,-6h6.185l0.451,-2h-6.182l1.364,-6h5.366zM13.818,15h-5l1.364,-6h5l-1.364,6z" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportHeight="20.0"
android:viewportWidth="20.0">
<path
android:fillColor="#FF000000"
android:pathData="M13.6,13.47c-0.91,0.953 -2.191,1.545 -3.61,1.545 -2.756,0 -4.99,-2.234 -4.99,-4.99 0,-0.009 0,-0.018 0,-0.026v0.001c0,-2.761 2.239,-5 5,-5 1.131,0 2.175,0.376 3.013,1.009l-0.013,-0.009v-1h2v6.5c0,0.828 0.672,1.5 1.5,1.5s1.5,-0.672 1.5,-1.5v0,-1.5c-0.003,-4.416 -3.584,-7.994 -8,-7.994 -4.418,0 -8,3.582 -8,8s3.582,8 8,8c1.305,0 2.537,-0.312 3.625,-0.867l-0.045,0.021 0.9,1.79c-1.305,0.668 -2.847,1.06 -4.48,1.06 -5.523,0 -10,-4.477 -10,-10s4.477,-10 10,-10c5.519,0 9.994,4.472 10,9.99v0.001h-0.01v1.5c0,0.003 0,0.007 0,0.01 0,1.933 -1.567,3.5 -3.5,3.5 -1.202,0 -2.262,-0.606 -2.892,-1.528l-0.008,-0.012zM10,13c1.657,0 3,-1.343 3,-3s-1.343,-3 -3,-3v0c-1.657,0 -3,1.343 -3,3s1.343,3 3,3v0z" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M18,10v-4c0,-3.313 -2.687,-6 -6,-6s-6,2.687 -6,6v4h-3v14h18v-14h-3zM8,6c0,-2.206 1.794,-4 4,-4s4,1.794 4,4v4h-8v-4zM19,22h-14v-10h14v10z" />
</vector>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<include <include
android:id="@+id/layout_app_bar" android:id="@+id/layout_app_bar"
layout="@layout/app_bar_chat_room" /> layout="@layout/app_bar" />
<FrameLayout <FrameLayout
android:id="@+id/fragment_container" android:id="@+id/fragment_container"
......
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:theme="@style/AppTheme"
tools:context=".chatroom.ui.PinnedMessagesActivity">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar_chat_room" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/layout_app_bar" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.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">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="?android:attr/homeAsUpIndicator"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.constraint.ConstraintLayout
android:id="@+id/toolbar_content_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- TODO implement -->
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_room_avatar"
android:layout_width="30dp"
android:layout_height="30dp"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:roundAsCircle="true" />
<TextView
android:id="@+id/text_room_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:drawablePadding="@dimen/text_view_drawable_padding"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
tools:text="Developers" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".favoritemessages.ui.FavoriteMessagesFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
app:indicatorColor="@color/black"
app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<ImageView
android:id="@+id/image_star"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_action_message_star_24dp"
android:tint="@color/icon_grey"
app:layout_constraintBottom_toTopOf="@+id/text_no_favorite_messages"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/text_no_favorite_messages"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/no_favorite_messages"
android:textColor="@color/colorSecondaryText"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/text_no_favorite_messages_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_star" />
<TextView
android:id="@+id/text_no_favorite_messages_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/no_favorite_description"
android:textAlignment="center"
android:textColor="@color/colorSecondaryTextLight"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_no_favorite_messages" />
<android.support.constraint.Group
android:id="@+id/no_messages_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="text_no_favorite_messages_description,image_star,text_no_favorite_messages"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -3,18 +3,14 @@ ...@@ -3,18 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
tools:context=".pinnedmessages.ui.PinnedMessagesFragment">
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view_pinned" android:id="@+id/recycler_view_pinned"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent" android:scrollbars="vertical" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<com.wang.avi.AVLoadingIndicatorView <com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading" android:id="@+id/view_loading"
...@@ -38,46 +34,46 @@ ...@@ -38,46 +34,46 @@
android:layout_height="100dp" android:layout_height="100dp"
android:src="@drawable/ic_action_message_pin_24dp" android:src="@drawable/ic_action_message_pin_24dp"
android:tint="@color/icon_grey" android:tint="@color/icon_grey"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@id/tv_pin_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tv_pin_title"
app:layout_constraintVertical_chainStyle="packed" /> app:layout_constraintVertical_chainStyle="packed" />
<TextView <TextView
android:id="@+id/tv_pin_title" android:id="@+id/tv_pin_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/no_pinned_messages" android:text="@string/no_pinned_messages"
app:layout_constraintStart_toStartOf="parent" android:textColor="@color/colorSecondaryText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_pin_icon"
app:layout_constraintBottom_toTopOf="@id/tv_pin_description"
android:textSize="20sp" android:textSize="20sp"
android:layout_marginTop="24dp"
android:textStyle="bold" android:textStyle="bold"
android:textColor="@color/colorSecondaryText"/> app:layout_constraintBottom_toTopOf="@id/tv_pin_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_pin_icon" />
<TextView <TextView
android:id="@+id/tv_pin_description" android:id="@+id/tv_pin_description"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/no_pinned_description"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_pin_title"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/no_pinned_description"
android:textAlignment="center" android:textAlignment="center"
android:textColor="@color/colorSecondaryTextLight"
android:textSize="16sp" android:textSize="16sp"
android:textColor="@color/colorSecondaryTextLight"/> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_pin_title" />
<android.support.constraint.Group <android.support.constraint.Group
android:id="@+id/pin_view" android:id="@+id/pin_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_pin_description,iv_pin_icon,tv_pin_title"
android:visibility="gone" android:visibility="gone"
app:constraint_referenced_ids="tv_pin_description,iv_pin_icon,tv_pin_title"
tools:visibility="visible" /> tools:visibility="visible" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -11,4 +11,9 @@ ...@@ -11,4 +11,9 @@
android:id="@+id/action_pinned_messages" android:id="@+id/action_pinned_messages"
android:title="@string/title_pinned_messages" android:title="@string/title_pinned_messages"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_favorite_messages"
android:title="@string/title_favorite_messages"
app:showAsAction="never" />
</menu> </menu>
\ No newline at end of file
...@@ -163,7 +163,13 @@ ...@@ -163,7 +163,13 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">Mensajes fijados</string> <string name="title_pinned_messages">Mensajes fijados</string>
<string name="no_pinned_messages">Sin mensajes fijadas</string> <string name="no_pinned_messages">Sin mensajes fijadas</string>
<string name="no_pinned_description">Todas las mensajes fijadas\naparecen aquí.</string> <string name="no_pinned_description">Todas las mensajes fijadas\naparecen aquí</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string name="title_favorite_messages">Favorite Messages</string>
<string name="no_favorite_messages">No favorite messages</string>
<string name="no_favorite_description">All the favorite messages\nappear here</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">Tamaño del archivo (%1$d bytes) excedió el tamaño máximo de carga de %2$d bytes</string> <string name="max_file_size_exceeded">Tamaño del archivo (%1$d bytes) excedió el tamaño máximo de carga de %2$d bytes</string>
......
...@@ -164,7 +164,13 @@ ...@@ -164,7 +164,13 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">Messages épinglés</string> <string name="title_pinned_messages">Messages épinglés</string>
<string name="no_pinned_messages">Aucun message épinglé</string> <string name="no_pinned_messages">Aucun message épinglé</string>
<string name="no_pinned_description">Tous les messages épinglés\napparaissent ici.</string> <string name="no_pinned_description">Tous les messages épinglés\napparaissent ici</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string name="title_favorite_messages">Favorite Messages</string>
<string name="no_favorite_messages">No favorite messages</string>
<string name="no_favorite_description">All the favorite messages\nappear here</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">Taille du fichier (%1$d bytes) dépassé la taille de téléchargement maximale de %2$d bytes</string> <string name="max_file_size_exceeded">Taille du fichier (%1$d bytes) dépassé la taille de téléchargement maximale de %2$d bytes</string>
......
...@@ -167,6 +167,12 @@ ...@@ -167,6 +167,12 @@
<string name="no_pinned_messages">कोई पिन संदेश नहीं</string> <string name="no_pinned_messages">कोई पिन संदेश नहीं</string>
<string name="no_pinned_description">सभी पिन किए गए संदेश यहां\nदिखाई देते हैं।</string> <string name="no_pinned_description">सभी पिन किए गए संदेश यहां\nदिखाई देते हैं।</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string name="title_favorite_messages">Favorite Messages</string>
<string name="no_favorite_messages">No favorite messages</string>
<string name="no_favorite_description">All the favorite messages\nappear here</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">फ़ाइल का आकार %1$d बाइट्स ने %2$d बाइट्स के अधिकतम अपलोड आकार को पार कर लिया है</string> <string name="max_file_size_exceeded">फ़ाइल का आकार %1$d बाइट्स ने %2$d बाइट्स के अधिकतम अपलोड आकार को पार कर लिया है</string>
......
...@@ -155,6 +155,12 @@ ...@@ -155,6 +155,12 @@
<string name="no_pinned_messages">Nenhuma mensagem pinada</string> <string name="no_pinned_messages">Nenhuma mensagem pinada</string>
<string name="no_pinned_description">Todas as mensagens pinadas\naparecerão aqui</string> <string name="no_pinned_description">Todas as mensagens pinadas\naparecerão aqui</string>
<!-- Favorite Messages -->
<!-- TODO Add proper translation-->
<string name="title_favorite_messages">Messagens Favoritas</string>
<string name="no_favorite_messages">Nenhuma messagem favorita</string>
<string name="no_favorite_description">Todas as mensagens favoritas\naparecerão aqui</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string> <string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string>
......
This diff is collapsed.
...@@ -154,7 +154,12 @@ ...@@ -154,7 +154,12 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">Pinned Messages</string> <string name="title_pinned_messages">Pinned Messages</string>
<string name="no_pinned_messages">No pinned messages</string> <string name="no_pinned_messages">No pinned messages</string>
<string name="no_pinned_description">All the pinned messages\nappear here.</string> <string name="no_pinned_description">All the pinned messages\nappear here</string>
<!-- Favorite Messages -->
<string name="title_favorite_messages">Favorite Messages</string>
<string name="no_favorite_messages">No favorite messages</string>
<string name="no_favorite_description">All the favorite messages\nappear here</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string> <string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment