react native I want to designate one image as the default - react-native

I wrote the code to upload an image, but when I click remove image, a blue screen appears as a default. I want to designate this screen as one image.
import 'react-native-gesture-handler'
import * as React from 'react';
import{
StyleSheet,
View,
Text,
Image,
TouchableOpacity,
ToastAndroid,
Alert,
} from 'react-native';
import { Avatar } from 'react-native-paper';
import { launchImageLibrary } from 'react-native-image-picker';
import styled from 'styled-components';
const Container = styled.SafeAreaView`
flex : 1;
`;
export default function Profile(){
const [pic, Setpic] = React.useState('');
const setToastMsg = msg => {
ToastAndroid.showWithGravity(msg, ToastAndroid.SHORT, ToastAndroid.CENTER)
};
const uploadImage = () => {
let options = {
mediaType : 'photo',
quality : 1,
includeBase64 : true,
};
launchImageLibrary(options, response => {
if(response.didCancel){
setToastMsg('Cancelled image selection');
}
else if((response.errorCode == 'permission')){
setToastMsg('permision not satisfied');
}
else if((response.errorCode == 'others')){
setToastMsg(response.errorMessage);
}
else if(response.assets[0].fileSize > 2097152){
Alert.alert(
'Maximum image size exceeded',
'Please choose image under 2MB'
[{text: 'OK'}],
);
}
else{
Setpic(response.assets[0].base64);
}
});
}
const removeImage = () => {
Setpic('');
setToastMsg('Image removed');
}
return(
<Container>
<View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
<View>
<TouchableOpacity activeOpacity={0.5} onPress={ ()=> uploadImage() }>
<Text>
Upload Image
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.5} onPress={ ()=> removeImage() }>
<Text>
Remove Image
</Text>
</TouchableOpacity>
</View>
</Container>
);
}
Can I change the code here?
const removeImage = () => {
Setpic('');
setToastMsg('Image removed');
}
or here?
<View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
I'm curious where you set the default image.
If you can't change the default image, please help me to change the color.
This code is based on Android

you could try a condition if pic is empty or not.
If it is empty will be rendered. If not You Avatar will be shown.
{ pic === "" ? (
<View>
<Text>Screen if pic is empty</Text>
<View>
):
( <View>
<Avatar.Image
size= {150}
source={{ uri : 'data:image/png;base64,' + pic}}
/>
</View>
)

Related

how to print the contents of a viewshot without display it in react native?

I am using the library react-native-view-shot and I am trying to print the contents of a viewshot without display it.
If I don't hide the contents I can print without a problem, but I need to hide the contents.
If I hide the viewshot and try to print the contents like:
import { StatusBar } from 'expo-status-bar';
import React, {Component} from 'react';
import {Button, ScrollView, StyleSheet, Text, TextInput, View, alert, Alert} from 'react-native';
import {discoverPrinters, pingPrinter, printImage, registerBrotherListener} from 'react-native-brother-printers';
import ViewShot from "react-native-view-shot";
export default class App extends Component {
state = {
displayContents: false
};
render() {
const {displayContents} = this.state;
return (
<ScrollView style={{flex: 1}}>
{displayContents && (
<ViewShot ref={(e) => {
this.viewShot = e;
}} options={{format: "jpg", quality: 0.9}}>
{ <Text style={{fontSize: 24}}>
print something
</Text> }
<Text style={{fontSize: 24}}>
printer test
</Text>
</ViewShot>
)}
<View style={styles.container}>
<Text>
Test Connection
</Text>
<Button title="Print from Manual" onPress={() => {
this.viewShot.capture().then(uri => {
// this.viewShot.capture().then(() => {
// console.log("do something with ", uri);
printImage(
{
"modelName": "Brother PT-P950NW",
"ipAddress": " 192.168.118.1",
},uri, {autoCut: false}).then(() => {
console.log("Discover Manual Successful");
}).catch((err) => {
console.log(err);
console.log("Discover Manual failed")
});
});
}}/>
</View>
</ScrollView>
);
}
}
I get this error message:
TypeError: undefined is not an object (evaluating '_this3.viewShot.capture')
It's possible do that ?

how to transform image from gallery or camera into base64?

I have a function that takes the image from the gallery or camera and sends it to an area where the user can view it.
import React, {useState} from 'react';
import {View, TouchableOpacity, Text, StyleSheet, Image} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default function Upload() {
const [avatar, setAvatar] = useState();
function imagePickerCallback(data) {
if (data.didCancel) {
return;
}
if (data.error) {
return;
}
if (data.customButton) {
return;
}
if (!data.assets[0].uri) {
return;
}
setAvatar(data.assets[0]);
}
return (
<View style={styles.container}>
<Image
source={{
uri: avatar
? avatar.uri
: 'https://mltmpgeox6sf.i.optimole.com/w:761/h:720/q:auto/https://redbanksmilesnj.com/wp-content/uploads/2015/11/man-avatar-placeholder.png',
}}
style={styles.avatar}
/>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchCamera(imagePickerCallback)
}>
<Text style={styles.buttonText}>camera</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchImageLibrary(imagePickerCallback)
}>
<Text style={styles.buttonText}>galery</Text>
</TouchableOpacity>
</View>
);
}
I'm filling the image source with the URI. I would like to know how to take this image and make it base64 to send it to firebase storage.
If I need to install a library, tell me which one to install.
If you read the library definition for options which is the first parameter. You can tell the library to return the base64 string. options: { includeBase64: true }
https://github.com/react-native-image-picker/react-native-image-picker#options
And that will return the below object with base64
https://github.com/react-native-image-picker/react-native-image-picker#asset-object
See below example:
import React, {useState} from 'react';
import {View, TouchableOpacity, Text, StyleSheet, Image} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default function Upload() {
const [avatar, setAvatar] = useState();
function imagePickerCallback(data) {
if (data.didCancel) {
return;
}
if (data.error) {
return;
}
if (data.customButton) {
return;
}
if (!data.assets[0].uri) {
return;
}
if((data.assets?.length ?? 0) > 0 && data.assets[0].base64){
//Here is my base64 string of assets[0]
}
setAvatar(data.assets[0]);
}
const options = {
includeBase64: true
}
return (
<View style={styles.container}>
<Image
source={{
uri: avatar
? avatar.uri
: 'https://mltmpgeox6sf.i.optimole.com/w:761/h:720/q:auto/https://redbanksmilesnj.com/wp-content/uploads/2015/11/man-avatar-placeholder.png',
}}
style={styles.avatar}
/>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchCamera(options, imagePickerCallback)
}>
<Text style={styles.buttonText}>camera</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() =>
ImagePicker.launchImageLibrary(options, imagePickerCallback)
}>
<Text style={styles.buttonText}>galery</Text>
</TouchableOpacity>
</View>
);
}

React Native Share shows 'Can't send empty messages' error by sharing viewshot

I'm trying to share a generated QR code as a viewshot on whatsapp. I've utilized react-native-view-shot and react-native-qrcode-svg for this matter as following:
import React, { useState, useRef } from 'react';
import { StyleSheet, Text, ScrollView, TextInput, TouchableOpacity, Alert, View, Share } from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import ViewShot from 'react-native-view-shot';
const App = () => {
const viewShotRef= useRef();
async function captureViewshot(){
const imgURI = await viewShotRef.current.capture();
Share.share({title: 'image', url: imgURI});
}
const [qr, setQr] = useState(false);
const [link, setLink] = useState('');
const createQr = () => {
if (link) {
setQr(true);
} else {
Alert.alert(
'Error',
"Please insert required field"
);
}
};
return (
<ScrollView style={styles.container}>
<Text style={styles.headerTitle}>Create QR Code</Text>
<View style={{flexDirection:'row'}}>
<TextInput
style={styles.input}
placeholder="Insert link here.."
onChangeText={(link) => setLink(link)}
/>
</View>
<TouchableOpacity style={styles.button} onPress={() => createQr()}>
<Text style={styles.buttonTitle}>Create</Text>
</TouchableOpacity>
{qr && (
<ViewShot ref={viewShotRef} style={styles.qrcontainer} options={{format:'jpg', quality: 0.8, result:'base64'}}>
<View><QRCode value={link} size={250} />
<Text
style={{
alignSelf: 'center',
fontSize: 15
}}>
{link}
</Text></View></ViewShot>
)}
{qr && (
<View>
<TouchableOpacity style={styles.button} onPress={captureViewshot}>
<Text style={styles.buttonTitle}>Share QR Code</Text>
</TouchableOpacity>
</View>
)}
</ScrollView>
);
}; export default App;
However, when I click on share button, the application keep sending no messages error. How do I modify the code so that my viewshot(the qr code) can be shared across other platform?
Thanks for your guidance.
You can use rn-qr-generator to generate a QR image (example). And then pass base64 of the generated QR image as url param
RNQRGenerator.generate({
...
base64: true, // set true to get base64 representation of the image
})
.then(response => {
const { base64 } = response;
const shareOptions = {
type: 'image/jpg',
title: 'image',
message: 'message'
url: base64
};
Share.open(shareOptions)
.then(res => console.log(res))
.catch(err => console.error(err));
})

How React Native to control Play/Pause Video in WebView

I am trying to play and pause video in WebView by React Native.
But when this.state.shouldPlay becomes true, the below injectedJavaScript does not work.
injectedJavaScript=
{`document.getElementsByTagName("video")[0].play();`}
Please advise how to control Video in WebView from React Native.
react-native-video cannot be used because of performance issue.
import * as React from 'react';
import { Component, useState, useEffect } from 'react';
import { Text, View, StyleSheet, Image, TouchableOpacity} from 'react-native';
import {WebView} from 'react-native-webview';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
shouldPlay: false, // not play at default
}
}
_handlePlayAndPause = () => {
if (this.state.shouldPlay == false) {
this.setState({shouldPlay: true });
} else {
this.setState({shouldPlay: false });
};
render() {
const {shouldPlay } = this.state;
return (
<View style={styles.container}>
{ shouldPlay ?
<View>
<WebView
source={{ uri: www.url.com/sample.mp4 }}
javaScriptEnabled = {true}
injectedJavaScript=
{`document.getElementsByTagName("video")[0].play();`}
/>
</View>
:
<View>
<WebView
source={{ uri: www.url.com/sample.mp4 }}
javaScriptEnabled = {true}
injectedJavaScript=
{`document.getElementsByTagName("video")[0].pause();`}
/>
</View>
}
{ shouldPlay ?
<View>
<TouchableOpacity onPress={ this._handlePlayAndPause } >
<Ionicons name="ios-pause"/>
</TouchableOpacity>
</View>
:
<View>
<TouchableOpacity onPress={ this._handlePlayAndPause } >
<Ionicons name="ios-play-circle"/>
</TouchableOpacity>
</View>
}
</View>
)
}
}
Thank you.

I can't figure out why I keep seeing "ReferenceError: Can't find variable: val"

I'm trying to get the images inside my getImageForLogo.js to load through a loop.
That file looks like so:
const images = {
logo1: require('../assets/logo1.jpeg'),
logo2: require('../assets/logo2.png'),
'logo with space': require('../assets/logo-with-space.jpeg'),
};
export default logos => images[logos];
My App.js:
import React from 'react';
import {
StyleSheet,
View,
Image,
ScrollView,
Text
} from 'react-native';
import getImageForLogo from './utils/getImageForLogo';
import Avatar from './components/Avatar';
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
logos: 'logo1'
};
}
render () {
const {
logos
} = this.state;
const form = { 'Logo1': 'assets/logo.jpg', 'Logo2': 'assets/logo2.jpg', 'Logo3': 'assets/logo3.jpg' };
return (
<View style={styles.appContainer}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Title</Text>
</View>
<ScrollView style={styles.timerlist}>
Object.values(form).map((key, val) => (
<Avatar
initials="KC"
size={75}
key={val}
source={key}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
));
</ScrollView>
</View>
);
}
}
I created the const form just to try and see if the loop works. I'm trying to cycle by using:
Object.values(form).map((key, val) => (
<Avatar
initials="KC"
size={75}
key={val}
source={key}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
));
however, when I run this, the app crashes and says ReferenceError: Can't find variable: val. I can't figure out why this happens because if I run this code on the Chrome terminal, it works.
EDIT:
Here's Avatar.js:
import {
ColorPropType,
StyleSheet,
Text,
View,
Image,
TouchableOpacity
} from 'react-native';
import PropTypes from 'prop-types';
import React from 'react';
import getImageForLogo from '../utils/getImageForLogo';
export default function Avatar({
size,
backgroundColor,
initials,
source,
onPressLinkImage,
}) {
const style = {
width: size,
height: size,
borderRadius: size / 2,
backgroundColor,
};
const image = getImageForLogo(source)
return (
<View style={[styles.container, style]}>
<TouchableOpacity onPress={onPressLinkImage}>
<Image source={image} style={styles.image} />
</TouchableOpacity>
</View>
);
}
Avatar.propTypes = {
initials: PropTypes.string.isRequired,
size: PropTypes.number.isRequired,
source: PropTypes.string.isRequired,
backgroundColor: ColorPropType.isRequired,
onPressLinkImage: PropTypes.func.isRequired,
};
Your code in the App.js appears to be missing some { } around your Object.values.
So instead of putting inside your ScrollView
Object.values(form).map((key, val) => (
<Avatar
initials="KC"
size={75}
key={val}
source={key}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
)
);
you should put
{Object.values(form).map((key, val) => (
<Avatar
initials="KC"
size={75}
key={val}
source={key}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
)
)}
notice that it is contained inside the { }.
Here is it inside your App.js
import React from 'react';
import {
StyleSheet,
View,
Image,
ScrollView,
Text
} from 'react-native';
import getImageForLogo from './utils/getImageForLogo';
import Avatar from './components/Avatar';
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
logos: 'logo1'
};
}
render () {
const {
logos
} = this.state;
const form = { 'Logo1': 'assets/logo.jpg', 'Logo2': 'assets/logo2.jpg', 'Logo3': 'assets/logo3.jpg' };
return (
<View style={styles.appContainer}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Title</Text>
</View>
<ScrollView style={styles.timerlist}>
{Object.values(form).map((key, val) => (
<Avatar
initials="KC"
size={75}
key={val}
source={key}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
))}
</ScrollView>
</View>
);
}
}
Also note your Object.values(form).map((key, val) will give the following keys and values
key | val
assets/logo.jpg | 0
assets/logo1.jpg | 1
assets/logo2.jpg | 2
For readability of your code I would change your code to the following:
{Object.values(form).map((source, key) => (
<Avatar
initials="KC"
size={75}
key={key}
source={source}
backgroundColor={'blue'}
onPressLinkImage={() => {
console.log('Pressed!');
}}
/>
)
)}