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>zio/stable
parent
7ae1bac620
commit
67c4dcff37
|
@ -220,6 +220,8 @@ PODS:
|
||||||
- React-jsinspector (0.68.2)
|
- React-jsinspector (0.68.2)
|
||||||
- React-logger (0.68.2):
|
- React-logger (0.68.2):
|
||||||
- glog
|
- glog
|
||||||
|
- react-native-cameraroll (5.1.0):
|
||||||
|
- React-Core
|
||||||
- react-native-pager-view (6.0.2):
|
- react-native-pager-view (6.0.2):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-safe-area-context (4.4.1):
|
- react-native-safe-area-context (4.4.1):
|
||||||
|
@ -301,6 +303,15 @@ PODS:
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNGestureHandler (2.6.1):
|
- RNGestureHandler (2.6.1):
|
||||||
- React-Core
|
- React-Core
|
||||||
|
- RNImageCropPicker (0.38.1):
|
||||||
|
- React-Core
|
||||||
|
- React-RCTImage
|
||||||
|
- RNImageCropPicker/QBImagePickerController (= 0.38.1)
|
||||||
|
- TOCropViewController
|
||||||
|
- RNImageCropPicker/QBImagePickerController (0.38.1):
|
||||||
|
- React-Core
|
||||||
|
- React-RCTImage
|
||||||
|
- TOCropViewController
|
||||||
- RNInAppBrowser (3.7.0):
|
- RNInAppBrowser (3.7.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNReanimated (2.10.0):
|
- RNReanimated (2.10.0):
|
||||||
|
@ -335,6 +346,7 @@ PODS:
|
||||||
- React-RCTImage
|
- React-RCTImage
|
||||||
- RNSVG (12.4.4):
|
- RNSVG (12.4.4):
|
||||||
- React-Core
|
- React-Core
|
||||||
|
- TOCropViewController (2.6.1)
|
||||||
- Yoga (1.14.0)
|
- Yoga (1.14.0)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
@ -359,6 +371,7 @@ DEPENDENCIES:
|
||||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||||
|
- "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)"
|
||||||
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
|
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
|
||||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||||
|
@ -377,6 +390,7 @@ DEPENDENCIES:
|
||||||
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
|
||||||
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
|
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
|
||||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||||
|
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||||
- RNInAppBrowser (from `../node_modules/react-native-inappbrowser-reborn`)
|
- RNInAppBrowser (from `../node_modules/react-native-inappbrowser-reborn`)
|
||||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||||
- RNScreens (from `../node_modules/react-native-screens`)
|
- RNScreens (from `../node_modules/react-native-screens`)
|
||||||
|
@ -386,6 +400,7 @@ DEPENDENCIES:
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- fmt
|
- fmt
|
||||||
|
- TOCropViewController
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
boost:
|
boost:
|
||||||
|
@ -426,6 +441,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||||
React-logger:
|
React-logger:
|
||||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||||
|
react-native-cameraroll:
|
||||||
|
:path: "../node_modules/@react-native-camera-roll/camera-roll"
|
||||||
react-native-pager-view:
|
react-native-pager-view:
|
||||||
:path: "../node_modules/react-native-pager-view"
|
:path: "../node_modules/react-native-pager-view"
|
||||||
react-native-safe-area-context:
|
react-native-safe-area-context:
|
||||||
|
@ -462,6 +479,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/@react-native-clipboard/clipboard"
|
:path: "../node_modules/@react-native-clipboard/clipboard"
|
||||||
RNGestureHandler:
|
RNGestureHandler:
|
||||||
:path: "../node_modules/react-native-gesture-handler"
|
:path: "../node_modules/react-native-gesture-handler"
|
||||||
|
RNImageCropPicker:
|
||||||
|
:path: "../node_modules/react-native-image-crop-picker"
|
||||||
RNInAppBrowser:
|
RNInAppBrowser:
|
||||||
:path: "../node_modules/react-native-inappbrowser-reborn"
|
:path: "../node_modules/react-native-inappbrowser-reborn"
|
||||||
RNReanimated:
|
RNReanimated:
|
||||||
|
@ -494,6 +513,7 @@ SPEC CHECKSUMS:
|
||||||
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
|
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
|
||||||
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
|
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
|
||||||
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
|
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
|
||||||
|
react-native-cameraroll: a40b082318eb1ecd0336a2f29d9f74b7f2c8cae8
|
||||||
react-native-pager-view: 592421df0259bf7a7a4fe85b74c24f3f39905605
|
react-native-pager-view: 592421df0259bf7a7a4fe85b74c24f3f39905605
|
||||||
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
|
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
|
||||||
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
||||||
|
@ -512,10 +532,12 @@ SPEC CHECKSUMS:
|
||||||
RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca
|
RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca
|
||||||
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
|
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
|
||||||
RNGestureHandler: 28ad20bf02257791f7f137b31beef34b9549f54b
|
RNGestureHandler: 28ad20bf02257791f7f137b31beef34b9549f54b
|
||||||
|
RNImageCropPicker: 648356d68fbf9911a1016b3e3723885d28373eda
|
||||||
RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364
|
RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364
|
||||||
RNReanimated: 5bdcbcc3a72aedeee7bb099604262403aa75a1e5
|
RNReanimated: 5bdcbcc3a72aedeee7bb099604262403aa75a1e5
|
||||||
RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9
|
RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9
|
||||||
RNSVG: ecd661f380a07ba690c9c5929c475a44f432d674
|
RNSVG: ecd661f380a07ba690c9c5929c475a44f432d674
|
||||||
|
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||||
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
|
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
|
||||||
|
|
||||||
PODFILE CHECKSUM: cf94853ebcb0d8e0d027dca9ab7a4ede886a8f20
|
PODFILE CHECKSUM: cf94853ebcb0d8e0d027dca9ab7a4ede886a8f20
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
5CEAE7B7A55582F96F1D5952 /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FCB672808307A6013805A3FE /* libPods-app.a */; };
|
56F0250941FE75DA8CF8094A /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */; };
|
||||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||||
|
BFADB63545C91424F7C8293A /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C668306DD1C0A63684EDCB0 /* libPods-app.a */; };
|
||||||
E4BBD590292C1F5200296224 /* app.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E4437C9E28581FA7006DA9E7 /* app.entitlements */; };
|
E4BBD590292C1F5200296224 /* app.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E4437C9E28581FA7006DA9E7 /* app.entitlements */; };
|
||||||
FEB90D21557517F9279AECA4 /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD3BC60FA05CF2D4F6F9BA2 /* libPods-app-appTests.a */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -31,21 +31,21 @@
|
||||||
00E356EE1AD99517003FC87E /* appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = appTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
00E356EE1AD99517003FC87E /* appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = appTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
00E356F21AD99517003FC87E /* appTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = appTests.m; sourceTree = "<group>"; };
|
00E356F21AD99517003FC87E /* appTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = appTests.m; sourceTree = "<group>"; };
|
||||||
03F7088487057F17D25D2F4B /* Pods-app-appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.release.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.release.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
13B07F961A680F5B00A75B9A /* app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = app.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
13B07F961A680F5B00A75B9A /* app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = app.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = app/AppDelegate.h; sourceTree = "<group>"; };
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = app/AppDelegate.h; sourceTree = "<group>"; };
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = app/AppDelegate.mm; sourceTree = "<group>"; };
|
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = app/AppDelegate.mm; sourceTree = "<group>"; };
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = app/Images.xcassets; sourceTree = "<group>"; };
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = app/Images.xcassets; sourceTree = "<group>"; };
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = app/Info.plist; sourceTree = "<group>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = app/Info.plist; sourceTree = "<group>"; };
|
||||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = app/main.m; sourceTree = "<group>"; };
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = app/main.m; sourceTree = "<group>"; };
|
||||||
19C43486502F2DE23E091FE3 /* Pods-app-appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.debug.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.debug.xcconfig"; sourceTree = "<group>"; };
|
3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.debug.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = app/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = app/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
970005155A83960D1D13380F /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; };
|
9C668306DD1C0A63684EDCB0 /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
BAD3BC60FA05CF2D4F6F9BA2 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.release.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
E4437C9E28581FA7006DA9E7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = app.entitlements; path = app/app.entitlements; sourceTree = "<group>"; };
|
E4437C9E28581FA7006DA9E7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = app.entitlements; path = app/app.entitlements; sourceTree = "<group>"; };
|
||||||
ED22CAA45207BC18E75DB44B /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; };
|
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
FCB672808307A6013805A3FE /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
FEB90D21557517F9279AECA4 /* libPods-app-appTests.a in Frameworks */,
|
56F0250941FE75DA8CF8094A /* libPods-app-appTests.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
5CEAE7B7A55582F96F1D5952 /* libPods-app.a in Frameworks */,
|
BFADB63545C91424F7C8293A /* libPods-app.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -103,8 +103,8 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
FCB672808307A6013805A3FE /* libPods-app.a */,
|
9C668306DD1C0A63684EDCB0 /* libPods-app.a */,
|
||||||
BAD3BC60FA05CF2D4F6F9BA2 /* libPods-app-appTests.a */,
|
F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -143,10 +143,10 @@
|
||||||
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED22CAA45207BC18E75DB44B /* Pods-app.debug.xcconfig */,
|
A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */,
|
||||||
970005155A83960D1D13380F /* Pods-app.release.xcconfig */,
|
3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */,
|
||||||
19C43486502F2DE23E091FE3 /* Pods-app-appTests.debug.xcconfig */,
|
65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */,
|
||||||
03F7088487057F17D25D2F4B /* Pods-app-appTests.release.xcconfig */,
|
AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */,
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -158,11 +158,11 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "appTests" */;
|
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "appTests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
F309585457BFF312EF73FD95 /* [CP] Check Pods Manifest.lock */,
|
A8646FFAA087C80271BB2CC6 /* [CP] Check Pods Manifest.lock */,
|
||||||
00E356EA1AD99517003FC87E /* Sources */,
|
00E356EA1AD99517003FC87E /* Sources */,
|
||||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||||
00E356EC1AD99517003FC87E /* Resources */,
|
00E356EC1AD99517003FC87E /* Resources */,
|
||||||
2772CBCCE24036517E86445D /* [CP] Copy Pods Resources */,
|
8DC349844744C81F79F94A1E /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -178,13 +178,13 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "app" */;
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "app" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
4D45C29570A58E7A8A8D177D /* [CP] Check Pods Manifest.lock */,
|
AFA1F7779F8B1AF36C3A7914 /* [CP] Check Pods Manifest.lock */,
|
||||||
FD10A7F022414F080027D42C /* Start Packager */,
|
FD10A7F022414F080027D42C /* Start Packager */,
|
||||||
13B07F871A680F5B00A75B9A /* Sources */,
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
9CEFF2A5EA3D60C120442CA6 /* [CP] Copy Pods Resources */,
|
EEF3465D9B31EDDCEB2438EA /* [CP] Copy Pods Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -266,7 +266,7 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||||
};
|
};
|
||||||
2772CBCCE24036517E86445D /* [CP] Copy Pods Resources */ = {
|
8DC349844744C81F79F94A1E /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -283,7 +283,29 @@
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
4D45C29570A58E7A8A8D177D /* [CP] Check Pods Manifest.lock */ = {
|
A8646FFAA087C80271BB2CC6 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-app-appTests-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
AFA1F7779F8B1AF36C3A7914 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -305,7 +327,7 @@
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
9CEFF2A5EA3D60C120442CA6 /* [CP] Copy Pods Resources */ = {
|
EEF3465D9B31EDDCEB2438EA /* [CP] Copy Pods Resources */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
@ -322,28 +344,6 @@
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
F309585457BFF312EF73FD95 /* [CP] Check Pods Manifest.lock */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
|
||||||
"${PODS_ROOT}/Manifest.lock",
|
|
||||||
);
|
|
||||||
name = "[CP] Check Pods Manifest.lock";
|
|
||||||
outputFileListPaths = (
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
"$(DERIVED_FILE_DIR)/Pods-app-appTests-checkManifestLockResult.txt",
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
|
||||||
showEnvVarsInLog = 0;
|
|
||||||
};
|
|
||||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
00E356F61AD99517003FC87E /* Debug */ = {
|
00E356F61AD99517003FC87E /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 19C43486502F2DE23E091FE3 /* Pods-app-appTests.debug.xcconfig */;
|
baseConfigurationReference = 65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
@ -424,7 +424,7 @@
|
||||||
};
|
};
|
||||||
00E356F71AD99517003FC87E /* Release */ = {
|
00E356F71AD99517003FC87E /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 03F7088487057F17D25D2F4B /* Pods-app-appTests.release.xcconfig */;
|
baseConfigurationReference = AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
@ -449,7 +449,7 @@
|
||||||
};
|
};
|
||||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = ED22CAA45207BC18E75DB44B /* Pods-app.debug.xcconfig */;
|
baseConfigurationReference = A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -478,7 +478,7 @@
|
||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 970005155A83960D1D13380F /* Pods-app.release.xcconfig */;
|
baseConfigurationReference = 3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
|
|
@ -48,8 +48,12 @@
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string></string>
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
<string></string>
|
<string></string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string></string>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIRequiredDeviceCapabilities</key>
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"@fortawesome/react-native-fontawesome": "^0.3.0",
|
"@fortawesome/react-native-fontawesome": "^0.3.0",
|
||||||
"@gorhom/bottom-sheet": "^4",
|
"@gorhom/bottom-sheet": "^4",
|
||||||
"@react-native-async-storage/async-storage": "^1.17.6",
|
"@react-native-async-storage/async-storage": "^1.17.6",
|
||||||
|
"@react-native-camera-roll/camera-roll": "^5.1.0",
|
||||||
"@react-native-clipboard/clipboard": "^1.10.0",
|
"@react-native-clipboard/clipboard": "^1.10.0",
|
||||||
"@zxing/text-encoding": "^0.9.0",
|
"@zxing/text-encoding": "^0.9.0",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
"react-native": "0.68.2",
|
"react-native": "0.68.2",
|
||||||
"react-native-appstate-hook": "^1.0.6",
|
"react-native-appstate-hook": "^1.0.6",
|
||||||
"react-native-gesture-handler": "^2.5.0",
|
"react-native-gesture-handler": "^2.5.0",
|
||||||
|
"react-native-image-crop-picker": "^0.38.1",
|
||||||
"react-native-inappbrowser-reborn": "^3.6.3",
|
"react-native-inappbrowser-reborn": "^3.6.3",
|
||||||
"react-native-linear-gradient": "^2.6.2",
|
"react-native-linear-gradient": "^2.6.2",
|
||||||
"react-native-pager-view": "^6.0.2",
|
"react-native-pager-view": "^6.0.2",
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import {PhotoIdentifier} from './../../../node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll'
|
||||||
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
|
import {CameraRoll} from '@react-native-camera-roll/camera-roll'
|
||||||
|
import {RootStoreModel} from './root-store'
|
||||||
|
|
||||||
|
export class UserLocalPhotosModel {
|
||||||
|
// state
|
||||||
|
photos: PhotoIdentifier[] = []
|
||||||
|
|
||||||
|
constructor(public rootStore: RootStoreModel) {
|
||||||
|
makeAutoObservable(this, {
|
||||||
|
rootStore: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async setup() {
|
||||||
|
await this._getPhotos()
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getPhotos() {
|
||||||
|
CameraRoll.getPhotos({first: 20}).then(r => {
|
||||||
|
runInAction(() => {
|
||||||
|
this.photos = r.edges
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,9 @@ import * as apilib from '../../../state/lib/api'
|
||||||
import {ComposerOpts} from '../../../state/models/shell-ui'
|
import {ComposerOpts} from '../../../state/models/shell-ui'
|
||||||
import {s, colors, gradients} from '../../lib/styles'
|
import {s, colors, gradients} from '../../lib/styles'
|
||||||
import {detectLinkables} from '../../../lib/strings'
|
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 MAX_TEXT_LENGTH = 256
|
||||||
const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
|
const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
|
||||||
|
@ -41,14 +44,22 @@ export const ComposePost = observer(function ComposePost({
|
||||||
const [isProcessing, setIsProcessing] = useState(false)
|
const [isProcessing, setIsProcessing] = useState(false)
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
const [text, setText] = useState('')
|
const [text, setText] = useState('')
|
||||||
|
const [selectedPhotos, setSelectedPhotos] = useState<string[]>([])
|
||||||
|
|
||||||
const autocompleteView = useMemo<UserAutocompleteViewModel>(
|
const autocompleteView = useMemo<UserAutocompleteViewModel>(
|
||||||
() => new UserAutocompleteViewModel(store),
|
() => new UserAutocompleteViewModel(store),
|
||||||
[],
|
[store],
|
||||||
|
)
|
||||||
|
const localPhotos = useMemo<UserLocalPhotosModel>(
|
||||||
|
() => new UserLocalPhotosModel(store),
|
||||||
|
[store],
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
autocompleteView.setup()
|
autocompleteView.setup()
|
||||||
})
|
localPhotos.setup()
|
||||||
|
}, [autocompleteView, localPhotos])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// HACK
|
// HACK
|
||||||
// wait a moment before focusing the input to resolve some layout bugs with the keyboard-avoiding-view
|
// 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)
|
}, 250)
|
||||||
}
|
}
|
||||||
return () => {
|
return () => {
|
||||||
if (to) clearTimeout(to)
|
if (to) {
|
||||||
|
clearTimeout(to)
|
||||||
}
|
}
|
||||||
}, [textInput.current])
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const onChangeText = (newText: string) => {
|
const onChangeText = (newText: string) => {
|
||||||
setText(newText)
|
setText(newText)
|
||||||
|
@ -116,6 +129,16 @@ export const ComposePost = observer(function ComposePost({
|
||||||
const canPost = text.length <= MAX_TEXT_LENGTH
|
const canPost = text.length <= MAX_TEXT_LENGTH
|
||||||
const progressColor = text.length > DANGER_TEXT_LENGTH ? '#e60000' : undefined
|
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(() => {
|
const textDecorated = useMemo(() => {
|
||||||
let i = 0
|
let i = 0
|
||||||
return detectLinkables(text).map(v => {
|
return detectLinkables(text).map(v => {
|
||||||
|
@ -192,7 +215,7 @@ export const ComposePost = observer(function ComposePost({
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<View style={styles.textInputLayout}>
|
<View style={[styles.textInputLayout, selectTextInputLayout]}>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
handle={store.me.handle || ''}
|
handle={store.me.handle || ''}
|
||||||
displayName={store.me.displayName}
|
displayName={store.me.displayName}
|
||||||
|
@ -203,13 +226,26 @@ export const ComposePost = observer(function ComposePost({
|
||||||
multiline
|
multiline
|
||||||
scrollEnabled
|
scrollEnabled
|
||||||
onChangeText={(text: string) => onChangeText(text)}
|
onChangeText={(text: string) => onChangeText(text)}
|
||||||
placeholder={replyTo ? 'Write your reply' : "What's up?"}
|
placeholder={selectTextInputPlaceholder}
|
||||||
style={styles.textInput}>
|
style={styles.textInput}>
|
||||||
{textDecorated}
|
{textDecorated}
|
||||||
</TextInput>
|
</TextInput>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<SelectedPhoto
|
||||||
style={[s.flexRow, {alignItems: 'center'}, s.pt10, s.pb10, s.pr5]}>
|
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} />
|
<View style={s.flex1} />
|
||||||
<Text style={[s.mr10, {color: progressColor}]}>
|
<Text style={[s.mr10, {color: progressColor}]}>
|
||||||
{MAX_TEXT_LENGTH - text.length}
|
{MAX_TEXT_LENGTH - text.length}
|
||||||
|
@ -282,9 +318,14 @@ const styles = StyleSheet.create({
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
},
|
},
|
||||||
|
textInputLayoutWithPhoto: {
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
},
|
||||||
|
textInputLayoutWithoutPhoto: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
textInputLayout: {
|
textInputLayout: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flex: 1,
|
|
||||||
borderTopWidth: 1,
|
borderTopWidth: 1,
|
||||||
borderTopColor: colors.gray2,
|
borderTopColor: colors.gray2,
|
||||||
paddingTop: 16,
|
paddingTop: 16,
|
||||||
|
@ -307,4 +348,10 @@ const styles = StyleSheet.create({
|
||||||
paddingLeft: 13,
|
paddingLeft: 13,
|
||||||
paddingRight: 8,
|
paddingRight: 8,
|
||||||
},
|
},
|
||||||
|
contentCenter: {alignItems: 'center'},
|
||||||
|
separator: {
|
||||||
|
borderBottomColor: 'black',
|
||||||
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
import React, {useCallback} from 'react'
|
||||||
|
import {Image, StyleSheet, TouchableOpacity, ScrollView} from 'react-native'
|
||||||
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
|
import {colors} from '../../lib/styles'
|
||||||
|
import {
|
||||||
|
openPicker,
|
||||||
|
openCamera,
|
||||||
|
openCropper,
|
||||||
|
} from 'react-native-image-crop-picker'
|
||||||
|
|
||||||
|
export const PhotoCarouselPicker = ({
|
||||||
|
selectedPhotos,
|
||||||
|
setSelectedPhotos,
|
||||||
|
localPhotos,
|
||||||
|
}: {
|
||||||
|
selectedPhotos: string[]
|
||||||
|
setSelectedPhotos: React.Dispatch<React.SetStateAction<string[]>>
|
||||||
|
localPhotos: any
|
||||||
|
}) => {
|
||||||
|
const handleOpenCamera = useCallback(() => {
|
||||||
|
openCamera({
|
||||||
|
mediaType: 'photo',
|
||||||
|
cropping: true,
|
||||||
|
width: 1000,
|
||||||
|
height: 1000,
|
||||||
|
}).then(
|
||||||
|
item => {
|
||||||
|
setSelectedPhotos([item.path, ...selectedPhotos])
|
||||||
|
},
|
||||||
|
_err => {
|
||||||
|
// ignore
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, [selectedPhotos, setSelectedPhotos])
|
||||||
|
|
||||||
|
const handleSelectPhoto = useCallback(
|
||||||
|
async (uri: string) => {
|
||||||
|
const img = await openCropper({
|
||||||
|
mediaType: 'photo',
|
||||||
|
path: uri,
|
||||||
|
width: 1000,
|
||||||
|
height: 1000,
|
||||||
|
})
|
||||||
|
setSelectedPhotos([img.path, ...selectedPhotos])
|
||||||
|
},
|
||||||
|
[selectedPhotos, setSelectedPhotos],
|
||||||
|
)
|
||||||
|
|
||||||
|
const handleOpenGallery = useCallback(() => {
|
||||||
|
openPicker({
|
||||||
|
multiple: true,
|
||||||
|
maxFiles: 4,
|
||||||
|
mediaType: 'photo',
|
||||||
|
}).then(async items => {
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
for await (const image of items) {
|
||||||
|
const img = await openCropper({
|
||||||
|
mediaType: 'photo',
|
||||||
|
path: image.path,
|
||||||
|
width: 1000,
|
||||||
|
height: 1000,
|
||||||
|
})
|
||||||
|
result.push(img.path)
|
||||||
|
}
|
||||||
|
setSelectedPhotos([...result, ...selectedPhotos])
|
||||||
|
})
|
||||||
|
}, [selectedPhotos, setSelectedPhotos])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView
|
||||||
|
horizontal
|
||||||
|
style={styles.photosContainer}
|
||||||
|
showsHorizontalScrollIndicator={false}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.galleryButton, styles.photo]}
|
||||||
|
onPress={handleOpenCamera}>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="camera"
|
||||||
|
size={24}
|
||||||
|
style={{color: colors.blue3}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
{localPhotos.photos.map((item: any, index: number) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={`local-image-${index}`}
|
||||||
|
style={styles.photoButton}
|
||||||
|
onPress={() => handleSelectPhoto(item.node.image.uri)}>
|
||||||
|
<Image style={styles.photo} source={{uri: item.node.image.uri}} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[styles.galleryButton, styles.photo]}
|
||||||
|
onPress={handleOpenGallery}>
|
||||||
|
<FontAwesomeIcon icon="image" style={{color: colors.blue3}} size={24} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</ScrollView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
photosContainer: {
|
||||||
|
width: '100%',
|
||||||
|
maxHeight: 96,
|
||||||
|
padding: 8,
|
||||||
|
overflow: 'hidden',
|
||||||
|
},
|
||||||
|
galleryButton: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: colors.gray3,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
photoButton: {
|
||||||
|
width: 75,
|
||||||
|
height: 75,
|
||||||
|
marginRight: 8,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 16,
|
||||||
|
borderColor: colors.gray3,
|
||||||
|
},
|
||||||
|
photo: {
|
||||||
|
width: 75,
|
||||||
|
height: 75,
|
||||||
|
marginRight: 8,
|
||||||
|
borderRadius: 16,
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,87 @@
|
||||||
|
import React, {useCallback} from 'react'
|
||||||
|
import {Image, StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
|
import {colors} from '../../lib/styles'
|
||||||
|
|
||||||
|
export const SelectedPhoto = ({
|
||||||
|
selectedPhotos,
|
||||||
|
setSelectedPhotos,
|
||||||
|
}: {
|
||||||
|
selectedPhotos: string[]
|
||||||
|
setSelectedPhotos: React.Dispatch<React.SetStateAction<string[]>>
|
||||||
|
}) => {
|
||||||
|
const imageStyle =
|
||||||
|
selectedPhotos.length === 1
|
||||||
|
? styles.image250
|
||||||
|
: selectedPhotos.length === 2
|
||||||
|
? styles.image175
|
||||||
|
: styles.image85
|
||||||
|
|
||||||
|
const handleRemovePhoto = useCallback(
|
||||||
|
item => {
|
||||||
|
setSelectedPhotos(
|
||||||
|
selectedPhotos.filter(filterItem => filterItem !== item),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
[selectedPhotos, setSelectedPhotos],
|
||||||
|
)
|
||||||
|
|
||||||
|
return selectedPhotos.length !== 0 ? (
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
{selectedPhotos.length !== 0 &&
|
||||||
|
selectedPhotos.map((item, index) => (
|
||||||
|
<View
|
||||||
|
key={`selected-image-${index}`}
|
||||||
|
style={[styles.image, imageStyle]}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => handleRemovePhoto(item)}
|
||||||
|
style={styles.removePhotoButton}>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="xmark"
|
||||||
|
size={16}
|
||||||
|
style={{color: colors.white}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<Image style={[styles.image, imageStyle]} source={{uri: item}} />
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
imageContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginTop: 16,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
borderRadius: 8,
|
||||||
|
margin: 2,
|
||||||
|
},
|
||||||
|
image250: {
|
||||||
|
width: 250,
|
||||||
|
height: 250,
|
||||||
|
},
|
||||||
|
image175: {
|
||||||
|
width: 175,
|
||||||
|
height: 175,
|
||||||
|
},
|
||||||
|
image85: {
|
||||||
|
width: 85,
|
||||||
|
height: 85,
|
||||||
|
},
|
||||||
|
removePhotoButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 8,
|
||||||
|
right: 8,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
borderRadius: 12,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: colors.black,
|
||||||
|
zIndex: 1,
|
||||||
|
},
|
||||||
|
})
|
|
@ -56,6 +56,9 @@ import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark'
|
||||||
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
||||||
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
||||||
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
||||||
|
import {faCamera} from '@fortawesome/free-solid-svg-icons/faCamera'
|
||||||
|
import {faImage} from '@fortawesome/free-solid-svg-icons/faImage'
|
||||||
|
import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark'
|
||||||
|
|
||||||
export function setup() {
|
export function setup() {
|
||||||
library.add(
|
library.add(
|
||||||
|
@ -115,5 +118,8 @@ export function setup() {
|
||||||
faTicket,
|
faTicket,
|
||||||
faTrashCan,
|
faTrashCan,
|
||||||
faX,
|
faX,
|
||||||
|
faCamera,
|
||||||
|
faImage,
|
||||||
|
faXmark,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -1897,6 +1897,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
merge-options "^3.0.4"
|
merge-options "^3.0.4"
|
||||||
|
|
||||||
|
"@react-native-camera-roll/camera-roll@^5.1.0":
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-5.1.0.tgz#5cfb3cf02d72ab03b3d6a0bdda392e2896c8d55f"
|
||||||
|
integrity sha512-74pavpt2T2U3V0r5d+pn4NChJbRNcydqakp3NVmosod35Lzxrt9My7kCLDdHXW2S6J6DhgXb/n36/heZQB4AUA==
|
||||||
|
|
||||||
"@react-native-clipboard/clipboard@^1.10.0":
|
"@react-native-clipboard/clipboard@^1.10.0":
|
||||||
version "1.11.1"
|
version "1.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.11.1.tgz#d3a9e685ce2383b1e92b89a334896c5575cc103d"
|
resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.11.1.tgz#d3a9e685ce2383b1e92b89a334896c5575cc103d"
|
||||||
|
@ -10191,6 +10196,11 @@ react-native-gradle-plugin@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.6.tgz#b61a9234ad2f61430937911003cddd7e15c72b45"
|
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.6.tgz#b61a9234ad2f61430937911003cddd7e15c72b45"
|
||||||
integrity sha512-eIlgtsmDp1jLC24dRn43hB3kEcZVqx6DUQbR0N1ABXGnMEafm9I3V3dUUeD1vh+Dy5WqijSoEwLNUPLgu5zDMg==
|
integrity sha512-eIlgtsmDp1jLC24dRn43hB3kEcZVqx6DUQbR0N1ABXGnMEafm9I3V3dUUeD1vh+Dy5WqijSoEwLNUPLgu5zDMg==
|
||||||
|
|
||||||
|
react-native-image-crop-picker@^0.38.1:
|
||||||
|
version "0.38.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.38.1.tgz#5973b4a8b55835b987e6be2064de411e849ac005"
|
||||||
|
integrity sha512-cF5UQnWplzHCeiCO+aiGS/0VomWaLmFf3nSsgTMPfY+8+99h8N/eHQvVdSF7RsGw50B8394wGeGyqHjjp8YRWw==
|
||||||
|
|
||||||
react-native-inappbrowser-reborn@^3.6.3:
|
react-native-inappbrowser-reborn@^3.6.3:
|
||||||
version "3.7.0"
|
version "3.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-inappbrowser-reborn/-/react-native-inappbrowser-reborn-3.7.0.tgz#849a43c3c7da22b65147649fe596836bcb494083"
|
resolved "https://registry.yarnpkg.com/react-native-inappbrowser-reborn/-/react-native-inappbrowser-reborn-3.7.0.tgz#849a43c3c7da22b65147649fe596836bcb494083"
|
||||||
|
|
Loading…
Reference in New Issue