From 3d4b390a8a9c4a7c52354a0c7bd4bc0a8e12f9f8 Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Tue, 11 Jun 2024 20:50:56 +0100
Subject: Only enable keyboard controller when necessary (#4483)

* Only enable keyboard controller when necessary

* make it screen only

* rm keyboard padding

* rm keyboardpadding file

* revert using keyboard controller in composer

* remove styles.outer (unnecessary for revert)

* continue to use keyboard padding in the report dialog for dms

---------

Co-authored-by: Hailey <me@haileyok.com>
---
 src/view/com/composer/Composer.tsx | 347 +++++++++++++++++--------------------
 1 file changed, 163 insertions(+), 184 deletions(-)

(limited to 'src/view/com/composer/Composer.tsx')

diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index e8ea5189f..9bb704012 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -10,16 +10,12 @@ import {
   ActivityIndicator,
   BackHandler,
   Keyboard,
+  KeyboardAvoidingView,
   LayoutChangeEvent,
   StyleSheet,
   TouchableOpacity,
   View,
 } from 'react-native'
-import {
-  KeyboardAvoidingView,
-  KeyboardStickyView,
-  useKeyboardController,
-} from 'react-native-keyboard-controller'
 import Animated, {
   interpolateColor,
   useAnimatedStyle,
@@ -131,17 +127,6 @@ export const ComposePost = observer(function ComposePost({
   const {closeAllModals} = useModalControls()
   const t = useTheme()
 
-  // Disable this in the composer to prevent any extra keyboard height being applied.
-  // See https://github.com/bluesky-social/social-app/pull/4399
-  const {setEnabled} = useKeyboardController()
-  React.useEffect(() => {
-    if (!isAndroid) return
-    setEnabled(false)
-    return () => {
-      setEnabled(true)
-    }
-  }, [setEnabled])
-
   const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
   const [isProcessing, setIsProcessing] = useState(false)
   const [processingState, setProcessingState] = useState('')
@@ -431,181 +416,175 @@ export const ComposePost = observer(function ComposePost({
   } = useAnimatedBorders()
 
   return (
-    <>
-      <KeyboardAvoidingView
-        testID="composePostView"
-        behavior="padding"
-        style={a.flex_1}
-        keyboardVerticalOffset={replyTo ? 115 : isAndroid ? 180 : 162}>
-        <View
-          style={[a.flex_1, viewStyles]}
-          aria-modal
-          accessibilityViewIsModal>
-          <Animated.View style={topBarAnimatedStyle}>
-            <View style={styles.topbarInner}>
-              <TouchableOpacity
-                testID="composerDiscardButton"
-                onPress={onPressCancel}
-                onAccessibilityEscape={onPressCancel}
-                accessibilityRole="button"
-                accessibilityLabel={_(msg`Cancel`)}
-                accessibilityHint={_(
-                  msg`Closes post composer and discards post draft`,
-                )}
-                hitSlop={HITSLOP_10}>
-                <Text style={[pal.link, s.f18]}>
-                  <Trans>Cancel</Trans>
-                </Text>
-              </TouchableOpacity>
-              <View style={a.flex_1} />
-              {isProcessing ? (
-                <>
-                  <Text style={pal.textLight}>{processingState}</Text>
-                  <View style={styles.postBtn}>
-                    <ActivityIndicator />
-                  </View>
-                </>
-              ) : (
-                <>
-                  <LabelsBtn
-                    labels={labels}
-                    onChange={setLabels}
-                    hasMedia={hasMedia}
-                  />
-                  {canPost ? (
-                    <TouchableOpacity
-                      testID="composerPublishBtn"
-                      onPress={onPressPublish}
-                      accessibilityRole="button"
-                      accessibilityLabel={
-                        replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)
-                      }
-                      accessibilityHint="">
-                      <LinearGradient
-                        colors={[
-                          gradients.blueLight.start,
-                          gradients.blueLight.end,
-                        ]}
-                        start={{x: 0, y: 0}}
-                        end={{x: 1, y: 1}}
-                        style={styles.postBtn}>
-                        <Text style={[s.white, s.f16, s.bold]}>
-                          {replyTo ? (
-                            <Trans context="action">Reply</Trans>
-                          ) : (
-                            <Trans context="action">Post</Trans>
-                          )}
-                        </Text>
-                      </LinearGradient>
-                    </TouchableOpacity>
-                  ) : (
-                    <View style={[styles.postBtn, pal.btn]}>
-                      <Text style={[pal.textLight, s.f16, s.bold]}>
-                        <Trans context="action">Post</Trans>
-                      </Text>
-                    </View>
-                  )}
-                </>
+    <KeyboardAvoidingView
+      testID="composePostView"
+      behavior={isIOS ? 'padding' : 'height'}
+      keyboardVerticalOffset={isIOS ? 70 : 0}
+      style={[a.flex_1]}>
+      <View style={[a.flex_1, viewStyles]} aria-modal accessibilityViewIsModal>
+        <Animated.View style={topBarAnimatedStyle}>
+          <View style={styles.topbarInner}>
+            <TouchableOpacity
+              testID="composerDiscardButton"
+              onPress={onPressCancel}
+              onAccessibilityEscape={onPressCancel}
+              accessibilityRole="button"
+              accessibilityLabel={_(msg`Cancel`)}
+              accessibilityHint={_(
+                msg`Closes post composer and discards post draft`,
               )}
-            </View>
-
-            {isAltTextRequiredAndMissing && (
-              <View style={[styles.reminderLine, pal.viewLight]}>
-                <View style={styles.errorIcon}>
-                  <FontAwesomeIcon
-                    icon="exclamation"
-                    style={{color: colors.red4}}
-                    size={10}
-                  />
+              hitSlop={HITSLOP_10}>
+              <Text style={[pal.link, s.f18]}>
+                <Trans>Cancel</Trans>
+              </Text>
+            </TouchableOpacity>
+            <View style={a.flex_1} />
+            {isProcessing ? (
+              <>
+                <Text style={pal.textLight}>{processingState}</Text>
+                <View style={styles.postBtn}>
+                  <ActivityIndicator />
                 </View>
-                <Text style={[pal.text, a.flex_1]}>
-                  <Trans>One or more images is missing alt text.</Trans>
-                </Text>
-              </View>
+              </>
+            ) : (
+              <>
+                <LabelsBtn
+                  labels={labels}
+                  onChange={setLabels}
+                  hasMedia={hasMedia}
+                />
+                {canPost ? (
+                  <TouchableOpacity
+                    testID="composerPublishBtn"
+                    onPress={onPressPublish}
+                    accessibilityRole="button"
+                    accessibilityLabel={
+                      replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)
+                    }
+                    accessibilityHint="">
+                    <LinearGradient
+                      colors={[
+                        gradients.blueLight.start,
+                        gradients.blueLight.end,
+                      ]}
+                      start={{x: 0, y: 0}}
+                      end={{x: 1, y: 1}}
+                      style={styles.postBtn}>
+                      <Text style={[s.white, s.f16, s.bold]}>
+                        {replyTo ? (
+                          <Trans context="action">Reply</Trans>
+                        ) : (
+                          <Trans context="action">Post</Trans>
+                        )}
+                      </Text>
+                    </LinearGradient>
+                  </TouchableOpacity>
+                ) : (
+                  <View style={[styles.postBtn, pal.btn]}>
+                    <Text style={[pal.textLight, s.f16, s.bold]}>
+                      <Trans context="action">Post</Trans>
+                    </Text>
+                  </View>
+                )}
+              </>
             )}
-            {error !== '' && (
-              <View style={styles.errorLine}>
-                <View style={styles.errorIcon}>
-                  <FontAwesomeIcon
-                    icon="exclamation"
-                    style={{color: colors.red4}}
-                    size={10}
-                  />
-                </View>
-                <Text style={[s.red4, a.flex_1]}>{error}</Text>
+          </View>
+
+          {isAltTextRequiredAndMissing && (
+            <View style={[styles.reminderLine, pal.viewLight]}>
+              <View style={styles.errorIcon}>
+                <FontAwesomeIcon
+                  icon="exclamation"
+                  style={{color: colors.red4}}
+                  size={10}
+                />
               </View>
-            )}
-          </Animated.View>
-          <Animated.ScrollView
-            onScroll={scrollHandler}
-            style={styles.scrollView}
-            keyboardShouldPersistTaps="always"
-            onContentSizeChange={onScrollViewContentSizeChange}
-            onLayout={onScrollViewLayout}>
-            {replyTo ? <ComposerReplyTo replyTo={replyTo} /> : undefined}
-
-            <View
-              style={[
-                styles.textInputLayout,
-                isNative && styles.textInputLayoutMobile,
-              ]}>
-              <UserAvatar
-                avatar={currentProfile?.avatar}
-                size={50}
-                type={currentProfile?.associated?.labeler ? 'labeler' : 'user'}
+              <Text style={[pal.text, a.flex_1]}>
+                <Trans>One or more images is missing alt text.</Trans>
+              </Text>
+            </View>
+          )}
+          {error !== '' && (
+            <View style={styles.errorLine}>
+              <View style={styles.errorIcon}>
+                <FontAwesomeIcon
+                  icon="exclamation"
+                  style={{color: colors.red4}}
+                  size={10}
+                />
+              </View>
+              <Text style={[s.red4, a.flex_1]}>{error}</Text>
+            </View>
+          )}
+        </Animated.View>
+        <Animated.ScrollView
+          onScroll={scrollHandler}
+          style={styles.scrollView}
+          keyboardShouldPersistTaps="always"
+          onContentSizeChange={onScrollViewContentSizeChange}
+          onLayout={onScrollViewLayout}>
+          {replyTo ? <ComposerReplyTo replyTo={replyTo} /> : undefined}
+
+          <View
+            style={[
+              styles.textInputLayout,
+              isNative && styles.textInputLayoutMobile,
+            ]}>
+            <UserAvatar
+              avatar={currentProfile?.avatar}
+              size={50}
+              type={currentProfile?.associated?.labeler ? 'labeler' : 'user'}
+            />
+            <TextInput
+              ref={textInput}
+              richtext={richtext}
+              placeholder={selectTextInputPlaceholder}
+              autoFocus
+              setRichText={setRichText}
+              onPhotoPasted={onPhotoPasted}
+              onPressPublish={onPressPublish}
+              onNewLink={onNewLink}
+              onError={setError}
+              accessible={true}
+              accessibilityLabel={_(msg`Write post`)}
+              accessibilityHint={_(
+                msg`Compose posts up to ${MAX_GRAPHEME_LENGTH} characters in length`,
+              )}
+            />
+          </View>
+
+          <Gallery gallery={gallery} />
+          {gallery.isEmpty && extLink && (
+            <View style={a.relative}>
+              <ExternalEmbed
+                link={extLink}
+                gif={extGif}
+                onRemove={() => {
+                  setExtLink(undefined)
+                  setExtGif(undefined)
+                }}
               />
-              <TextInput
-                ref={textInput}
-                richtext={richtext}
-                placeholder={selectTextInputPlaceholder}
-                autoFocus
-                setRichText={setRichText}
-                onPhotoPasted={onPhotoPasted}
-                onPressPublish={onPressPublish}
-                onNewLink={onNewLink}
-                onError={setError}
-                accessible={true}
-                accessibilityLabel={_(msg`Write post`)}
-                accessibilityHint={_(
-                  msg`Compose posts up to ${MAX_GRAPHEME_LENGTH} characters in length`,
-                )}
+              <GifAltText
+                link={extLink}
+                gif={extGif}
+                onSubmit={handleChangeGifAltText}
               />
             </View>
+          )}
 
-            <Gallery gallery={gallery} />
-            {gallery.isEmpty && extLink && (
-              <View style={a.relative}>
-                <ExternalEmbed
-                  link={extLink}
-                  gif={extGif}
-                  onRemove={() => {
-                    setExtLink(undefined)
-                    setExtGif(undefined)
-                  }}
-                />
-                <GifAltText
-                  link={extLink}
-                  gif={extGif}
-                  onSubmit={handleChangeGifAltText}
-                />
-              </View>
-            )}
-            {quote ? (
-              <View style={[s.mt5, isWeb && s.mb10]}>
-                <View style={{pointerEvents: 'none'}}>
-                  <QuoteEmbed quote={quote} />
-                </View>
-                {quote.uri !== initQuote?.uri && (
-                  <QuoteX onRemove={() => setQuote(undefined)} />
-                )}
+          {quote ? (
+            <View style={[s.mt5, s.mb2, isWeb && s.mb10]}>
+              <View style={{pointerEvents: 'none'}}>
+                <QuoteEmbed quote={quote} />
               </View>
-            ) : undefined}
-          </Animated.ScrollView>
-          <SuggestedLanguage text={richtext.text} />
-        </View>
-      </KeyboardAvoidingView>
-      <KeyboardStickyView
-        offset={{closed: isIOS ? -insets.bottom : 0, opened: 0}}>
+              {quote.uri !== initQuote?.uri && (
+                <QuoteX onRemove={() => setQuote(undefined)} />
+              )}
+            </View>
+          ) : undefined}
+        </Animated.ScrollView>
+        <SuggestedLanguage text={richtext.text} />
+
         {replyTo ? null : (
           <ThreadgateBtn
             threadgate={threadgate}
@@ -644,7 +623,7 @@ export const ComposePost = observer(function ComposePost({
           <SelectLangBtn />
           <CharProgress count={graphemeLength} />
         </View>
-      </KeyboardStickyView>
+      </View>
       <Prompt.Basic
         control={discardPromptControl}
         title={_(msg`Discard draft?`)}
@@ -653,7 +632,7 @@ export const ComposePost = observer(function ComposePost({
         confirmButtonCta={_(msg`Discard`)}
         confirmButtonColor="negative"
       />
-    </>
+    </KeyboardAvoidingView>
   )
 })
 
-- 
cgit 1.4.1

