diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt
index bcc095ad2d..ea91b3a6d0 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt
@@ -4,11 +4,15 @@ import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
+import android.widget.RelativeLayout
import kotlinx.android.synthetic.main.view_input_bar.view.*
import network.loki.messenger.R
class InputBar : LinearLayout {
+ private val attachmentsButton by lazy { InputBarButton(context, R.drawable.ic_plus_24) }
+ private val microphoneButton by lazy { InputBarButton(context, R.drawable.ic_microphone) }
+
// region Lifecycle
constructor(context: Context) : super(context) {
setUpViewHierarchy()
@@ -24,7 +28,11 @@ class InputBar : LinearLayout {
private fun setUpViewHierarchy() {
LayoutInflater.from(context).inflate(R.layout.view_input_bar, this)
+ attachmentsButtonContainer.addView(attachmentsButton)
+ attachmentsButton.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
attachmentsButton.setOnClickListener { }
+ microphoneButtonContainer.addView(microphoneButton)
+ microphoneButton.layoutParams = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
microphoneButton.setOnClickListener { }
}
// endregion
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBarButton.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBarButton.kt
new file mode 100644
index 0000000000..0a311c9b1a
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBarButton.kt
@@ -0,0 +1,100 @@
+package org.thoughtcrime.securesms.conversation.v2.input_bar
+
+import android.animation.PointFEvaluator
+import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.ColorStateList
+import android.graphics.PointF
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.MotionEvent
+import android.widget.ImageView
+import android.widget.RelativeLayout
+import androidx.annotation.DrawableRes
+import network.loki.messenger.R
+import org.thoughtcrime.securesms.loki.utilities.*
+import org.thoughtcrime.securesms.loki.views.GlowViewUtilities
+import org.thoughtcrime.securesms.loki.views.InputBarButtonImageViewContainer
+
+class InputBarButton : RelativeLayout {
+ @DrawableRes private var iconID = 0
+
+ companion object {
+ val animationDuration = 250.toLong()
+ }
+
+ private val expandedImageViewPosition by lazy { PointF(0.0f, 0.0f) }
+ private val collapsedImageViewPosition by lazy { PointF((expandedSize - collapsedSize) / 2, (expandedSize - collapsedSize) / 2) }
+
+ val expandedSize by lazy { resources.getDimension(R.dimen.input_bar_button_expanded_size) }
+ val collapsedSize by lazy { resources.getDimension(R.dimen.input_bar_button_collapsed_size) }
+
+ private val imageViewContainer by lazy {
+ val result = InputBarButtonImageViewContainer(context)
+ val size = collapsedSize.toInt()
+ result.layoutParams = LayoutParams(size, size)
+ result.setBackgroundResource(R.drawable.input_bar_button_background)
+ result.mainColor = resources.getColorWithID(R.color.input_bar_button_background, context.theme)
+ result
+ }
+
+ private val imageView by lazy {
+ val result = ImageView(context)
+ val size = toPx(16, resources)
+ result.layoutParams = LayoutParams(size, size)
+ result.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ result.setImageResource(iconID)
+ result.imageTintList = ColorStateList.valueOf(resources.getColorWithID(R.color.text, context.theme))
+ result
+ }
+
+ constructor(context: Context) : super(context) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { throw IllegalAccessException("Use InputBarButton(context:iconID:) instead.") }
+
+ constructor(context: Context, @DrawableRes iconID: Int) : super(context) {
+ this.iconID = iconID
+ val size = resources.getDimension(R.dimen.input_bar_button_expanded_size).toInt()
+ val layoutParams = LayoutParams(size, size)
+ this.layoutParams = layoutParams
+ addView(imageViewContainer)
+ imageViewContainer.x = collapsedImageViewPosition.x
+ imageViewContainer.y = collapsedImageViewPosition.y
+ imageViewContainer.addView(imageView)
+ val imageViewLayoutParams = imageView.layoutParams as LayoutParams
+ imageViewLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT)
+ imageView.layoutParams = imageViewLayoutParams
+ gravity = Gravity.TOP or Gravity.LEFT // Intentionally not Gravity.START
+ }
+
+ fun expand() {
+ GlowViewUtilities.animateColorChange(context, imageViewContainer, R.color.input_bar_button_background, R.color.accent)
+ imageViewContainer.animateSizeChange(R.dimen.input_bar_button_collapsed_size, R.dimen.input_bar_button_expanded_size, animationDuration)
+ animateImageViewContainerPositionChange(collapsedImageViewPosition, expandedImageViewPosition)
+ }
+
+ fun collapse() {
+ GlowViewUtilities.animateColorChange(context, imageViewContainer, R.color.accent, R.color.input_bar_button_background)
+ imageViewContainer.animateSizeChange(R.dimen.input_bar_button_expanded_size, R.dimen.input_bar_button_collapsed_size, animationDuration)
+ animateImageViewContainerPositionChange(expandedImageViewPosition, collapsedImageViewPosition)
+ }
+
+ private fun animateImageViewContainerPositionChange(startPosition: PointF, endPosition: PointF) {
+ val animation = ValueAnimator.ofObject(PointFEvaluator(), startPosition, endPosition)
+ animation.duration = animationDuration
+ animation.addUpdateListener { animator ->
+ val point = animator.animatedValue as PointF
+ imageViewContainer.x = point.x
+ imageViewContainer.y = point.y
+ }
+ animation.start()
+ }
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ when (event.action) {
+ MotionEvent.ACTION_DOWN -> { expand() }
+ MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { collapse() }
+ }
+ return true
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/GlowView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/GlowView.kt
index e48a67fbc9..e99e6f601a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/GlowView.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/GlowView.kt
@@ -7,9 +7,12 @@ import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
+import android.widget.ImageView
import android.widget.LinearLayout
+import android.widget.RelativeLayout
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
+import androidx.appcompat.widget.AppCompatImageView
import network.loki.messenger.R
import org.thoughtcrime.securesms.loki.utilities.getColorWithID
import org.thoughtcrime.securesms.loki.utilities.toPx
@@ -155,4 +158,36 @@ class PathDotView : View, GlowView {
super.onDraw(c)
}
// endregion
-}
\ No newline at end of file
+}
+
+class InputBarButtonImageViewContainer : RelativeLayout, GlowView {
+ @ColorInt override var mainColor: Int = 0
+ set(newValue) { field = newValue; paint.color = newValue }
+ @ColorInt override var sessionShadowColor: Int = 0 // Unused
+
+ private val paint: Paint by lazy {
+ val result = Paint()
+ result.style = Paint.Style.FILL
+ result.isAntiAlias = true
+ result
+ }
+
+ // region Lifecycle
+ constructor(context: Context) : super(context) { }
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { }
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { }
+
+ init {
+ setWillNotDraw(false)
+ }
+ // endregion
+
+ // region Updating
+ override fun onDraw(c: Canvas) {
+ val w = width.toFloat()
+ val h = height.toFloat()
+ c.drawCircle(w / 2, h / 2, w / 2, paint)
+ super.onDraw(c)
+ }
+ // endregion
+}
diff --git a/app/src/main/res/drawable/input_bar_button_background.xml b/app/src/main/res/drawable/input_bar_button_background.xml
index 68f8684bc1..4de519558a 100644
--- a/app/src/main/res/drawable/input_bar_button_background.xml
+++ b/app/src/main/res/drawable/input_bar_button_background.xml
@@ -1,17 +1,4 @@
-
-
- -
-
-
-
-
- -
-
-
-
-
-
\ No newline at end of file
+ android:shape="oval" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_conversation_v2_action_bar.xml b/app/src/main/res/layout/activity_conversation_v2_action_bar.xml
index 04e4013170..4716171f50 100644
--- a/app/src/main/res/layout/activity_conversation_v2_action_bar.xml
+++ b/app/src/main/res/layout/activity_conversation_v2_action_bar.xml
@@ -19,6 +19,8 @@
android:text="Elon"
android:textColor="@color/text"
android:textStyle="bold"
- android:textSize="@dimen/very_large_font_size" />
+ android:textSize="@dimen/very_large_font_size"
+ android:maxLines="1"
+ android:ellipsize="end" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_conversation.xml b/app/src/main/res/layout/view_conversation.xml
index 55dbbff04b..c661335caa 100644
--- a/app/src/main/res/layout/view_conversation.xml
+++ b/app/src/main/res/layout/view_conversation.xml
@@ -1,5 +1,6 @@
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_input_bar.xml b/app/src/main/res/layout/view_input_bar.xml
index 4250c3c8be..997122f190 100644
--- a/app/src/main/res/layout/view_input_bar.xml
+++ b/app/src/main/res/layout/view_input_bar.xml
@@ -1,7 +1,6 @@
@@ -16,23 +15,12 @@
android:layout_height="match_parent">
-
-
-
-
+ android:layout_marginStart="@dimen/small_spacing" />
-
-
-
-
+ android:layout_marginEnd="@dimen/small_spacing" />
diff --git a/app/src/main/res/layout/view_input_bar_button.xml b/app/src/main/res/layout/view_input_bar_button.xml
new file mode 100644
index 0000000000..096c616ab6
--- /dev/null
+++ b/app/src/main/res/layout/view_input_bar_button.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-notnight-v21/colors.xml b/app/src/main/res/values-notnight-v21/colors.xml
index 95021ff8b0..2a82dabd1d 100644
--- a/app/src/main/res/values-notnight-v21/colors.xml
+++ b/app/src/main/res/values-notnight-v21/colors.xml
@@ -21,7 +21,7 @@
#0D000000
#FFFFFF
#FCFCFC
- #0D000000
+ #F2F2F2
#ffffff
#fcfcfc
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index e61ab9ccac..b1ad8d9715 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -28,7 +28,7 @@
#0DFFFFFF
#000000
#171717
- #0DFFFFFF
+ #0D0D0D
- #5ff8b0
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index fd05d71d76..0afc835242 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -37,6 +37,8 @@
8dp
16dp
56dp
+ 40dp
+ 48dp
8dp