Skip to content

Commit 81c542a

Browse files
sgnyMoOx
authored andcommitted
CameraRoll: documentation and example (#485)
1 parent ed5396f commit 81c542a

1 file changed

Lines changed: 230 additions & 26 deletions

File tree

‎reason-react-native/src/apis/CameraRoll.md‎

Lines changed: 230 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,49 @@
11
---
22
id: apis/CameraRoll
33
title: CameraRoll
4-
wip: true
4+
wip: false
55
---
66

7+
## Methods
8+
9+
- `saveToCameraRoll` allows saving photos and videos to the Camera Roll. File to be saved is specified as a tag which can be
10+
11+
- on Android, a local image or video URI, such as "file:///sdcard/img.png"
12+
- on iOS, a local video URI or any image URI (local, remote asset-library, or base64 data URIs)
13+
14+
Media type (photo or video) will be automatically inferred; any file will be inferred to be a photo, unless the file extension is `mov` or `mp4`, then it will be inferred to be a video.
15+
16+
```reason
17+
saveToCameraRoll(tag)
18+
```
19+
20+
The function will return the URI for the saved file as a string wrapped in a Promise, `Js.Promise.t(string)`.
21+
22+
- `saveToCameraRollWithType` allows saving photos and videos to the Camera Roll, where the tag will be specified as above, overriding the automatically determined type.
23+
24+
```reason
25+
saveToCameraRollWithType(tag, _type)
26+
```
27+
28+
where `_type` can be `` `photo `` or `` `video ``.
29+
30+
The function will return the URI for the saved file as a string wrapped in a Promise, `Js.Promise.t(string)`.
31+
32+
- `getPhotos` takes as argument `getPhotosParams`
33+
734
```reason
8-
type getPhotosParams;
35+
getPhotos(getPhotosParams)
36+
```
937

10-
[@bs.obj]
11-
external getPhotosParams:
38+
The function will return a `photoIdentifiersPage` object wrapped in a Promise, that is `Js.Promise.t(photoIdentifiersPage)`. Array of `photoIdentifier` will contain details of photos or videos matching parameters provided in the `getPhotosParam` object.
39+
40+
41+
## Types
42+
43+
- `getPhotosParams` can be constructed with its eponymous constructor
44+
45+
```reason
46+
getPhotosParams:
1247
(
1348
~first: int,
1449
~after: string=?,
@@ -26,10 +61,27 @@ external getPhotosParams:
2661
~assetType: [@bs.string] [ | `All | `Videos | `Photos]=?,
2762
~mimeTypes: array(string)=?,
2863
unit
29-
) =>
30-
getPhotosParams =
31-
"";
64+
)
65+
```
66+
67+
- `photoIdentifiersPage`
3268

69+
```reason
70+
type photoIdentifiersPage = {
71+
.
72+
"edges": array(photoIdentifier),
73+
"page_info": {
74+
.
75+
"has_next_page": bool,
76+
"start_cursor": Js.Nullable.t(string),
77+
"end_cursor": Js.Nullable.t(string),
78+
},
79+
};
80+
```
81+
82+
- `photoIdentifier`
83+
84+
```reason
3385
type photoIdentifier = {
3486
.
3587
"node": {
@@ -57,28 +109,180 @@ type photoIdentifier = {
57109
}),
58110
},
59111
};
112+
```
60113

61-
type photoIdentifiersPage = {
62-
.
63-
"edges": array(photoIdentifier),
64-
"page_info": {
65-
.
66-
"has_next_page": bool,
67-
"start_cursor": Js.Nullable.t(string),
68-
"end_cursor": Js.Nullable.t(string),
69-
},
114+
## Example
115+
116+
```reason
117+
open ReactNative;
118+
119+
let windowWidth = float_of_int(Dimensions.get(`window)##width);
120+
let windowHeight = float_of_int(Dimensions.get(`window)##height);
121+
122+
type state = {
123+
tag: string,
124+
path: option(string),
125+
photos: array(CameraRoll.photoIdentifier),
70126
};
71127
72-
[@bs.module "react-native"] [@bs.scope "CameraRoll"]
73-
external saveToCameraRoll: string => Js.Promise.t(string) = "";
128+
type action =
129+
| SetTag(string)
130+
| SetPath(string)
131+
| SetPhotos(array(CameraRoll.photoIdentifier));
132+
133+
let textStyle = Style.style(~textAlign=`center, ());
134+
135+
[@react.component]
136+
let make = () => {
137+
let (state, dispatch) =
138+
React.useReducer(
139+
(state, action) =>
140+
switch (action) {
141+
| SetTag(uri) => {...state, tag: uri}
142+
| SetPath(uri) => {...state, path: Some(uri)}
143+
| SetPhotos(a) => {...state, photos: a}
144+
},
145+
{
146+
tag: "https://images.unsplash.com/photo-1520453803296-c39eabe2dab4",
147+
path: None,
148+
photos: [||],
149+
},
150+
);
74151
75-
[@bs.module "react-native"] [@bs.scope "CameraRoll"]
76-
external saveToCameraRollWithType:
77-
(string, ~_type: [@bs.string] [ | `photo | `video]) => Js.Promise.t(string) =
78-
"saveToCameraRoll";
152+
let getPhotos = () => {
153+
Js.Promise.(
154+
CameraRoll.getPhotos(
155+
CameraRoll.getPhotosParams(
156+
~first=20,
157+
~assetType=`Photos,
158+
~groupTypes=`All,
159+
(),
160+
),
161+
)
162+
|> then_(r => resolve(dispatch(SetPhotos(r##edges))))
163+
|> catch(err => resolve(Js.Console.warn(err)))
164+
|> ignore
165+
);
166+
};
79167
80-
[@bs.module "react-native"] [@bs.scope "CameraRoll"]
81-
external getPhotos: getPhotosParams => Js.Promise.t(photoIdentifiersPage) =
82-
"";
168+
let savePhoto = uri => {
169+
Js.Promise.(
170+
CameraRoll.saveToCameraRoll(uri)
171+
|> then_(r => resolve(dispatch(SetPath(r))))
172+
|> catch(err => resolve(Js.Console.warn(err)))
173+
|> ignore
174+
);
175+
};
176+
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+
)}>
202+
{switch (state.path) {
203+
| None =>
204+
<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>
209+
</View>
210+
211+
| Some(p) =>
212+
<Image
213+
style={Style.style(
214+
~width=Style.pt(0.8 *. windowWidth),
215+
~height=Style.pt(0.56 *. windowWidth),
216+
(),
217+
)}
218+
source={Image.Source.fromUriSource(Image.uriSource(~uri=p, ()))}
219+
/>
220+
}}
221+
</View>
222+
<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+
/>
245+
<Button
246+
onPress={_ => savePhoto(state.tag)}
247+
title={js|Save a Photo|js}
248+
/>
249+
</View>
250+
</View>
251+
<View
252+
style={Style.style(
253+
~height=Style.pt(0.25 *. windowHeight),
254+
~justifyContent=`spaceBetween,
255+
(),
256+
)}>
257+
<View>
258+
<Text style=textStyle>
259+
"Saved photo will be in the Camera Roll"->React.string
260+
</Text>
261+
<Button onPress={_ => getPhotos()} title={js|Open CameraRoll|js} />
262+
</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>
284+
</View>
285+
</View>;
286+
};
83287
84-
```
288+
```

0 commit comments

Comments
 (0)