React-native-image-viewer: 'Save image to album' not working

Created on 8 Sep 2019  路  3Comments  路  Source: ascoders/react-native-image-viewer

Hi, I'm testing my app on an Android device, and the functionality of saving the image to the phone's album is not working (after long-pressing the image). Is anyone else running into the same issue? In any case, is there a way of disabling the menu after long-pressing? I'm using Expo to develop the app

Most helpful comment

This works just fine on iOS and Android.

The onSave prop won't automatically save the image. You'll have to import CameraRoll from react-native-community and save the image that way. Read over the following to import it correctly: https://github.com/react-native-community/react-native-cameraroll

Here's an example of how i'm using it in my app:

import React from "react";
import { ActivityIndicator, Modal, Alert } from "react-native";
import CameraRoll from "@react-native-community/cameraroll";
import ImageViewer from "react-native-image-zoom-viewer";

export default class Example extends React.Component {
    state = {
        image_index: 0,
        images: [],
        show_modal: false
    };

    constructor(props) {
        super(props);

        this._getImages();
    }

    _getImages = () => {
        // Make some external request to get images if needed... This is just an example
        let images = [
            {
                uri: "some uri",
                props: {
                    id: 1
                },
            },
            {
                uri: "some uri2",
                props: {
                    id: 2
                },
            }
        ];

        this.setState({ images });
    };

    _saveImage = uri => {
        let promise = CameraRoll.saveToCameraRoll(uri);

        promise
            .then(function(result) {
                Alert.alert(
                    "Success",
                    "Image Saved to Photo Gallery",
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            })
            .catch(function(error) {
                Alert.alert(
                    "Error Saving Image",
                    error,
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            });
    };

    render() {
        return (
            <Modal visible={this.state.show_modal} transparent={true}>
                <ImageViewer
                    imageUrls={this.state.images}
                    index={this.state.image_index}
                    enableSwipeDown
                    enablePreload
                    loadingRender={() => (
                        <ActivityIndicator
                            style={{
                                justifyContent: "center",
                                alignSelf: "center"
                            }}
                            size="large"
                            color="#FFFFFF"
                        />
                    )}
                    onSave={uri => this._saveImage(uri)}
                    onSwipeDown={() => this.setState({ show_modal: false })}
                    menuContext={{
                        saveToLocal: "Save Image",
                        cancel: "Cancel"
                    }}
                />
            </Modal>
        );
    }
}

All 3 comments

I am experiencing the same on IOS

This works just fine on iOS and Android.

The onSave prop won't automatically save the image. You'll have to import CameraRoll from react-native-community and save the image that way. Read over the following to import it correctly: https://github.com/react-native-community/react-native-cameraroll

Here's an example of how i'm using it in my app:

import React from "react";
import { ActivityIndicator, Modal, Alert } from "react-native";
import CameraRoll from "@react-native-community/cameraroll";
import ImageViewer from "react-native-image-zoom-viewer";

export default class Example extends React.Component {
    state = {
        image_index: 0,
        images: [],
        show_modal: false
    };

    constructor(props) {
        super(props);

        this._getImages();
    }

    _getImages = () => {
        // Make some external request to get images if needed... This is just an example
        let images = [
            {
                uri: "some uri",
                props: {
                    id: 1
                },
            },
            {
                uri: "some uri2",
                props: {
                    id: 2
                },
            }
        ];

        this.setState({ images });
    };

    _saveImage = uri => {
        let promise = CameraRoll.saveToCameraRoll(uri);

        promise
            .then(function(result) {
                Alert.alert(
                    "Success",
                    "Image Saved to Photo Gallery",
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            })
            .catch(function(error) {
                Alert.alert(
                    "Error Saving Image",
                    error,
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            });
    };

    render() {
        return (
            <Modal visible={this.state.show_modal} transparent={true}>
                <ImageViewer
                    imageUrls={this.state.images}
                    index={this.state.image_index}
                    enableSwipeDown
                    enablePreload
                    loadingRender={() => (
                        <ActivityIndicator
                            style={{
                                justifyContent: "center",
                                alignSelf: "center"
                            }}
                            size="large"
                            color="#FFFFFF"
                        />
                    )}
                    onSave={uri => this._saveImage(uri)}
                    onSwipeDown={() => this.setState({ show_modal: false })}
                    menuContext={{
                        saveToLocal: "Save Image",
                        cancel: "Cancel"
                    }}
                />
            </Modal>
        );
    }
}

```
const saveImage = async uri => {
RNFetchBlob.config({
fileCache: true,
appendExt: 'png',
})
.fetch('GET', uri)
.then(res => {
CameraRoll.saveToCameraRoll(res.data, 'photo')
.then(res =>
Alert.alert(
'Success',
'Image Saved to Photo Gallery',
[
{
text: 'OK',
},
],
{cancelable: false},
),
)
.catch(err =>
Alert.alert(
'Error Saving Image',
error,
[
{
text: 'OK',
},
],
{cancelable: false},
),
);
})
.catch(error =>
Alert.alert(
'Error Saving Image',
error,
[
{
text: 'OK',
},
],
{cancelable: false},
),
);
};

ref={n => {
imageViewer = n;
}}
enablePreload={true}
useNativeDriver={true}
onSave={uri => saveImage(uri)}
imageUrls={images}
/>

```

onSave will let you write custom code for image store operation. For the image store operation you can use rn-fetch-blob like what I did.

Was this page helpful?
0 / 5 - 0 ratings