Basic profile images working

This commit is contained in:
Zhiyuan Zheng 2021-05-13 02:03:24 +02:00
parent 87343989cf
commit d4c93750c7
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
7 changed files with 279 additions and 138 deletions

View File

@ -35,6 +35,10 @@ PODS:
- React-Core
- UMCore
- UMImageLoaderInterface
- EXImageManipulator (9.1.0):
- UMCore
- UMFileSystemInterface
- UMImageLoaderInterface
- EXImagePicker (10.1.4):
- UMCore
- UMFileSystemInterface
@ -530,6 +534,7 @@ DEPENDENCIES:
- EXFont (from `../node_modules/expo-font/ios`)
- EXHaptics (from `../node_modules/expo-haptics/ios`)
- EXImageLoader (from `../node_modules/expo-image-loader/ios`)
- EXImageManipulator (from `../node_modules/expo-image-manipulator/ios`)
- EXImagePicker (from `../node_modules/expo-image-picker/ios`)
- EXKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- EXLocalization (from `../node_modules/expo-localization/ios`)
@ -651,6 +656,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-haptics/ios"
EXImageLoader:
:path: "../node_modules/expo-image-loader/ios"
EXImageManipulator:
:path: "../node_modules/expo-image-manipulator/ios"
EXImagePicker:
:path: "../node_modules/expo-image-picker/ios"
EXKeepAwake:
@ -803,6 +810,7 @@ SPEC CHECKSUMS:
EXFont: d6fb79f9863120f0d0b26b0c2d1453bc9511e9df
EXHaptics: 2de40c5f50a9e78da92c209db06db5134d8cac0b
EXImageLoader: da941c9399e01ec28f2d5b270bdd21f2c8ca596c
EXImageManipulator: a099e4694070c7cb86aa0b0b1afa3ea184153a7d
EXImagePicker: dd05b8a5cb782c79d07d1d72e5850c6acc2b9a37
EXKeepAwake: d4e4a3ed8c1c4fd940dd62fc5a8be2a190371fd4
EXLocalization: f139efe4a06be1041815879959346e3d437a6e93

View File

@ -45,6 +45,7 @@
"expo-crypto": "~9.1.0",
"expo-firebase-analytics": "~4.0.2",
"expo-haptics": "~10.0.0",
"expo-image-manipulator": "~9.1.0",
"expo-image-picker": "~10.1.4",
"expo-linking": "~2.2.3",
"expo-localization": "~10.1.0",
@ -89,8 +90,8 @@
"valid-url": "^1.0.9"
},
"devDependencies": {
"@babel/core": "~7.14.0",
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
"@babel/core": "~7.14.2",
"@babel/plugin-proposal-optional-chaining": "^7.14.2",
"@babel/preset-typescript": "^7.13.0",
"@expo/config": "^3.3.40",
"@jest/types": "^26.6.2",

View File

@ -1,6 +1,4 @@
declare namespace Nav {
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
type RootStackParamList = {
'Screen-Tabs': undefined
'Screen-Actions':

View File

@ -1,13 +1,14 @@
import * as ImagePicker from 'expo-image-picker'
import { Alert, Linking } from 'react-native'
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
import i18next from 'i18next'
import analytics from '@components/analytics'
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
import * as ImageManipulator from 'expo-image-manipulator'
import * as ImagePicker from 'expo-image-picker'
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types'
import i18next from 'i18next'
import { Alert, Linking } from 'react-native'
export interface Props {
mediaTypes?: ImagePicker.MediaTypeOptions
uploader: (imageInfo: ImageInfo) => void
resize?: { width?: number; height?: number } // Resize mode contain
showActionSheetWithOptions: (
options: ActionSheetOptions,
callback: (i: number) => void
@ -16,118 +17,134 @@ export interface Props {
const mediaSelector = async ({
mediaTypes = ImagePicker.MediaTypeOptions.All,
uploader,
resize,
showActionSheetWithOptions
}: Props): Promise<any> => {
showActionSheetWithOptions(
{
title: i18next.t('componentMediaSelector:title'),
options: [
i18next.t('componentMediaSelector:options.library'),
i18next.t('componentMediaSelector:options.photo'),
i18next.t('componentMediaSelector:options.cancel')
],
cancelButtonIndex: 2
},
async buttonIndex => {
if (buttonIndex === 0) {
const {
status
} = await ImagePicker.requestMediaLibraryPermissionsAsync()
if (status !== 'granted') {
Alert.alert(
i18next.t('componentMediaSelector:library.alert.title'),
i18next.t('componentMediaSelector:library.alert.message'),
[
{
text: i18next.t(
'componentMediaSelector:library.alert.buttons.cancel'
),
style: 'cancel',
onPress: () =>
analytics('mediaSelector_nopermission', { action: 'cancel' })
},
{
text: i18next.t(
'componentMediaSelector:library.alert.buttons.settings'
),
style: 'default',
onPress: () => {
analytics('mediaSelector_nopermission', {
action: 'settings'
})
Linking.openURL('app-settings:')
}
}
]
)
} else {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes,
exif: false
})
if (!result.cancelled) {
// https://github.com/expo/expo/issues/11214
const fixResult = {
...result,
uri: result.uri.replace('file:/data', 'file:///data')
}
uploader(fixResult)
return
}: Props): Promise<ImageInfo> => {
return new Promise((resolve, reject) => {
const resolveResult = async (result: ImageInfo) => {
if (resize && result.type === 'image') {
let newResult: ImageManipulator.ImageResult
if (resize.width && resize.height) {
if (resize.width / resize.height > result.width / result.height) {
newResult = await ImageManipulator.manipulateAsync(result.uri, [
{ resize: { width: resize.width } }
])
} else {
newResult = await ImageManipulator.manipulateAsync(result.uri, [
{ resize: { height: resize.height } }
])
}
}
} else if (buttonIndex === 1) {
const { status } = await ImagePicker.requestCameraPermissionsAsync()
if (status !== 'granted') {
Alert.alert(
i18next.t('componentMediaSelector:photo.alert.title'),
i18next.t('componentMediaSelector:photo.alert.message'),
[
{
text: i18next.t(
'componentMediaSelector:photo.alert.buttons.cancel'
),
style: 'cancel',
onPress: () => {
analytics('compose_addattachment_camera_nopermission', {
action: 'cancel'
})
}
},
{
text: i18next.t(
'componentMediaSelector:photo.alert.buttons.settings'
),
style: 'default',
onPress: () => {
analytics('compose_addattachment_camera_nopermission', {
action: 'settings'
})
Linking.openURL('app-settings:')
}
}
]
)
} else {
const result = await ImagePicker.launchCameraAsync({
mediaTypes,
exif: false
})
newResult = await ImageManipulator.manipulateAsync(result.uri, [
{ resize }
])
}
resolve(newResult)
} else {
resolve(result)
}
}
if (!result.cancelled) {
// https://github.com/expo/expo/issues/11214
const fixResult = {
...result,
uri: result.uri.replace('file:/data', 'file:///data')
showActionSheetWithOptions(
{
title: i18next.t('componentMediaSelector:title'),
options: [
i18next.t('componentMediaSelector:options.library'),
i18next.t('componentMediaSelector:options.photo'),
i18next.t('componentMediaSelector:options.cancel')
],
cancelButtonIndex: 2
},
async buttonIndex => {
if (buttonIndex === 0) {
const {
status
} = await ImagePicker.requestMediaLibraryPermissionsAsync()
if (status !== 'granted') {
Alert.alert(
i18next.t('componentMediaSelector:library.alert.title'),
i18next.t('componentMediaSelector:library.alert.message'),
[
{
text: i18next.t(
'componentMediaSelector:library.alert.buttons.cancel'
),
style: 'cancel',
onPress: () =>
analytics('mediaSelector_nopermission', {
action: 'cancel'
})
},
{
text: i18next.t(
'componentMediaSelector:library.alert.buttons.settings'
),
style: 'default',
onPress: () => {
analytics('mediaSelector_nopermission', {
action: 'settings'
})
Linking.openURL('app-settings:')
}
}
]
)
} else {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes,
exif: false
})
if (!result.cancelled) {
await resolveResult(result)
}
}
} else if (buttonIndex === 1) {
const { status } = await ImagePicker.requestCameraPermissionsAsync()
if (status !== 'granted') {
Alert.alert(
i18next.t('componentMediaSelector:photo.alert.title'),
i18next.t('componentMediaSelector:photo.alert.message'),
[
{
text: i18next.t(
'componentMediaSelector:photo.alert.buttons.cancel'
),
style: 'cancel',
onPress: () => {
analytics('compose_addattachment_camera_nopermission', {
action: 'cancel'
})
}
},
{
text: i18next.t(
'componentMediaSelector:photo.alert.buttons.settings'
),
style: 'default',
onPress: () => {
analytics('compose_addattachment_camera_nopermission', {
action: 'settings'
})
Linking.openURL('app-settings:')
}
}
]
)
} else {
const result = await ImagePicker.launchCameraAsync({
mediaTypes,
exif: false
})
if (!result.cancelled) {
await resolveResult(result)
}
uploader(fixResult)
return
}
}
}
}
)
)
})
}
export default mediaSelector

View File

@ -123,7 +123,8 @@ const addAttachment = async ({
})
}
mediaSelector({ uploader, showActionSheetWithOptions })
const result = await mediaSelector({ showActionSheetWithOptions })
await uploader(result)
}
export default addAttachment

View File

@ -1,7 +1,10 @@
import GracefullyImage from '@components/GracefullyImage'
import mediaSelector from '@components/mediaSelector'
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { StackScreenProps } from '@react-navigation/stack'
import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile'
import * as ImagePicker from 'expo-image-picker'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollView } from 'react-native-gesture-handler'
@ -87,30 +90,48 @@ const TabMeProfileRoot: React.FC<StackScreenProps<
<MenuRow
title={t('me.profile.root.avatar.title')}
description={t('me.profile.root.avatar.description')}
// content={
// <GracefullyImage
// style={{ flex: 1 }}
// uri={{
// original: data?.avatar_static
// }}
// />
// }
// loading={isLoading}
// iconBack='ChevronRight'
content={
<GracefullyImage
key={data?.avatar_static}
style={{ flex: 1 }}
uri={{
original: data?.avatar_static
}}
/>
}
loading={isLoading}
iconBack='ChevronRight'
onPress={async () => {
const image = await mediaSelector({
showActionSheetWithOptions,
mediaTypes: ImagePicker.MediaTypeOptions.Images,
resize: { width: 400, height: 400 }
})
mutate({ type: 'avatar', data: image.uri })
}}
/>
<MenuRow
title={t('me.profile.root.banner.title')}
description={t('me.profile.root.banner.description')}
// content={
// <GracefullyImage
// style={{ flex: 1 }}
// uri={{
// original: data?.header_static
// }}
// />
// }
// loading={isLoading}
// iconBack='ChevronRight'
content={
<GracefullyImage
key={data?.header_static}
style={{ flex: 1 }}
uri={{
original: data?.header_static
}}
/>
}
loading={isLoading}
iconBack='ChevronRight'
onPress={async () => {
const image = await mediaSelector({
showActionSheetWithOptions,
mediaTypes: ImagePicker.MediaTypeOptions.Images,
resize: { width: 1500, height: 500 }
})
mutate({ type: 'header', data: image.uri })
}}
/>
<MenuRow
title={t('me.profile.root.note.title')}
@ -118,9 +139,10 @@ const TabMeProfileRoot: React.FC<StackScreenProps<
loading={isLoading}
iconBack='ChevronRight'
onPress={() => {
navigation.navigate('Tab-Me-Profile-Note', {
note: data?.source?.note || ''
})
data &&
navigation.navigate('Tab-Me-Profile-Note', {
note: data.source?.note
})
}}
/>
<MenuRow

View File

@ -43,7 +43,7 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.7.5", "@babel/core@~7.14.0":
"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.7.5":
version "7.14.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88"
integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==
@ -64,6 +64,27 @@
semver "^6.3.0"
source-map "^0.5.0"
"@babel/core@~7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.2.tgz#54e45334ffc0172048e5c93ded36461d3ad4c417"
integrity sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.14.2"
"@babel/helper-compilation-targets" "^7.13.16"
"@babel/helper-module-transforms" "^7.14.2"
"@babel/helpers" "^7.14.0"
"@babel/parser" "^7.14.2"
"@babel/template" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.1.2"
semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.14.0", "@babel/generator@^7.5.0", "@babel/generator@^7.9.0":
version "7.14.1"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93"
@ -73,6 +94,15 @@
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/generator@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.2.tgz#d5773e8b557d421fd6ce0d5efa5fd7fc22567c30"
integrity sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==
dependencies:
"@babel/types" "^7.14.2"
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
@ -148,6 +178,15 @@
"@babel/template" "^7.12.13"
"@babel/types" "^7.12.13"
"@babel/helper-function-name@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2"
integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==
dependencies:
"@babel/helper-get-function-arity" "^7.12.13"
"@babel/template" "^7.12.13"
"@babel/types" "^7.14.2"
"@babel/helper-get-function-arity@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
@ -191,6 +230,20 @@
"@babel/traverse" "^7.14.0"
"@babel/types" "^7.14.0"
"@babel/helper-module-transforms@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5"
integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==
dependencies:
"@babel/helper-module-imports" "^7.13.12"
"@babel/helper-replace-supers" "^7.13.12"
"@babel/helper-simple-access" "^7.13.12"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-validator-identifier" "^7.14.0"
"@babel/template" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
"@babel/helper-optimise-call-expression@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
@ -286,6 +339,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47"
integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==
"@babel/parser@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746"
integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a"
@ -421,6 +479,15 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-proposal-optional-chaining@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e"
integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==
dependencies:
"@babel/helper-plugin-utils" "^7.13.0"
"@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-proposal-private-methods@^7.12.13", "@babel/plugin-proposal-private-methods@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787"
@ -1140,6 +1207,20 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/traverse@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b"
integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.14.2"
"@babel/helper-function-name" "^7.14.2"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/parser" "^7.14.2"
"@babel/types" "^7.14.2"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.9.0":
version "7.14.1"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db"
@ -1148,6 +1229,14 @@
"@babel/helper-validator-identifier" "^7.14.0"
to-fast-properties "^2.0.0"
"@babel/types@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.2.tgz#4208ae003107ef8a057ea8333e56eb64d2f6a2c3"
integrity sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==
dependencies:
"@babel/helper-validator-identifier" "^7.14.0"
to-fast-properties "^2.0.0"
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@ -4609,6 +4698,11 @@ expo-image-loader@~2.1.1:
resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-2.1.1.tgz#028ae58f7c7a33ca9a406716c2b31969216d016f"
integrity sha512-EeItNIsmw4g+FIb9S9AHE7FAWQkuiIguFMua/RQ2mFHKFZYa/BU32MGagY+e4LzasBVbDKWgd3NHO+EYC6XeEA==
expo-image-manipulator@~9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-9.1.0.tgz#c1bac33c071e116a97a654f9f11bf50f7ff8932c"
integrity sha512-jguMQ3k63JJwxo1mAsLRa+lXbH9fVsQXKbOfwY5KKXvNld7aaRgCO6pWnrBfCxvKkU4KhVp9JWOrsz4qcnYQ2w==
expo-image-picker@~10.1.4:
version "10.1.4"
resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-10.1.4.tgz#5805ea365385298cd59315790481a0a8d6c6a9ef"