|
1 | 1 | --- |
2 | 2 | id: apis/CameraRoll |
3 | 3 | title: CameraRoll |
4 | | -wip: false |
5 | 4 | --- |
6 | 5 |
|
7 | 6 | ## Methods |
8 | 7 |
|
9 | | -- `saveToCameraRoll` allows saving photos and videos to the Camera Roll. File to be saved is specified as a tag which can be |
| 8 | +- `saveToCameraRoll` allows saving photos and videos to the Camera Roll or Photo Gallery. File to be saved is specified as a tag which can be |
10 | 9 |
|
11 | 10 | - on Android, a local image or video URI, such as "file:///sdcard/img.png" |
12 | 11 | - on iOS, a local video URI or any image URI (local, remote asset-library, or base64 data URIs) |
@@ -40,7 +39,9 @@ The function will return a `photoIdentifiersPage` object wrapped in a Promise, t |
40 | 39 |
|
41 | 40 | ## Types |
42 | 41 |
|
43 | | -- `getPhotosParams` can be constructed with its eponymous constructor |
| 42 | +- `getPhotosParams` can be constructed with the constructor of the same name |
| 43 | + - `first` takes an integer which specifies the number of files for which details will be returned. Files will match in reverse order (i.e. most recent first) |
| 44 | + - `after` takes a string which should be obtained from `photoIdentifiersPage` returned in a previous `getPhotos` call, under the `end_cursor` key contained in turn under the `page_info` key. |
44 | 45 |
|
45 | 46 | ```reason |
46 | 47 | getPhotosParams: |
@@ -130,7 +131,99 @@ type action = |
130 | 131 | | SetPath(string) |
131 | 132 | | SetPhotos(array(CameraRoll.photoIdentifier)); |
132 | 133 |
|
133 | | -let textStyle = Style.style(~textAlign=`center, ()); |
| 134 | +let styles = Style.( |
| 135 | + StyleSheet.create({ |
| 136 | + "container": |
| 137 | + style( |
| 138 | + ~flex=1., |
| 139 | + ~flexDirection=`column, |
| 140 | + ~alignItems=`center, |
| 141 | + ~justifyContent=`spaceBetween, |
| 142 | + (), |
| 143 | + ), |
| 144 | + "getPhotosExample": |
| 145 | + style( |
| 146 | + ~height=pt(0.25 *. windowHeight), |
| 147 | + ~justifyContent=`spaceBetween, |
| 148 | + (), |
| 149 | + ), |
| 150 | + "saveToCameraRollExample": |
| 151 | + style( |
| 152 | + ~width=pt(0.8 *. windowWidth), |
| 153 | + ~height=pt(0.6 *. windowHeight), |
| 154 | + ~margin=pt(0.1 *. windowWidth), |
| 155 | + ~justifyContent=`spaceAround, |
| 156 | + (), |
| 157 | + ), |
| 158 | + "image": |
| 159 | + style( |
| 160 | + ~width=pt(0.8 *. windowWidth), |
| 161 | + ~height=pt(0.56 *. windowWidth), |
| 162 | + (), |
| 163 | + ), |
| 164 | + "imageContainer": |
| 165 | + style( |
| 166 | + ~width=pt(0.8 *. windowWidth), |
| 167 | + ~height=pt(0.56 *. windowWidth), |
| 168 | + ~borderWidth=1., |
| 169 | + ~justifyContent=`center, |
| 170 | + (), |
| 171 | + ), |
| 172 | + "text": style(~textAlign=`center, ()), |
| 173 | + "textInput": |
| 174 | + style( |
| 175 | + ~textAlign=`center, |
| 176 | + ~borderRadius=8., |
| 177 | + ~padding=pt(4.), |
| 178 | + ~borderWidth=1., |
| 179 | + ~backgroundColor=Color.linen, |
| 180 | + (), |
| 181 | + ), |
| 182 | + "thumbnail": |
| 183 | + style( |
| 184 | + ~width=pt(0.21 *. windowHeight), |
| 185 | + ~height=pt(0.15 *. windowHeight), |
| 186 | + (), |
| 187 | + ), |
| 188 | + "thumbnails": |
| 189 | + style( |
| 190 | + ~height=pt(0.15 *. windowHeight), |
| 191 | + (), |
| 192 | + ), |
| 193 | + }) |
| 194 | +); |
| 195 | +
|
| 196 | +let styledText = s => { |
| 197 | + <Text style=styles##text> s->React.string </Text>; |
| 198 | +}; |
| 199 | +
|
| 200 | +let thumbnails = photos => { |
| 201 | + <View style=styles##thumbnails> |
| 202 | + <ScrollView horizontal=true> |
| 203 | + {photos |
| 204 | + ->Belt.Array.mapWithIndex((i, s) => |
| 205 | + <Image |
| 206 | + style=styles##thumbnail |
| 207 | + source={Image.Source.fromUriSource( |
| 208 | + Image.uriSource(~uri=s##node##image##uri, ()), |
| 209 | + )} |
| 210 | + key={string_of_int(i)} |
| 211 | + /> |
| 212 | + ) |
| 213 | + ->React.array} |
| 214 | + </ScrollView> |
| 215 | + </View>; |
| 216 | +}; |
| 217 | +
|
| 218 | +let inputBox = (tag, dispatch) => { |
| 219 | + <TextInput |
| 220 | + style=styles##textInput |
| 221 | + multiline=true |
| 222 | + defaultValue="https://images.unsplash.com/photo-1520453803296-c39eabe2dab4" |
| 223 | + value=tag |
| 224 | + onChangeText={s => dispatch(SetTag(s))} |
| 225 | + />; |
| 226 | +}; |
134 | 227 |
|
135 | 228 | [@react.component] |
136 | 229 | let make = () => { |
@@ -174,113 +267,43 @@ let make = () => { |
174 | 267 | ); |
175 | 268 | }; |
176 | 269 |
|
177 | | - <View |
178 | | - style={Style.style( |
179 | | - ~flex=1., |
180 | | - ~flexDirection=`column, |
181 | | - ~alignItems=`center, |
182 | | - ~justifyContent=`spaceBetween, |
183 | | - (), |
184 | | - )}> |
185 | | - <View |
186 | | - style={Style.style( |
187 | | - ~width=Style.pt(0.8 *. windowWidth), |
188 | | - ~height=Style.pt(0.6 *. windowHeight), |
189 | | - ~margin=Style.pt(0.1 *. windowWidth), |
190 | | - // ~marginBottom=Style.pt(0.1 *. windowWidth), |
191 | | - ~justifyContent=`spaceAround, |
192 | | - (), |
193 | | - )}> |
194 | | - <View |
195 | | - style={Style.style( |
196 | | - ~width=Style.pt(0.8 *. windowWidth), |
197 | | - ~height=Style.pt(0.56 *. windowWidth), |
198 | | - ~borderWidth=1., |
199 | | - ~justifyContent=`center, |
200 | | - (), |
201 | | - )}> |
| 270 | + <View style=styles##container> |
| 271 | + <View style=styles##saveToCameraRollExample> |
| 272 | + <View style=styles##imageContainer> |
202 | 273 | {switch (state.path) { |
203 | 274 | | None => |
| 275 | + // default view, before a photo is saved to the Camera Roll or Photo Library |
204 | 276 | <View> |
205 | | - <Text style=textStyle> |
206 | | - "Press the Save Photo button"->React.string |
207 | | - </Text> |
208 | | - <Text style=textStyle> "below to load photo"->React.string </Text> |
| 277 | + {styledText("Press the Save Photo button")} |
| 278 | + {styledText("below to load photo")} |
209 | 279 | </View> |
210 | | -
|
211 | 280 | | Some(p) => |
| 281 | + // Once a photo is saved to the Camera Roll or Photo Library, it will be displayed in this view |
212 | 282 | <Image |
213 | | - style={Style.style( |
214 | | - ~width=Style.pt(0.8 *. windowWidth), |
215 | | - ~height=Style.pt(0.56 *. windowWidth), |
216 | | - (), |
217 | | - )} |
| 283 | + style=styles##image |
218 | 284 | source={Image.Source.fromUriSource(Image.uriSource(~uri=p, ()))} |
219 | 285 | /> |
220 | 286 | }} |
221 | 287 | </View> |
222 | 288 | <View> |
223 | | - <Text style=textStyle> |
224 | | - "Enter a path for a photo to save,"->React.string |
225 | | - </Text> |
226 | | - <Text style=textStyle> |
227 | | - "or try the example given below"->React.string |
228 | | - </Text> |
229 | | - <TextInput |
230 | | - style={Style.array([| |
231 | | - textStyle, |
232 | | - Style.style( |
233 | | - ~borderRadius=8., |
234 | | - ~padding=Style.pt(4.), |
235 | | - ~borderWidth=1., |
236 | | - ~backgroundColor=Color.linen, |
237 | | - (), |
238 | | - ), |
239 | | - |])} |
240 | | - multiline=true |
241 | | - defaultValue="https://images.unsplash.com/photo-1520453803296-c39eabe2dab4" |
242 | | - value={state.tag} |
243 | | - onChangeText={s => dispatch(SetTag(s))} |
244 | | - /> |
| 289 | + {styledText("Enter a path for a photo to save,")} |
| 290 | + {styledText("or try the example given below")} |
| 291 | + // TextInput box to try other photo sources |
| 292 | + {inputBox(state.tag, dispatch)} |
| 293 | + // An attempt will be made to save the photo file specified in the TextInput box to the Camera Roll or Photo Library once the button below is pressed |
245 | 294 | <Button |
246 | 295 | onPress={_ => savePhoto(state.tag)} |
247 | 296 | title={js|Save a Photo|js} |
248 | 297 | /> |
249 | 298 | </View> |
250 | 299 | </View> |
251 | | - <View |
252 | | - style={Style.style( |
253 | | - ~height=Style.pt(0.25 *. windowHeight), |
254 | | - ~justifyContent=`spaceBetween, |
255 | | - (), |
256 | | - )}> |
| 300 | + <View style=styles##getPhotosExample> |
257 | 301 | <View> |
258 | | - <Text style=textStyle> |
259 | | - "Saved photo will be in the Camera Roll"->React.string |
260 | | - </Text> |
| 302 | + {styledText("Saved photo will appear in the Camera Roll")} |
| 303 | + // An attempt will be made to get the most recent 20 photos from the Camera Roll or Photo Library |
261 | 304 | <Button onPress={_ => getPhotos()} title={js|Open CameraRoll|js} /> |
262 | 305 | </View> |
263 | | - <View style={Style.style(~height=Style.pt(0.15 *. windowHeight), ())}> |
264 | | - <ScrollView horizontal=true> |
265 | | - {React.array( |
266 | | - Array.mapi( |
267 | | - (i, s) => |
268 | | - <Image |
269 | | - style={Style.style( |
270 | | - ~width=Style.pt(0.21 *. windowHeight), |
271 | | - ~height=Style.pt(0.15 *. windowHeight), |
272 | | - (), |
273 | | - )} |
274 | | - source={Image.Source.fromUriSource( |
275 | | - Image.uriSource(~uri=s##node##image##uri, ()), |
276 | | - )} |
277 | | - key={string_of_int(i)} |
278 | | - />, |
279 | | - state.photos, |
280 | | - ), |
281 | | - )} |
282 | | - </ScrollView> |
283 | | - </View> |
| 306 | + {thumbnails(state.photos)} |
284 | 307 | </View> |
285 | 308 | </View>; |
286 | 309 | }; |
|
0 commit comments