Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

[C-2994] Improve mobile image selection #4041

Merged
merged 7 commits into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/common/src/store/cache/collections/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type Image = {
size?: number
fileType?: string
url: string
file?: string | File
file?: string | File | { uri: string; name: string; type: string }
}

export type EditPlaylistValues = Collection & {
Expand Down
2 changes: 1 addition & 1 deletion packages/mobile/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true

vectorDrawables.useSupportLibrary = true
// versionCode is automatically incremented in CI
versionCode 1
// Make sure this is above the currently released Android version in the play store if your changes touch native code:
Expand Down
5 changes: 5 additions & 0 deletions packages/mobile/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />


<application android:usesCleartextTraffic="true" android:name=".MainApplication" android:label="@string/app_name" android:icon="${appIcon}" android:resource="@mipmap/ic_notification" android:allowBackup="false" android:largeHeap="true" android:theme="@style/BootTheme">
<activity android:name=".MainActivity" android:launchMode="singleTask" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize" android:exported="true">
<intent-filter android:autoVerify="true">
Expand Down
3 changes: 3 additions & 0 deletions packages/mobile/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ buildscript {

allprojects {
repositories {
maven { url "$rootDir/../node_modules/react-native/android" }
maven { url 'https://maven.google.com' }
maven { url "https://www.jitpack.io" }
maven { url "https://maven.fpregistry.io/releases" }
maven { url "https://storage.googleapis.com/snap-kit-build/maven" }
maven { url "https://artifact.bytedance.com/repository/AwemeOpenSDK" }
Expand Down
16 changes: 16 additions & 0 deletions packages/mobile/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,15 @@ PODS:
- React
- RNGestureHandler (1.10.3):
- React-Core
- RNImageCropPicker (0.40.0):
- React-Core
- React-RCTImage
- RNImageCropPicker/QBImagePickerController (= 0.40.0)
- TOCropViewController
- RNImageCropPicker/QBImagePickerController (0.40.0):
- React-Core
- React-RCTImage
- TOCropViewController
- RNPermissions (3.0.5):
- React-Core
- RNReactNativeHapticFeedback (1.11.0):
Expand Down Expand Up @@ -725,6 +734,7 @@ PODS:
- SSZipArchive (2.2.3)
- SwiftAudioEx (0.15.3)
- TikTokOpenSDK (5.0.0)
- TOCropViewController (2.6.1)
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
Expand Down Expand Up @@ -834,6 +844,7 @@ DEPENDENCIES:
- "RNFingerprintjsPro (from `../../../node_modules/@fingerprintjs/fingerprintjs-pro-react-native`)"
- RNFS (from `../../../node_modules/react-native-fs`)
- RNGestureHandler (from `../../../node_modules/react-native-gesture-handler`)
- RNImageCropPicker (from `../../../node_modules/react-native-image-crop-picker`)
- RNPermissions (from `../../../node_modules/react-native-permissions`)
- RNReactNativeHapticFeedback (from `../../../node_modules/react-native-haptic-feedback`)
- RNReanimated (from `../../../node_modules/react-native-reanimated`)
Expand Down Expand Up @@ -889,6 +900,7 @@ SPEC REPOS:
- SSZipArchive
- SwiftAudioEx
- TikTokOpenSDK
- TOCropViewController
- YogaKit

EXTERNAL SOURCES:
Expand Down Expand Up @@ -1050,6 +1062,8 @@ EXTERNAL SOURCES:
:path: "../../../node_modules/react-native-fs"
RNGestureHandler:
:path: "../../../node_modules/react-native-gesture-handler"
RNImageCropPicker:
:path: "../../../node_modules/react-native-image-crop-picker"
RNPermissions:
:path: "../../../node_modules/react-native-permissions"
RNReactNativeHapticFeedback:
Expand Down Expand Up @@ -1184,6 +1198,7 @@ SPEC CHECKSUMS:
RNFingerprintjsPro: 317426b3f0479c4737960f7aa90b0f8a02ac07f9
RNFS: 3ab21fa6c56d65566d1fb26c2228e2b6132e5e32
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNImageCropPicker: 486e2f7e2b0461ce24321f751410dce1b3b49e6d
RNPermissions: 7043bacbf928eae25808275cfe73799b8f618911
RNReactNativeHapticFeedback: 653a8c126a0f5e88ce15ffe280b3ff37e1fbb285
RNReanimated: addc4900bf47882118d0a1b21747fa6705fa8cff
Expand All @@ -1202,6 +1217,7 @@ SPEC CHECKSUMS:
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
SwiftAudioEx: 83eabba2940924fc1c0d5cb0896049921365229c
TikTokOpenSDK: a63564ea4dc1fabc56352bf7aa9ddc386cdb63b6
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a

Expand Down
1 change: 1 addition & 0 deletions packages/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"react-native-get-random-values": "1.8.0",
"react-native-google-cast": "4.6.0",
"react-native-haptic-feedback": "1.11.0",
"react-native-image-crop-picker": "^0.40.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📍

"react-native-image-picker": "4.10.2",
"react-native-in-app-review": "4.2.1",
"react-native-keyboard-aware-scroll-view": "0.9.5",
Expand Down
7 changes: 2 additions & 5 deletions packages/mobile/src/components/core/Screen/ScreenContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ export type ScreenContentProps = OfflinePlaceholderProps & {
isOfflineCapable?: boolean
}

export const ScreenContent = ({
children,
isOfflineCapable,
...other
}: ScreenContentProps) => {
export const ScreenContent = (props: ScreenContentProps) => {
const { children, isOfflineCapable, ...other } = props
const isReachable = useSelector(getIsReachable)
const wasReachable = usePrevious(isReachable)

Expand Down
2 changes: 0 additions & 2 deletions packages/mobile/src/components/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ export * from './Button'
export * from './CardList'
export * from './DynamicImage'
export * from './EmptyTile'
export * from './FormTextInput'
export * from './FormImageInput'
export * from './GradientIcon'
export * from './GradientText'
export * from './Hyperlink'
Expand Down
26 changes: 9 additions & 17 deletions packages/mobile/src/components/fields/PickArtworkField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useCallback, useMemo, useState } from 'react'

import { useField } from 'formik'
import { View } from 'react-native'
import type { Asset } from 'react-native-image-picker'

import IconImage from 'app/assets/images/iconImage.svg'
import IconPencil from 'app/assets/images/iconPencil.svg'
Expand Down Expand Up @@ -56,7 +55,7 @@ const messages = {

type PickArtworkFieldProps = {
name: string
onChange?: (image: Asset) => void
onChange?: () => void
buttonTitle?: string
onPress?: () => void
onImageLoad?: () => void
Expand All @@ -73,24 +72,17 @@ export const PickArtworkField = (props: PickArtworkFieldProps) => {
const trackArtworkUrl = value?.url ?? existingTrackArtwork
const [isImageLoading, setIsImageLoading] = useState(false)

const { secondary } = useThemeColors()

const handleChangeArtwork = useCallback(() => {
const handleImageSelected = (_image: Image, rawResponse: Asset) => {
setArtwork({
url: rawResponse.uri,
file: {
uri: rawResponse.uri,
name: rawResponse.fileName,
type: rawResponse.type
},
source: 'original'
})
onChange?.(rawResponse)
const handleImageSelected = (image: Image) => {
setArtwork(image)
onChange?.()
setIsImageLoading(true)
}
launchSelectImageActionSheet(handleImageSelected, secondary)
}, [secondary, setArtwork, onChange])
launchSelectImageActionSheet(handleImageSelected, {
height: 1000,
width: 1000
})
}, [setArtwork, onChange])

const handleImageLoad = useCallback(() => {
onImageLoad?.()
Expand Down
17 changes: 4 additions & 13 deletions packages/mobile/src/components/form-screen/FormScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ type FormScreenProps = ScreenProps & {
onSubmit: () => void
onReset: () => void
errors?: Record<string, unknown>
goBackOnSubmit?: boolean
}

export const FormScreen = ({ children, ...props }: FormScreenProps) => {
const { onSubmit, onReset, errors, goBackOnSubmit, ...other } = props
export const EditProfileFormScreen = (props: FormScreenProps) => {
const { children, onSubmit, onReset, errors, ...other } = props

const navigation = useNavigation()

Expand All @@ -29,13 +28,6 @@ export const FormScreen = ({ children, ...props }: FormScreenProps) => {
navigation.goBack()
}, [navigation, onReset])

const handleSave = useCallback(() => {
onSubmit()
if (goBackOnSubmit) {
navigation.goBack()
}
}, [onSubmit, goBackOnSubmit, navigation])

const topbarLeft = (
<TextButton
title={messages.cancel}
Expand All @@ -48,15 +40,14 @@ export const FormScreen = ({ children, ...props }: FormScreenProps) => {
<TextButton
title={messages.save}
variant='primary'
onPress={handleSave}
onPress={onSubmit}
disabled={!isEmpty(errors)}
/>
)

// TODO: add <ScreenContent> to usages of SafeAreaScreen
return (
<Screen
variant={'white'}
variant='white'
topbarLeft={topbarLeft}
topbarRight={topbarRight}
{...other}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ import IconInstagram from 'app/assets/images/iconInstagram.svg'
import IconLink from 'app/assets/images/iconLink.svg'
import IconTikTokInverted from 'app/assets/images/iconTikTokInverted.svg'
import IconTwitterBird from 'app/assets/images/iconTwitterBird.svg'
import { FormImageInput, FormTextInput, ScrollView } from 'app/components/core'
import { FormScreen } from 'app/components/form-screen'
import { ScrollView } from 'app/components/core'
import { EditProfileFormScreen } from 'app/components/form-screen'
import { useUserCoverImage } from 'app/components/image/UserCoverImage'
import { useUserImage } from 'app/components/image/UserImage'
import { isImageUriSource } from 'app/hooks/useContentNodeImage'
import { useNavigation } from 'app/hooks/useNavigation'
import { makeStyles } from 'app/styles'
import type { Image } from 'app/types/image'

import { ProfileImageField } from './ProfileImageField'
import { ProfileTextField } from './ProfileTextField'
import type { ProfileValues, UpdatedProfile } from './types'

const { getAccountUser } = accountSelectors
Expand Down Expand Up @@ -74,53 +76,60 @@ const EditProfileForm = (props: EditProfileFormProps) => {
handleReset,
isTwitterVerified,
isInstagramVerified,
isTikTokVerified
isTikTokVerified,
errors
} = props
const styles = useStyles()

return (
<FormScreen variant='white' onReset={handleReset} onSubmit={handleSubmit}>
<FormImageInput
<EditProfileFormScreen
onReset={handleReset}
onSubmit={handleSubmit}
errors={errors}
>
<ProfileImageField
name='cover_photo'
styles={{ imageContainer: styles.coverPhoto }}
imageOptions={{ height: 500, width: 2000, freeStyleCropEnabled: true }}
/>
<FormImageInput
<ProfileImageField
name='profile_picture'
styles={{
root: styles.profilePicture,
imageContainer: styles.profilePictureImageContainer,
image: styles.profilePictureImage
}}
imageOptions={{ height: 1000, width: 1000, cropperCircleOverlay: true }}
/>
<ScrollView style={styles.textFields}>
<FormTextInput isFirstInput name='name' label='Name' />
<FormTextInput name='bio' label='Bio' multiline maxLength={256} />
<FormTextInput name='location' label='Location' />
<FormTextInput
<ProfileTextField isFirstInput name='name' label='Name' />
<ProfileTextField name='bio' label='Bio' multiline maxLength={256} />
<ProfileTextField name='location' label='Location' />
<ProfileTextField
editable={!isTwitterVerified}
name='twitter_handle'
label='Twitter Handle'
prefix='@'
icon={IconTwitterBird}
/>
<FormTextInput
<ProfileTextField
editable={!isInstagramVerified}
name='instagram_handle'
label='Instagram Handle'
prefix='@'
icon={IconInstagram}
/>
<FormTextInput
<ProfileTextField
editable={!isTikTokVerified}
name='tiktok_handle'
label='TikTok Handle'
prefix='@'
icon={IconTikTokInverted}
/>
<FormTextInput name='website' label='Website' icon={IconLink} />
<FormTextInput name='donation' label='Donation' icon={IconDonate} />
<ProfileTextField name='website' label='Website' icon={IconLink} />
<ProfileTextField name='donation' label='Donation' icon={IconDonate} />
</ScrollView>
</FormScreen>
</EditProfileFormScreen>
)
}

Expand Down
Loading