about summary refs log tree commit diff
path: root/src/view/com/util/UserBanner.tsx
blob: d5d6e3aaa039767db3eb5d585ca03febec8fabc1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import React, {useCallback} from 'react'
import {StyleSheet, View, TouchableOpacity, Alert, Image} from 'react-native'
import Svg, {Rect, Defs, LinearGradient, Stop} from 'react-native-svg'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {colors, gradients} from '../../lib/styles'
import {
  openCamera,
  openCropper,
  openPicker,
  PickedMedia,
} from './images/image-crop-picker/ImageCropPicker'
import {useStores} from '../../../state'

export function UserBanner({
  banner,
  onSelectNewBanner,
}: {
  banner?: string | null
  onSelectNewBanner?: (img: PickedMedia) => void
}) {
  const store = useStores()
  const handleEditBanner = useCallback(() => {
    Alert.alert('Select upload method', '', [
      {
        text: 'Take a new photo',
        onPress: () => {
          openCamera(store, {
            mediaType: 'photo',
            // compressImageMaxWidth: 3000, TODO needed?
            width: 3000,
            // compressImageMaxHeight: 1000, TODO needed?
            height: 1000,
          }).then(onSelectNewBanner)
        },
      },
      {
        text: 'Select from gallery',
        onPress: () => {
          openPicker(store, {
            mediaType: 'photo',
          }).then(async items => {
            await openCropper(store, {
              mediaType: 'photo',
              path: items[0].path,
              // compressImageMaxWidth: 3000, TODO needed?
              width: 3000,
              // compressImageMaxHeight: 1000, TODO needed?
              height: 1000,
            }).then(onSelectNewBanner)
          })
        },
      },
    ])
  }, [store, onSelectNewBanner])

  const renderSvg = () => (
    <Svg width="100%" height="150" viewBox="50 0 200 100">
      <Defs>
        <LinearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
          <Stop
            offset="0"
            stopColor={gradients.blueDark.start}
            stopOpacity="1"
          />
          <Stop offset="1" stopColor={gradients.blueDark.end} stopOpacity="1" />
        </LinearGradient>
      </Defs>
      <Rect x="0" y="0" width="400" height="100" fill="url(#grad)" />
      <Rect x="0" y="0" width="400" height="100" fill="url(#grad2)" />
    </Svg>
  )

  // setUserBanner is only passed as prop on the EditProfile component
  return onSelectNewBanner ? (
    <TouchableOpacity onPress={handleEditBanner}>
      {banner ? (
        <Image style={styles.bannerImage} source={{uri: banner}} />
      ) : (
        renderSvg()
      )}
      <View style={styles.editButtonContainer}>
        <FontAwesomeIcon
          icon="camera"
          size={12}
          style={{color: colors.white}}
        />
      </View>
    </TouchableOpacity>
  ) : banner ? (
    <Image
      style={styles.bannerImage}
      resizeMode="cover"
      source={{uri: banner}}
    />
  ) : (
    renderSvg()
  )
}

const styles = StyleSheet.create({
  editButtonContainer: {
    position: 'absolute',
    width: 24,
    height: 24,
    bottom: 8,
    right: 8,
    borderRadius: 12,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: colors.gray5,
  },
  bannerImage: {
    width: '100%',
    height: 150,
  },
})