Skip to content

Commit

Permalink
fix: keyboard size after gifs expand [WPB-4985] (#2331)
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas committed Oct 17, 2023
1 parent e066cb0 commit 5794fe0
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,21 @@ fun EnabledMessageComposer(
val isImeVisible = WindowInsets.isImeVisible
val offsetY = WindowInsets.ime.getBottom(density)
val isKeyboardMoving = isKeyboardMoving()
val imeAnimationSource = WindowInsets.imeAnimationSource.getBottom(density)
val imeAnimationTarget = WindowInsets.imeAnimationTarget.getBottom(density)

with(messageComposerStateHolder) {
val inputStateHolder = messageCompositionInputStateHolder

LaunchedEffect(offsetY) {
inputStateHolder.handleOffsetChange(with(density) { offsetY.toDp() }, navBarHeight)
with(density) {
inputStateHolder.handleOffsetChange(
offsetY.toDp(),
navBarHeight,
imeAnimationSource.toDp(),
imeAnimationTarget.toDp()
)
}
}

LaunchedEffect(isImeVisible) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class MessageCompositionInputStateHolder(
var isTextExpanded by mutableStateOf(false)
private set

var initialKeyboardHeight by mutableStateOf(0.dp)
private set

var previousOffset by mutableStateOf(0.dp)
private set

Expand All @@ -90,9 +93,15 @@ class MessageCompositionInputStateHolder(
}
}

fun handleOffsetChange(offset: Dp, navBarHeight: Dp) {
fun handleOffsetChange(offset: Dp, navBarHeight: Dp, source: Dp, target: Dp) {
val actualOffset = max(offset - navBarHeight, 0.dp)

// this check secures that if some additional space will be added to keyboard
// like gifs search it will save initial keyboard height
if (source == target && source > 0.dp && initialKeyboardHeight == 0.dp) {
initialKeyboardHeight = source - navBarHeight
}

if (previousOffset < actualOffset) {
optionsVisible = true
if (!subOptionsVisible || optionsHeight <= actualOffset) {
Expand Down Expand Up @@ -151,7 +160,11 @@ class MessageCompositionInputStateHolder(
fun showOptions() {
optionsVisible = true
subOptionsVisible = true
optionsHeight = keyboardHeight
if (initialKeyboardHeight > 0.dp) {
optionsHeight = initialKeyboardHeight
} else {
optionsHeight = keyboardHeight
}
clearFocus()
}

Expand All @@ -169,19 +182,22 @@ class MessageCompositionInputStateHolder(
return optionsHeight + if (additionalOptionsSubMenuState != AdditionalOptionSubMenuState.RecordAudio) 0.dp else composeTextHeight
}

@Suppress("LongParameterList")
@VisibleForTesting
fun updateValuesForTesting(
keyboardHeight: Dp = KeyboardHeight.default,
previousOffset: Dp = 0.dp,
showSubOptions: Boolean = false,
optionsHeight: Dp = 0.dp,
showOptions: Boolean = false,
initialKeyboardHeight: Dp = 0.dp
) {
this.keyboardHeight = keyboardHeight
this.previousOffset = previousOffset
this.subOptionsVisible = showSubOptions
this.optionsHeight = optionsHeight
this.optionsVisible = showOptions
this.initialKeyboardHeight = initialKeyboardHeight
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ class MessageCompositionInputStateHolderTest {
@Test
fun `when offset increases and is bigger than previous and options height, options height is updated`() {
// When
state.handleOffsetChange(50.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
50.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsHeight shouldBeEqualTo 50.dp
Expand All @@ -82,7 +87,12 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(previousOffset = 50.dp)

// When
state.handleOffsetChange(20.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
20.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsHeight shouldBeEqualTo 20.dp
Expand All @@ -94,7 +104,12 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(previousOffset = 50.dp)

// When
state.handleOffsetChange(0.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
0.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsVisible shouldBeEqualTo false
Expand All @@ -107,7 +122,12 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(keyboardHeight = 30.dp)

// When
state.handleOffsetChange(30.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
30.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.subOptionsVisible shouldBeEqualTo false
Expand All @@ -119,7 +139,12 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(keyboardHeight = 20.dp)

// When
state.handleOffsetChange(30.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
30.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.keyboardHeight shouldBeEqualTo 30.dp
Expand All @@ -131,7 +156,12 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(previousOffset = 50.dp, keyboardHeight = 20.dp)

// When
state.handleOffsetChange(30.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
30.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.keyboardHeight shouldBeEqualTo 30.dp
Expand All @@ -149,7 +179,12 @@ class MessageCompositionInputStateHolderTest {
)

// When
state.handleOffsetChange(30.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
30.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsHeight shouldBeEqualTo 10.dp
Expand All @@ -166,7 +201,12 @@ class MessageCompositionInputStateHolderTest {
)

// When
state.handleOffsetChange(30.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
30.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsHeight shouldBeEqualTo 30.dp
Expand All @@ -178,20 +218,58 @@ class MessageCompositionInputStateHolderTest {
state.updateValuesForTesting(previousOffset = 40.dp, keyboardHeight = 20.dp)

// When
state.handleOffsetChange(40.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
40.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.keyboardHeight shouldBeEqualTo 40.dp
state.optionsHeight shouldBeEqualTo 0.dp
}

@Test
fun `given first keyboard appear when source equals target, then initialKeyboardHeight is set`() {
// Given
val imeValue = 50.dp
state.updateValuesForTesting(initialKeyboardHeight = 0.dp)

// When
state.handleOffsetChange(20.dp, NAVIGATION_BAR_HEIGHT, source = imeValue, target = imeValue)

// Then
state.initialKeyboardHeight shouldBeEqualTo imeValue
}

@Test
fun `given extended keyboard height when attachment button is clicked, then keyboardHeight is set to initialKeyboardHeight`() {
// Given
val initialKeyboardHeight = 10.dp
state.updateValuesForTesting(previousOffset = 40.dp, keyboardHeight = 20.dp, initialKeyboardHeight = initialKeyboardHeight)

// When
state.showOptions()
state.handleOffsetChange(0.dp, NAVIGATION_BAR_HEIGHT, source = TARGET, target = SOURCE)

// Then
state.keyboardHeight shouldBeEqualTo 20.dp
state.optionsHeight shouldBeEqualTo initialKeyboardHeight
}

@Test
fun `when offset decreases but is not zero, only optionsHeight is updated`() {
// Given
state.updateValuesForTesting(previousOffset = 50.dp)

// When
state.handleOffsetChange(10.dp, NAVIGATION_BAR_HEIGHT)
state.handleOffsetChange(
10.dp,
NAVIGATION_BAR_HEIGHT,
SOURCE,
TARGET
)

// Then
state.optionsHeight shouldBeEqualTo 10.dp
Expand All @@ -202,5 +280,7 @@ class MessageCompositionInputStateHolderTest {
companion object {
// I set it 0 to make tests more straight forward
val NAVIGATION_BAR_HEIGHT = 0.dp
val SOURCE = 0.dp
val TARGET = 50.dp
}
}

0 comments on commit 5794fe0

Please sign in to comment.