Commit 2e5f7c8b authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Add Upload File feature

parent 05d9453c
......@@ -16,9 +16,9 @@ import chat.rocket.android.authentication.login.presentation.LoginView
import chat.rocket.android.helper.AnimationHelper
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_log_in.*
import javax.inject.Inject
......
......@@ -11,7 +11,7 @@ import chat.rocket.android.R
import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.util.*
import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_server.*
import javax.inject.Inject
......
......@@ -14,8 +14,8 @@ import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.helper.AnimationHelper
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_sign_up.*
import javax.inject.Inject
......
......@@ -14,8 +14,8 @@ import chat.rocket.android.R
import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter
import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
import chat.rocket.android.helper.AnimationHelper
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
import javax.inject.Inject
......
......@@ -6,6 +6,7 @@ import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.domain.GetSettingsInteractor
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException
import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.realtime.State
......@@ -16,6 +17,7 @@ import chat.rocket.core.internal.rest.messages
import chat.rocket.core.internal.rest.sendMessage
import chat.rocket.core.model.Message
import chat.rocket.core.model.Value
import chat.rocket.core.model.attachment.Attachment
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch
......@@ -80,14 +82,27 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
view.showGenericErrorMessage()
}
view.enableMessageInput()
}
}
}
fun sendFile(chatRoomId: String, fileName: String) {
launchUI(strategy) {
view.showLoading()
try {
// client.sendMessage(chatRoomId)
} catch (ex: RocketChatException) {
} finally {
view.hideLoading()
}
}
}
fun subscribeMessages(roomId: String) {
client.addStateChannel(stateChannel)
launch(CommonPool + strategy.jobs) {
......
package chat.rocket.android.chatroom.presentation
import android.net.Uri
import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
......@@ -20,6 +21,13 @@ interface ChatRoomView : LoadingView, MessageView {
*/
fun sendMessage(text: String)
/**
* Send a file to a chat room.
*
* @param uri The file URI to send.
*/
fun sendFile(uri: Uri)
/**
* Shows a (recent) message sent to a chat room.
*
......
......@@ -7,7 +7,7 @@ import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R
import chat.rocket.android.util.addFragment
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.textContent
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
......
......@@ -8,8 +8,8 @@ import chat.rocket.android.R
import chat.rocket.android.chatroom.viewmodel.AttachmentType
import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.player.PlayerActivity
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import com.facebook.drawee.view.SimpleDraweeView
import com.stfalcon.frescoimageviewer.ImageViewer
import kotlinx.android.synthetic.main.avatar.view.*
......
package chat.rocket.android.chatroom.ui
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.support.v4.app.Fragment
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
......@@ -14,11 +18,10 @@ import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.*
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.message_composer.*
import javax.inject.Inject
......@@ -37,6 +40,7 @@ private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
private const val REQUEST_CODE_FOR_PERFORM_SAF = 42
class ChatRoomFragment : Fragment(), ChatRoomView {
@Inject lateinit var presenter: ChatRoomPresenter
......@@ -45,6 +49,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
private lateinit var chatRoomType: String
private var isChatRoomReadOnly: Boolean = false
private lateinit var adapter: ChatRoomAdapter
// For reveal and unreveal anim.
private val hypotenuse by lazy { Math.hypot(relative_layout.width.toDouble(), relative_layout.height.toDouble()).toFloat() }
private val max by lazy { Math.max(layout_message_attachment_options.width.toDouble(), layout_message_attachment_options.height.toDouble()).toFloat() }
private val centerX by lazy { recycler_view.right }
private val centerY by lazy { recycler_view.bottom }
private lateinit var handler: Handler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......@@ -66,6 +76,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
presenter.loadMessages(chatRoomId, chatRoomType)
handler = Handler()
setupComposer()
}
......@@ -74,6 +85,14 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
super.onDestroyView()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (requestCode == REQUEST_CODE_FOR_PERFORM_SAF && resultCode == Activity.RESULT_OK) {
if (resultData != null) {
sendFile(resultData.data)
}
}
}
override fun showMessages(dataSet: List<MessageViewModel>) {
activity?.apply {
if (recycler_view.adapter == null) {
......@@ -101,6 +120,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
}
}
override fun sendFile(uri: Uri) {
var fileName: String? = null
activity?.apply {
fileName = uri.getFileName(this)
}
if (fileName != null) {
presenter.sendFile(chatRoomId, fileName.toString())
}
}
override fun showNewMessage(message: MessageViewModel) {
text_message.textContent = ""
adapter.addItem(message)
......@@ -108,12 +137,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
}
override fun disableMessageInput() {
text_send.isEnabled = false
button_send.isEnabled = false
text_message.isEnabled = false
}
override fun enableMessageInput(clear: Boolean) {
text_send.isEnabled = true
button_send.isEnabled = true
text_message.isEnabled = true
if (clear) text_message.textContent = ""
}
......@@ -133,9 +162,68 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
private fun setupComposer() {
if (isChatRoomReadOnly) {
text_room_is_read_only.setVisible(true)
top_container.setVisible(false)
input_container.setVisible(false)
} else {
text_send.setOnClickListener { sendMessage(text_message.textContent) }
var playAnimation = true
text_message.asObservable(0)
.subscribe({ t ->
if (t.isNotEmpty() && playAnimation) {
button_show_attachment_options.fadeInOrOut(1F, 0F, 120)
button_send.fadeInOrOut(0F, 1F, 120)
playAnimation = false
}
if (t.isEmpty()) {
button_send.fadeInOrOut(1F, 0F, 120)
button_show_attachment_options.fadeInOrOut(0F, 1F, 120)
playAnimation = true
}
})
button_send.setOnClickListener { sendMessage(text_message.textContent) }
button_show_attachment_options.setOnClickListener {
if (layout_message_attachment_options.isShown) {
hideAttachmentOptions()
} else {
showAttachmentOptions()
}
}
view_dim.setOnClickListener { hideAttachmentOptions() }
button_files.setOnClickListener {
handler.postDelayed({
performSAF()
}, 300)
handler.postDelayed({
hideAttachmentOptions()
}, 600)
}
}
}
private fun showAttachmentOptions() {
view_dim.setVisible(true)
// Play anim.
button_show_attachment_options.rotateBy(45F)
layout_message_attachment_options.circularRevealOrUnreveal(centerX, centerY, 0F, hypotenuse)
}
private fun hideAttachmentOptions() {
// Play anim.
button_show_attachment_options.rotateBy(-45F)
layout_message_attachment_options.circularRevealOrUnreveal(centerX, centerY, max, 0F)
view_dim.setVisible(false)
}
private fun performSAF() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF)
}
}
\ No newline at end of file
......@@ -10,9 +10,9 @@ import android.widget.ImageView
import android.widget.TextView
import chat.rocket.android.R
import chat.rocket.android.helper.UrlHelper
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import chat.rocket.common.model.RoomType
import chat.rocket.core.model.ChatRoom
import com.facebook.drawee.view.SimpleDraweeView
......
......@@ -14,8 +14,8 @@ import chat.rocket.android.R
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import chat.rocket.android.chatrooms.presentation.ChatRoomsView
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.DividerItemDecoration
import chat.rocket.core.model.ChatRoom
import dagger.android.support.AndroidSupportInjection
......
......@@ -5,7 +5,7 @@ import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.widget.TextView
import chat.rocket.android.util.ifEmpty
import chat.rocket.android.util.extensions.ifEmpty
object TextHelper {
......
......@@ -11,10 +11,10 @@ import chat.rocket.android.R
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.profile.presentation.ProfilePresenter
import chat.rocket.android.profile.presentation.ProfileView
import chat.rocket.android.util.getObservable
import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisible
import chat.rocket.android.util.textContent
import chat.rocket.android.util.extensions.asObservable
import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.textContent
import dagger.android.support.AndroidSupportInjection
import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.app_bar.*
......@@ -126,7 +126,7 @@ class ProfileFragment : Fragment(), ProfileView, ActionMode.Callback {
}
private fun listenToChanges() {
Observables.combineLatest(text_name.getObservable(), text_username.getObservable(), text_email.getObservable()).subscribe({ t ->
Observables.combineLatest(text_name.asObservable(), text_username.asObservable(), text_email.asObservable()).subscribe({ t ->
if (t.first.toString() != currentName || t.second.toString() != currentUsername || t.third.toString() != currentEmail) {
startActionMode()
} else {
......
package chat.rocket.android.util.extensions
import android.view.View
import android.view.ViewAnimationUtils
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
fun View.rotateBy(value: Float, duration: Long = 200) {
animate()
.rotationBy(value)
.setDuration(duration)
.start()
}
fun View.fadeInOrOut(startValue: Float, finishValue: Float, duration: Long = 200) {
animate()
.alpha(startValue)
.setDuration(duration)
.setInterpolator(DecelerateInterpolator())
.withEndAction({
animate()
.alpha(finishValue)
.setDuration(duration)
.setInterpolator(AccelerateInterpolator()).start()
}).start()
if (startValue > finishValue) {
setVisible(false)
} else {
setVisible(true)
}
}
fun View.circularRevealOrUnreveal(centerX: Int, centerY: Int, startRadius: Float, endRadius: Float, duration: Long = 600) {
val anim = ViewAnimationUtils.createCircularReveal(this, centerX, centerY, startRadius, endRadius)
anim.duration = duration
if (startRadius < endRadius) {
setVisible(true)
} else {
setVisible(false)
}
anim.start()
}
\ No newline at end of file
package chat.rocket.android.util.extensions
import android.widget.EditText
import com.jakewharton.rxbinding2.widget.RxTextView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit
fun EditText.asObservable(debounceTimeout: Long = 100): Observable<CharSequence> {
return RxTextView.textChanges(this)
.debounce(debounceTimeout, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
}
\ No newline at end of file
package chat.rocket.android.util.extensions
import android.app.Activity
import android.net.Uri
import android.widget.TextView
import android.provider.OpenableColumns
fun String.ifEmpty(value: String): String {
if (isEmpty()) {
return value
}
return this
}
var TextView.textContent: String
get() = text.toString()
set(value) {
text = value
}
var TextView.hintContent: String
get() = hint.toString()
set(value) {
hint = value
}
fun Uri.getFileName(activity: Activity): String? {
val cursor = activity.contentResolver.query(this, null, null, null, null, null)
var fileName: String? = null
cursor.use { cursor ->
if (cursor != null && cursor.moveToFirst()) {
fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
}
return fileName
}
fun Uri.getFileSize(activity: Activity): String? {
val cursor = activity.contentResolver.query(this, null, null, null, null, null)
var fileSize: String? = null
cursor.use { cursor ->
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
if (cursor != null && cursor.moveToFirst()) {
if (!cursor.isNull(sizeIndex)) {
fileSize = cursor.getString(sizeIndex)
}
}
}
return fileSize
}
\ No newline at end of file
package chat.rocket.android.util
package chat.rocket.android.util.extensions
import android.support.annotation.LayoutRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import com.jakewharton.rxbinding2.widget.RxTextView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import java.util.concurrent.TimeUnit
fun String.ifEmpty(value: String): String {
if (isEmpty()) {
return value
}
return this
}
fun View.setVisible(visible: Boolean) {
visibility = if (visible) {
......@@ -28,23 +15,4 @@ fun View.setVisible(visible: Boolean) {
fun ViewGroup.inflate(@LayoutRes resource: Int): View {
return LayoutInflater.from(context).inflate(resource, this, false)
}
var TextView.textContent: String
get() = text.toString()
set(value) {
text = value
}
var TextView.hintContent: String
get() = hint.toString()
set(value) {
hint = value
}
fun EditText.getObservable(): Observable<CharSequence> {
return RxTextView.textChanges(this)
.debounce(100, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF2F343D"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="17.0"
android:viewportWidth="18.0">
<path
android:fillColor="#FF1D74F5"
android:fillType="nonZero"
android:pathData="M4.221,11.799L10.444,5.576C10.97,5.05 11.833,5.067 12.383,5.617C12.928,6.163 12.946,7.034 12.423,7.557L6.195,13.785C5.226,14.754 3.613,14.717 2.599,13.704C1.582,12.687 1.546,11.08 2.52,10.106L9.295,3.331C10.713,1.913 13.07,1.966 14.552,3.448C16.035,4.931 16.087,7.287 14.668,8.706L7.898,15.476L8.747,16.324L15.516,9.555C17.383,7.688 17.316,4.588 15.364,2.636C13.414,0.686 10.313,0.616 8.446,2.483L1.671,9.258C0.248,10.681 0.302,13.03 1.788,14.515C3.27,15.997 5.626,16.051 7.044,14.633L13.272,8.405C14.242,7.435 14.209,5.82 13.195,4.805C12.175,3.786 10.569,3.754 9.595,4.728L3.373,10.95L4.221,11.799Z" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="20.0"
android:viewportWidth="20.0">
<path
android:fillColor="#FF2F343D"
android:fillType="evenOdd"
android:pathData="M12.4,7.6m-1.2,0a1.2,1.2 0,1 1,2.4 0a1.2,1.2 0,1 1,-2.4 0" />
<path
android:fillColor="#FF2F343D"
android:fillType="evenOdd"
android:pathData="M7.6,7.6m-1.2,0a1.2,1.2 0,1 1,2.4 0a1.2,1.2 0,1 1,-2.4 0" />
<path
android:pathData="M10,10m-8.4,0a8.4,8.4 0,1 1,16.8 0a8.4,8.4 0,1 1,-16.8 0"
android:strokeColor="#FF2F343D"
android:strokeWidth="1.5" />
<path
android:pathData="M6.606,12.794L6.606,12.794C8.48,14.669 11.52,14.669 13.394,12.794"
android:strokeColor="#FF2F343D"
android:strokeWidth="1.5" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="20.0"
android:viewportWidth="22.0">
<path
android:fillColor="#FF1D74F5"
android:fillType="nonZero"
android:pathData="M0.869,1.32C0.731,0.987 0.79,0.565 1.045,0.276C1.281,0.01 1.634,-0.079 1.967,0.076L20.645,9.134C20.939,9.29 21.136,9.645 21.136,10C21.155,10.377 20.939,10.71 20.645,10.866L1.967,19.924C1.634,20.079 1.281,19.99 1.045,19.724C0.79,19.435 0.712,19.036 0.869,18.68L4.263,10L0.869,1.32ZM18.193,10L3.262,2.741L5.832,9.29L9.953,9.334C10.404,9.312 10.777,9.734 10.777,10.266C10.796,10.777 10.423,11.199 9.953,11.199L5.636,11.199L3.262,17.259L18.193,10Z" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/colorLightTheme" />
<corners
android:radius="6dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/colorBackgroundContentFileAttachment" />
<corners
android:radius="6dp" />
<stroke
android:width="2dp"
android:color="@color/colorDrawableTintGrey" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/colorBackgroundFileAttachment" />
<corners
android:radius="6dp" />
</shape>
\ No newline at end of file
......@@ -2,10 +2,21 @@
<RelativeLayout 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/relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="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"
tools:visibility="visible" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
......@@ -13,21 +24,29 @@
android:layout_above="@+id/layout_message_composer"
android:scrollbars="vertical" />
<View
android:id="@+id/view_dim"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/layout_message_composer"
android:background="@color/colorDim"
android:visibility="gone" />
<include
android:id="@+id/layout_message_attachment_options"
layout="@layout/message_attachment_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_above="@+id/layout_message_composer"
android:visibility="gone"
tools:visibility="visible" />
<include
android:id="@+id/layout_message_composer"
layout="@layout/message_composer"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<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"
tools:visibility="visible" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/attachment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text_file_attachment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/style_message_file_upload_content_bg"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_files_24dp"
android:ellipsize="end"
android:gravity="center"
android:maxLength="20"
android:maxLines="1"
android:padding="5dp"
android:visibility="gone"
tools:text="brazilian_anthem.mp4"
tools:visibility="visible" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_attachment"
android:layout_width="match_parent"
android:layout_height="150dp"
android:visibility="gone"
fresco:actualImageScaleType="fitStart"
fresco:placeholderImage="@drawable/image_dummy"
tools:visibility="visible"
android:visibility="gone"/>
tools:visibility="visible" />
<FrameLayout
android:id="@+id/audio_video_attachment"
......@@ -23,17 +39,18 @@
android:background="@color/black"
android:visibility="gone"
tools:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/exo_controls_play"/>
android:src="@drawable/exo_controls_play" />
</FrameLayout>
<TextView
android:id="@+id/file_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Filename.png"/>
tools:text="Filename.png" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/style_attachment_options"
android:orientation="vertical">
<Button
android:id="@+id/button_files"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="20dp"
android:drawableStart="@drawable/ic_files_24dp"
android:gravity="start|center"
android:text="@string/action_files" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
......@@ -22,36 +22,51 @@
app:layout_constraintTop_toBottomOf="@+id/divider" />
<LinearLayout
android:id="@+id/top_container"
android:id="@+id/input_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:paddingBottom="10dp"
app:layout_constraintTop_toBottomOf="@+id/divider">
<ImageButton
android:id="@+id/button_add_reaction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/msg_content_description_show_attachment_options"
android:src="@drawable/ic_reaction_24dp" />
<EditText
android:id="@+id/text_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@android:color/transparent"
android:hint="@string/msg_message"
android:maxLines="4" />
<TextView
android:id="@+id/text_send"
style="@style/TextAppearance.AppCompat.Medium"
<ImageButton
android:id="@+id/button_show_attachment_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/msg_content_description_show_attachment_options"
android:src="@drawable/ic_add_24dp" />
<ImageButton
android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:text="@string/action_send"
android:textColor="@color/colorAccent" />
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/msg_content_description_send_message"
android:src="@drawable/ic_send_24dp"
android:visibility="gone" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
......@@ -11,12 +11,12 @@
<!-- Actions -->
<string name="action_connect">Conectar</string>
<string name="action_send">Enviar</string>
<string name="action_terms_of_service">Termos de Serviço</string>
<string name="action_privacy_policy">Política de Privacidade</string>
<string name="action_search">Pesquisar</string>
<string name="action_update">Atualizar</string>
<string name="action_logout">Sair</string>
<string name="action_files">Arquivos</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">Sem conexão à internet</string>
......@@ -44,6 +44,8 @@
<string name="msg_content_description_log_in_using_meteor">Fazer login através do Meteor</string>
<string name="msg_content_description_log_in_using_twitter">Fazer login através do Twitter</string>
<string name="msg_content_description_log_in_using_gitlab">Fazer login através do Gitlab</string>
<string name="msg_content_description_send_message">Enviar mensagem</string>
<string name="msg_content_description_show_attachment_options">Mostrar opções de anexo</string>
<string name="msg_you">Você</string>
<string name="msg_unknown">Desconhecido</string>
......
......@@ -15,7 +15,14 @@
<color name="colorDividerMessageComposer">#D8D8D8</color>
<color name="colorLightTheme">#FBFBFB</color>
<color name="colorDim">#99000000</color>
<color name="colorBackgroundFileAttachment">#E2FFC8</color>
<color name="colorBackgroundContentFileAttachment">#FFD8F5C0</color>
<color name="white">#FFFFFFFF</color>
<color name="black">#FF000000</color>
</resources>
\ No newline at end of file
......@@ -12,12 +12,12 @@
<!-- Actions -->
<string name="action_connect">Connect</string>
<string name="action_send">Send</string>
<string name="action_terms_of_service">Terms of Service</string>
<string name="action_privacy_policy">Privacy Policy</string>
<string name="action_search">Search</string>
<string name="action_update">Update</string>
<string name="action_logout">Log Out</string>
<string name="action_files">Files</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">No internet connection</string>
......@@ -46,6 +46,8 @@
<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>
<string name="msg_content_description_send_message">Send message</string>
<string name="msg_content_description_show_attachment_options">Show attachment options</string>
<string name="msg_you">You</string>
<string name="msg_unknown">Unknown</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