From 67c4dcff3731444c6e6eadcbed1d55bd503bda4a Mon Sep 17 00:00:00 2001
From: João Ferreiro <joaoferreiro5@gmail.com>
Date: Fri, 2 Dec 2022 16:41:01 +0000
Subject: Upload image in composer (#27)

* upload images in composer v1

* fix android compile

* reafctor image carousel into new component;
fix photo overlapping text in composer

* revert android changes

* further refactoring code into different components

* move show carousel out of the component

* fixing add photo using camera

* fix typescript issue; force mediatype photo

* change post test with photo attached;
remove auto linking settings

* use runInAction in getPhotos model

* react-hooks/exhaustive-deps fixes

* crop every photo;
make use of useCallback

* moving placeholder condition

* Cleanup

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
---
 src/view/com/composer/ComposePost.tsx | 65 ++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 9 deletions(-)

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

diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx
index a61759c24..b43f4ab9e 100644
--- a/src/view/com/composer/ComposePost.tsx
+++ b/src/view/com/composer/ComposePost.tsx
@@ -23,6 +23,9 @@ import * as apilib from '../../../state/lib/api'
 import {ComposerOpts} from '../../../state/models/shell-ui'
 import {s, colors, gradients} from '../../lib/styles'
 import {detectLinkables} from '../../../lib/strings'
+import {UserLocalPhotosModel} from '../../../state/models/user-local-photos'
+import {PhotoCarouselPicker} from './PhotoCarouselPicker'
+import {SelectedPhoto} from './SelectedPhoto'
 
 const MAX_TEXT_LENGTH = 256
 const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
@@ -41,14 +44,22 @@ export const ComposePost = observer(function ComposePost({
   const [isProcessing, setIsProcessing] = useState(false)
   const [error, setError] = useState('')
   const [text, setText] = useState('')
+  const [selectedPhotos, setSelectedPhotos] = useState<string[]>([])
+
   const autocompleteView = useMemo<UserAutocompleteViewModel>(
     () => new UserAutocompleteViewModel(store),
-    [],
+    [store],
+  )
+  const localPhotos = useMemo<UserLocalPhotosModel>(
+    () => new UserLocalPhotosModel(store),
+    [store],
   )
 
   useEffect(() => {
     autocompleteView.setup()
-  })
+    localPhotos.setup()
+  }, [autocompleteView, localPhotos])
+
   useEffect(() => {
     // HACK
     // wait a moment before focusing the input to resolve some layout bugs with the keyboard-avoiding-view
@@ -60,9 +71,11 @@ export const ComposePost = observer(function ComposePost({
       }, 250)
     }
     return () => {
-      if (to) clearTimeout(to)
+      if (to) {
+        clearTimeout(to)
+      }
     }
-  }, [textInput.current])
+  }, [])
 
   const onChangeText = (newText: string) => {
     setText(newText)
@@ -116,6 +129,16 @@ export const ComposePost = observer(function ComposePost({
   const canPost = text.length <= MAX_TEXT_LENGTH
   const progressColor = text.length > DANGER_TEXT_LENGTH ? '#e60000' : undefined
 
+  const selectTextInputLayout =
+    selectedPhotos.length !== 0
+      ? styles.textInputLayoutWithPhoto
+      : styles.textInputLayoutWithoutPhoto
+  const selectTextInputPlaceholder = replyTo
+    ? 'Write your reply'
+    : selectedPhotos.length !== 0
+    ? 'Write a comment'
+    : "What's up?"
+
   const textDecorated = useMemo(() => {
     let i = 0
     return detectLinkables(text).map(v => {
@@ -192,7 +215,7 @@ export const ComposePost = observer(function ComposePost({
             </View>
           </View>
         ) : undefined}
-        <View style={styles.textInputLayout}>
+        <View style={[styles.textInputLayout, selectTextInputLayout]}>
           <UserAvatar
             handle={store.me.handle || ''}
             displayName={store.me.displayName}
@@ -203,13 +226,26 @@ export const ComposePost = observer(function ComposePost({
             multiline
             scrollEnabled
             onChangeText={(text: string) => onChangeText(text)}
-            placeholder={replyTo ? 'Write your reply' : "What's up?"}
+            placeholder={selectTextInputPlaceholder}
             style={styles.textInput}>
             {textDecorated}
           </TextInput>
         </View>
-        <View
-          style={[s.flexRow, {alignItems: 'center'}, s.pt10, s.pb10, s.pr5]}>
+        <SelectedPhoto
+          selectedPhotos={selectedPhotos}
+          setSelectedPhotos={setSelectedPhotos}
+        />
+        {localPhotos.photos != null &&
+          text === '' &&
+          selectedPhotos.length === 0 && (
+            <PhotoCarouselPicker
+              selectedPhotos={selectedPhotos}
+              setSelectedPhotos={setSelectedPhotos}
+              localPhotos={localPhotos}
+            />
+          )}
+        <View style={styles.separator} />
+        <View style={[s.flexRow, s.pt10, s.pb10, s.pr5, styles.contentCenter]}>
           <View style={s.flex1} />
           <Text style={[s.mr10, {color: progressColor}]}>
             {MAX_TEXT_LENGTH - text.length}
@@ -282,9 +318,14 @@ const styles = StyleSheet.create({
     justifyContent: 'center',
     marginRight: 5,
   },
+  textInputLayoutWithPhoto: {
+    flexWrap: 'wrap',
+  },
+  textInputLayoutWithoutPhoto: {
+    flex: 1,
+  },
   textInputLayout: {
     flexDirection: 'row',
-    flex: 1,
     borderTopWidth: 1,
     borderTopColor: colors.gray2,
     paddingTop: 16,
@@ -307,4 +348,10 @@ const styles = StyleSheet.create({
     paddingLeft: 13,
     paddingRight: 8,
   },
+  contentCenter: {alignItems: 'center'},
+  separator: {
+    borderBottomColor: 'black',
+    borderBottomWidth: StyleSheet.hairlineWidth,
+    width: '100%',
+  },
 })
-- 
cgit 1.4.1

