kopia lustrzana https://github.com/ryukoposting/Signal-Android
Increase stories caption limit to 1500 grapheme clusters.
rodzic
654b602cef
commit
9326c1726a
|
@ -3,10 +3,8 @@ package org.thoughtcrime.securesms.components
|
|||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import org.whispersystems.signalservice.api.util.Preconditions
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
|
@ -18,8 +16,6 @@ class ViewBinderDelegate<T : ViewBinding>(private val bindingFactory: (View) ->
|
|||
private var binding: T? = null
|
||||
|
||||
operator fun getValue(thisRef: Fragment, property: KProperty<*>): T {
|
||||
Preconditions.checkState(thisRef.viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED))
|
||||
|
||||
if (binding == null) {
|
||||
thisRef.viewLifecycleOwner.lifecycle.addObserver(this@ViewBinderDelegate)
|
||||
binding = bindingFactory(thisRef.requireView())
|
||||
|
|
|
@ -164,7 +164,7 @@ class MediaSelectionRepository(context: Context) {
|
|||
} else {
|
||||
val iterator = BreakIteratorCompat.getInstance()
|
||||
iterator.setText(body)
|
||||
iterator.take(Stories.MAX_BODY_SIZE).toString()
|
||||
iterator.take(Stories.MAX_CAPTION_SIZE).toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,21 +5,27 @@ import android.os.Bundle
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.core.Maybe
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.processors.BehaviorProcessor
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import io.reactivex.rxjava3.subjects.Subject
|
||||
import org.signal.core.util.BreakIteratorCompat
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||
import org.thoughtcrime.securesms.conversation.MessageSendType
|
||||
import org.thoughtcrime.securesms.mediasend.Media
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
||||
import org.thoughtcrime.securesms.mediasend.VideoEditorFragment
|
||||
import org.thoughtcrime.securesms.mediasend.v2.review.AddMessageCharacterCount
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints
|
||||
import org.thoughtcrime.securesms.mms.SentMediaQuality
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
@ -53,6 +59,8 @@ class MediaSelectionViewModel(
|
|||
)
|
||||
)
|
||||
|
||||
private val addAMessageUpdatePublisher = BehaviorProcessor.create<CharSequence>()
|
||||
|
||||
val isContactSelectionRequired = destination == MediaSelectionDestination.ChooseAfterMediaSelection
|
||||
|
||||
val state: LiveData<MediaSelectionState> = store.stateLiveData
|
||||
|
@ -64,6 +72,22 @@ class MediaSelectionViewModel(
|
|||
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
fun watchAddAMessageCount(): Flowable<AddMessageCharacterCount> {
|
||||
return addAMessageUpdatePublisher
|
||||
.onBackpressureLatest()
|
||||
.map {
|
||||
val iterator = BreakIteratorCompat.getInstance()
|
||||
iterator.setText(it)
|
||||
AddMessageCharacterCount(iterator.countBreaks())
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
fun updateAddAMessageCount(input: CharSequence?) {
|
||||
addAMessageUpdatePublisher.onNext(input ?: "")
|
||||
}
|
||||
|
||||
private val isMeteredDisposable: Disposable = repository.isMetered.subscribe { metered ->
|
||||
store.update {
|
||||
it.copy(
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.thoughtcrime.securesms.mediasend.v2.review
|
||||
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Manages the current character count for the add-message input.
|
||||
*
|
||||
* We only want to display the count if DISPLAY_COUNT or less characters remain.
|
||||
* The actual count is calculated in the background by the ViewModel.
|
||||
*/
|
||||
@JvmInline
|
||||
value class AddMessageCharacterCount(private val count: Int) {
|
||||
fun getRemaining(): Int = max(Stories.MAX_CAPTION_SIZE - count, 0)
|
||||
|
||||
fun shouldDisplayCount(): Boolean = getRemaining() <= DISPLAY_COUNT_THRESHOLD
|
||||
|
||||
companion object {
|
||||
private const val DISPLAY_COUNT_THRESHOLD = 50
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.view.KeyEvent
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.viewModels
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
|
@ -14,10 +15,8 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
|
|||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import org.signal.core.util.EditTextUtil
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.ComposeText
|
||||
import org.thoughtcrime.securesms.components.InputAwareLayout
|
||||
import org.thoughtcrime.securesms.components.KeyboardEntryDialogFragment
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle
|
||||
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard
|
||||
import org.thoughtcrime.securesms.components.mention.MentionAnnotation
|
||||
import org.thoughtcrime.securesms.conversation.ui.inlinequery.InlineQuery
|
||||
|
@ -27,6 +26,7 @@ import org.thoughtcrime.securesms.conversation.ui.inlinequery.InlineQueryResults
|
|||
import org.thoughtcrime.securesms.conversation.ui.inlinequery.InlineQueryViewModel
|
||||
import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerFragment
|
||||
import org.thoughtcrime.securesms.conversation.ui.mentions.MentionsPickerViewModel
|
||||
import org.thoughtcrime.securesms.databinding.V2MediaAddMessageDialogFragmentBinding
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPage
|
||||
import org.thoughtcrime.securesms.keyboard.KeyboardPagerViewModel
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
|
@ -58,11 +58,8 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
ownerProducer = { requireActivity() }
|
||||
)
|
||||
|
||||
private lateinit var input: ComposeText
|
||||
private lateinit var emojiDrawerToggle: EmojiToggle
|
||||
private val binding by ViewBinderDelegate(V2MediaAddMessageDialogFragmentBinding::bind)
|
||||
private lateinit var emojiDrawerStub: Stub<MediaKeyboard>
|
||||
private lateinit var hud: InputAwareLayout
|
||||
private lateinit var mentionsContainer: ViewGroup
|
||||
private lateinit var inlineQueryResultsController: InlineQueryResultsController
|
||||
|
||||
private var requestedEmojiDrawer: Boolean = false
|
||||
|
@ -79,28 +76,34 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
input = view.findViewById(R.id.add_a_message_input)
|
||||
emojiDrawerStub = Stub(binding.content.emojiDrawerStub)
|
||||
|
||||
if (Stories.isFeatureEnabled()) {
|
||||
EditTextUtil.addGraphemeClusterLimitFilter(input, Stories.MAX_BODY_SIZE)
|
||||
EditTextUtil.addGraphemeClusterLimitFilter(binding.content.addAMessageInput, Stories.MAX_CAPTION_SIZE)
|
||||
}
|
||||
|
||||
input.setText(requireArguments().getCharSequence(ARG_INITIAL_TEXT))
|
||||
binding.content.addAMessageInput.addTextChangedListener(afterTextChanged = {
|
||||
viewModel.updateAddAMessageCount(it)
|
||||
})
|
||||
|
||||
binding.content.addAMessageInput.setText(requireArguments().getCharSequence(ARG_INITIAL_TEXT))
|
||||
|
||||
emojiDrawerToggle = view.findViewById(R.id.emoji_toggle)
|
||||
emojiDrawerStub = Stub(view.findViewById(R.id.emoji_drawer_stub))
|
||||
if (SignalStore.settings().isPreferSystemEmoji) {
|
||||
emojiDrawerToggle.visible = false
|
||||
binding.content.emojiToggle.visible = false
|
||||
} else {
|
||||
emojiDrawerToggle.setOnClickListener { onEmojiToggleClicked() }
|
||||
binding.content.emojiToggle.setOnClickListener { onEmojiToggleClicked() }
|
||||
}
|
||||
|
||||
hud = view.findViewById(R.id.hud)
|
||||
hud.setOnClickListener { dismissAllowingStateLoss() }
|
||||
binding.hud.setOnClickListener { dismissAllowingStateLoss() }
|
||||
|
||||
val confirm: View = view.findViewById(R.id.confirm_button)
|
||||
confirm.setOnClickListener { dismissAllowingStateLoss() }
|
||||
|
||||
disposables += viewModel.watchAddAMessageCount().subscribe { count ->
|
||||
binding.content.addAMessageLimit.visible = count.shouldDisplayCount()
|
||||
binding.content.addAMessageLimit.text = count.getRemaining().toString()
|
||||
}
|
||||
|
||||
disposables.add(
|
||||
viewModel.hudCommands.observeOn(AndroidSchedulers.mainThread()).subscribe {
|
||||
when (it) {
|
||||
|
@ -120,18 +123,18 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
super.onResume()
|
||||
|
||||
requestedEmojiDrawer = false
|
||||
ViewUtil.focusAndShowKeyboard(input)
|
||||
ViewUtil.focusAndShowKeyboard(binding.content.addAMessageInput)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
ViewUtil.hideKeyboard(requireContext(), input)
|
||||
ViewUtil.hideKeyboard(requireContext(), binding.content.addAMessageInput)
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
viewModel.setMessage(input.text)
|
||||
viewModel.setMessage(binding.content.addAMessageInput.text)
|
||||
}
|
||||
|
||||
override fun onKeyboardHidden() {
|
||||
|
@ -151,23 +154,21 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
super.onDestroyView()
|
||||
disposables.dispose()
|
||||
|
||||
input.setInlineQueryChangedListener(null)
|
||||
input.setMentionValidator(null)
|
||||
binding.content.addAMessageInput.setInlineQueryChangedListener(null)
|
||||
binding.content.addAMessageInput.setMentionValidator(null)
|
||||
}
|
||||
|
||||
private fun initializeMentions() {
|
||||
mentionsContainer = requireView().findViewById(R.id.mentions_picker_container)
|
||||
|
||||
inlineQueryResultsController = InlineQueryResultsController(
|
||||
requireContext(),
|
||||
inlineQueryViewModel,
|
||||
requireView().findViewById(R.id.background_holder),
|
||||
(requireView() as ViewGroup),
|
||||
input,
|
||||
binding.content.addAMessageInput,
|
||||
viewLifecycleOwner
|
||||
)
|
||||
|
||||
input.setInlineQueryChangedListener(object : InlineQueryChangedListener {
|
||||
binding.content.addAMessageInput.setInlineQueryChangedListener(object : InlineQueryChangedListener {
|
||||
override fun onQueryChanged(inlineQuery: InlineQuery) {
|
||||
when (inlineQuery) {
|
||||
is InlineQuery.Mention -> {
|
||||
|
@ -196,7 +197,7 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
disposables += inlineQueryViewModel
|
||||
.selection
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { r -> input.replaceText(r) }
|
||||
.subscribe { r -> binding.content.addAMessageInput.replaceText(r) }
|
||||
|
||||
val recipientId: RecipientId = viewModel.destination.getRecipientSearchKey()?.recipientId ?: return
|
||||
|
||||
|
@ -204,7 +205,7 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
this.recipient = recipient
|
||||
mentionsViewModel.onRecipientChange(recipient)
|
||||
|
||||
input.setMentionValidator { annotations ->
|
||||
binding.content.addAMessageInput.setMentionValidator { annotations ->
|
||||
if (!recipient.isPushV2Group) {
|
||||
annotations
|
||||
} else {
|
||||
|
@ -221,7 +222,7 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
}
|
||||
|
||||
mentionsViewModel.selectedRecipient.observe(viewLifecycleOwner) { recipient ->
|
||||
input.replaceTextWithMention(recipient.getDisplayName(requireContext()), recipient.id)
|
||||
binding.content.addAMessageInput.replaceTextWithMention(recipient.getDisplayName(requireContext()), recipient.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,17 +240,17 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
if (!emojiDrawerStub.resolved()) {
|
||||
keyboardPagerViewModel.setOnlyPage(KeyboardPage.EMOJI)
|
||||
emojiDrawerStub.get().setFragmentManager(childFragmentManager)
|
||||
emojiDrawerToggle.attach(emojiDrawerStub.get())
|
||||
binding.content.emojiToggle.attach(emojiDrawerStub.get())
|
||||
}
|
||||
|
||||
if (hud.currentInput == emojiDrawerStub.get()) {
|
||||
if (binding.hud.currentInput == emojiDrawerStub.get()) {
|
||||
requestedEmojiDrawer = false
|
||||
hud.showSoftkey(input)
|
||||
binding.hud.showSoftkey(binding.content.addAMessageInput)
|
||||
} else {
|
||||
requestedEmojiDrawer = true
|
||||
hud.hideSoftkey(input) {
|
||||
hud.post {
|
||||
hud.show(input, emojiDrawerStub.get())
|
||||
binding.hud.hideSoftkey(binding.content.addAMessageInput) {
|
||||
binding.hud.post {
|
||||
binding.hud.show(binding.content.addAMessageInput, emojiDrawerStub.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,11 +269,11 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
|||
}
|
||||
|
||||
private fun onEmojiSelected(emoji: String?) {
|
||||
input.insertEmoji(emoji)
|
||||
binding.content.addAMessageInput.insertEmoji(emoji)
|
||||
}
|
||||
|
||||
private fun onKeyEvent(keyEvent: KeyEvent?) {
|
||||
input.dispatchKeyEvent(keyEvent)
|
||||
binding.content.addAMessageInput.dispatchKeyEvent(keyEvent)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -168,7 +168,7 @@ public final class MultiShareArgs implements Parcelable {
|
|||
BreakIteratorCompat breakIteratorCompat = BreakIteratorCompat.getInstance();
|
||||
breakIteratorCompat.setText(getDraftText());
|
||||
|
||||
if (breakIteratorCompat.countBreaks() > Stories.MAX_BODY_SIZE) {
|
||||
if (breakIteratorCompat.countBreaks() > Stories.MAX_TEXT_STORY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ public final class MultiShareSender {
|
|||
BreakIteratorCompat breakIteratorCompat = BreakIteratorCompat.getInstance();
|
||||
breakIteratorCompat.setText(draftText);
|
||||
|
||||
String trimmed = breakIteratorCompat.take(Stories.MAX_BODY_SIZE).toString();
|
||||
String trimmed = breakIteratorCompat.take(Stories.MAX_TEXT_STORY_SIZE).toString();
|
||||
if (linkPreview == null) {
|
||||
return trimmed;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,8 @@ object Stories {
|
|||
|
||||
private val TAG = Log.tag(Stories::class.java)
|
||||
|
||||
const val MAX_BODY_SIZE = 700
|
||||
const val MAX_TEXT_STORY_SIZE = 700
|
||||
const val MAX_CAPTION_SIZE = 1500
|
||||
|
||||
@JvmField
|
||||
val MAX_VIDEO_DURATION_MILLIS = TimeUnit.SECONDS.toMillis(30)
|
||||
|
|
|
@ -12,7 +12,9 @@ import android.media.AudioManager
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.method.ScrollingMovementMethod
|
||||
import android.view.GestureDetector
|
||||
import android.view.GestureDetector.SimpleOnGestureListener
|
||||
import android.view.MotionEvent
|
||||
import android.view.ScaleGestureDetector
|
||||
import android.view.View
|
||||
|
@ -826,9 +828,16 @@ class StoryViewerPageFragment :
|
|||
}
|
||||
|
||||
private fun onShowCaptionOverlay(caption: TextView, largeCaption: TextView, largeCaptionOverlay: View) {
|
||||
sharedViewModel.setIsChildScrolling(true)
|
||||
|
||||
caption.visible = false
|
||||
largeCaption.visible = true
|
||||
largeCaptionOverlay.visible = true
|
||||
largeCaption.movementMethod = ScrollingMovementMethod()
|
||||
largeCaption.scrollY = 0
|
||||
largeCaption.setOnClickListener {
|
||||
onHideCaptionOverlay(caption, largeCaption, largeCaptionOverlay)
|
||||
}
|
||||
largeCaptionOverlay.setOnClickListener {
|
||||
onHideCaptionOverlay(caption, largeCaption, largeCaptionOverlay)
|
||||
}
|
||||
|
@ -839,8 +848,10 @@ class StoryViewerPageFragment :
|
|||
caption.visible = true
|
||||
largeCaption.visible = false
|
||||
largeCaptionOverlay.visible = false
|
||||
largeCaption.setOnClickListener(null)
|
||||
largeCaptionOverlay.setOnClickListener(null)
|
||||
viewModel.setIsDisplayingCaptionOverlay(false)
|
||||
sharedViewModel.setIsChildScrolling(false)
|
||||
}
|
||||
|
||||
private fun presentFrom(from: TextView, storyPost: StoryPost) {
|
||||
|
|
|
@ -25,7 +25,10 @@ data class StoryViewerPlaybackState(
|
|||
) {
|
||||
val hideChromeImmediate: Boolean = isRunningSharedElementAnimation
|
||||
|
||||
val hideChrome: Boolean = isRunningSharedElementAnimation || isUserLongTouching || isUserScrollingChild || isUserScaling
|
||||
val hideChrome: Boolean = isRunningSharedElementAnimation ||
|
||||
isUserLongTouching ||
|
||||
(isUserScrollingChild && !isDisplayingCaptionOverlay) ||
|
||||
isUserScaling
|
||||
|
||||
val isPaused: Boolean = !areSegmentsInitialized ||
|
||||
isUserTouching ||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||
<solid android:color="@color/core_grey_75"/>
|
||||
<corners android:radius="20dp"/>
|
||||
<solid android:color="@color/signal_dark_colorSurfaceVariant"/>
|
||||
<corners android:radius="18dp"/>
|
||||
</shape>
|
|
@ -132,14 +132,14 @@
|
|||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/story_large_caption"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:gravity="bottom"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
android:visibility="gone"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_constrainedHeight="true"
|
||||
app:layout_constraintBottom_toTopOf="@id/story_from_barrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.InputAwareLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:viewBindingIgnore="true"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/hud"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/v2_media_add_message_dialog_fragment_content" />
|
||||
<include android:id="@+id/content" layout="@layout/v2_media_add_message_dialog_fragment_content" />
|
||||
</org.thoughtcrime.securesms.components.InputAwareLayout>
|
|
@ -1,8 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:viewBindingIgnore="true"
|
||||
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">
|
||||
|
||||
|
@ -26,7 +25,7 @@
|
|||
android:layout_height="0dp"
|
||||
android:background="@drawable/rounded_rectangle_secondary_dark"
|
||||
app:layout_constraintBottom_toBottomOf="@id/add_a_message_input"
|
||||
app:layout_constraintEnd_toEndOf="@id/add_a_message_input"
|
||||
app:layout_constraintEnd_toEndOf="@id/add_a_message_limit"
|
||||
app:layout_constraintStart_toStartOf="@id/emoji_toggle"
|
||||
app:layout_constraintTop_toTopOf="@id/add_a_message_input" />
|
||||
|
||||
|
@ -49,7 +48,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
app:layout_goneMarginEnd="6dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@null"
|
||||
android:hint="@string/MediaReviewFragment__add_a_message"
|
||||
|
@ -61,11 +60,25 @@
|
|||
android:paddingEnd="10dp"
|
||||
android:textAppearance="@style/Signal.Text.Body"
|
||||
app:layout_constraintBottom_toTopOf="@id/emoji_drawer_stub"
|
||||
app:layout_constraintEnd_toStartOf="@id/confirm_button"
|
||||
app:layout_constraintEnd_toStartOf="@id/add_a_message_limit"
|
||||
app:layout_constraintStart_toEndOf="@id/emoji_toggle"
|
||||
app:layout_constraintTop_toTopOf="@id/input_barrier"
|
||||
app:layout_goneMarginStart="12dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_a_message_limit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:textAppearance="@style/Signal.Text.BodySmall"
|
||||
android:textColor="@color/signal_colorOnSurfaceVariant"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/add_a_message_input"
|
||||
app:layout_constraintEnd_toStartOf="@id/confirm_button"
|
||||
tools:text="50"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/confirm_button"
|
||||
android:layout_width="48dp"
|
||||
|
|
Ładowanie…
Reference in New Issue