I am working on creating a dialer in React Native. For dialing a call I was using expo-linking but that only opened default phone dialer. After researching here I found about about react-native-immediate-phone-call and tried it but I get no results. I installed it via npm, ejected project from expo a ran the app on a virtual phone but after I press the dial button I get an alert (so I now the function is working), but no dialing begins whatsoever.
<Pressable onPress={this.pressButton}>
<FontAwesomeIcon icon={faPhone} color={colorName} size={35} />
</Pressable>
pressButton = () => {
this.setState({
callValue: (call = !call)
})
Alert.alert(number)
RNImmediatePhoneCall.immediatePhoneCall(number);
}
Could anyone please tell me why this is not working? Thank you.
check your phone permission for call :
In the AndroidManifest.xml file of your android studio project add:
<uses-permission android:name="android.permission.CALL_PHONE" />
Related
I have this simple file upload button that I got from antd ant design documentation:
<Upload>
<Button
icon={<UploadOutlined />}
className="upload-btn"
>
Upload a file
</Button>
</Upload>
Every time I upload a file I get this error in the console log:
I don't want it to make a post request when I upload the file, I have a submit button for that.
You can do it by returning false from beforeUpload prop, like this:
<Upload beforeUpload={()=> {
/* update state here */
return false; }}>
<Button icon={<UploadOutlined />}>Select File</Button>
</Upload>
obviously in this manner you have to define a state, and store files in the state to send it to server manually. Here is an example to implement this logic.
hey guys i am learning react js and I have an update form to update book info. I am using django rest api for endpoints. I have a working form where I can upload files and do all those stuffs but I am not able to show the image which is already there in the template, Here I have a book cover image, which is already there in the database, it should be showing in the front-end and when I change the image, the new one should show, how can I add that feature here, I tried <img src={formData.book_cover} and consoling out this is showing the url, but the image isn't getting displayed.
From the network tab,
The problem I think is
Request URL:http://localhost:3000/media/book/book_sample/pride_in_nat.png
request url since the image gets displayed if the url is localhost:8000 instead of localhost:3000 as it is where the django server backend runs. So, how can I change that?
This is the code.
import React from "react";
function BookInfoForm() {
const initialFormData = Object.freeze({
id: '',
book_cover: '',
book_name: '',
book_summary: '',
});
const [formData, updateFormData] = useState(initialFormData);
const [image, setImage] = useState(null);
const { register, handleSubmit, control, errors } = useForm();
useEffect(() => {
axiosInstance.get('api/books/info/update/').then((res) => {
updateFormData({
...formData,
['book_cover']: res.data.book_cover,
['book_name']: res.data.book_name,
['book_summary']: res.data.book_summary,
});
});
}, [updateFormData]);
const handleChange = (e) => {
if (e.target.name === 'image') {
setImage({
image: e.target.files,
});
// console.log(e.target.files);
}
updateFormData({
...formData,
// Trimming any whitespace
[e.target.name]: e.target.value
});
};
const onSubmit = (data) =>{
let formData = new FormData();
formData.append('user', user.id),
formData.append('book_cover', data.image[0]),
formData.append('book_name', data.book_name),
formData.append('book_summary', data.book_summary),
axiosInstance.put('api/books/info/update/', formData),
}
return (
<>
<form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}>
<Grid container spacing={2}>
<Grid item xs={6}>
{/* Show existing book cover and change when new one is uploaded */}
<img src={formData.store_logo} alt="" />
<label htmlFor="book-cover">
<input
accept="image/*"
className={classes.input}
id="book-cover"
onChange={handleChange}
name="image"
type="file"
ref={register}
/>
Book Cover
<IconButton color="primary" component="span">
<PhotoCamera />
</IconButton>
</label>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="book_name"
label="Book Name"
name="book_name"
autoComplete="book_name"
value={formData.book_name}
onChange={handleChange}
inputRef={register({maxLength: 30})}
rows={1}
/>
</Grid>
<Grid item xs={12}>
<TextField
variant="outlined"
required
fullWidth
id="book_summary"
label="Book Summary"
name="book_summary"
autoComplete="book_summary"
value={formData.book_summary}
onChange={handleChange}
inputRef={register({maxLength: 1000})}
multiline
rows={3}
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Update
</Button>
</form>
</>
)
}
You might want to take a look at one of my answers on Why React needs webpack-dev-server to run?
As your frontend is running at localhost:3000 and you are providing a relative path to the img tag, the browser is assuming that the image is at localhost:3000.
Whenever your backend host is different than the frontend host, you have to provide a complete URL to the resource i.e., origin(http://localhost:8000) + path to the resource(/book/book_sample/pride_in_nat.png)
As you are storing the path to the resource in your database, just append the origin while giving it to the img tag.
<img src={`http://localhost:8000/${formData.store_logo}`} />
Suggestion
A better approach is to use .env files and load them according to your development or production environment
<img src={`${process.env.IMAGE_STORE_ORIGIN}${formData.store_logo}`} />
And in your .env file or .env.development file, you can add the entry for where your images are stored
In your .env file:
IMAGE_STORE_ORIGIN=http://localhost:8000/
So, when you want to change your backend server origin, you can just change it in one location and it is used inside your entire app instead of changing it manually every time you want to use a new server address.
Take a look at dotenv and dotenv-expand
I hope this should clarify your "why" and "what".
I would advise this as being the best solution and I highly would recommend this even though I have not worked heavily with Django.
I know with Django you can store files in media files as configured in your settings.py, as good and convenient that is I guess but the best solution in my understanding for managing files is dealing with a 3rd party like cloudinary(Very common when working with Node using 3rd party software's to manage files)
So the flow behind:
Make an account on cloudinary(Do not worry it's completely free but can upgrade)
When you want to save a file to DB you first interact with cloudinary with Django.
Once Django is done cloudinary Api will bring back a url of your image.
Then what you only have to do now is now save that link given in your database
Now with your Django Model
In the place where you had image as a "FileField" now you can safely convert to "CharField" or whatever that means text/string in django kind of forgot
Then now in your React app that should work
Cloudinary SDK docs for Django
https://cloudinary.com/documentation/django_integration
You can also look up some example on YouTube for clarity if docs are not clear
https://youtu.be/1T6G7Znrbfg
I am trying to get access to HTMLElementInput.files.path to send to my backend for cloudinary to process. The problem I am running into is there is now path key present on the object.
I've been reading through the MDN Input page, and I'm pretty sure I'm not doing anything wrong with the markup. The below is the code I have for intercepting the data on the input:
class App extends Component {
capture(e) {
e.preventDefault();
const image = document.querySelector('input').files[0];
console.log(image);
// image.path === undefined
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<form onSubmit={e => this.capture(e)}>
<div>
<label htmlFor="photo_image">Upload an image</label>
<input id="photo_image" type="file" accept=".jpg, .jpeg, .png" />
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}
}
export default App;
I am stumped. If someone sees where I'm going wrong or if there is a gotcha with react that I don't know about I am all ears!
Update
I should have left this information before, my apologies. The project is bootstrapped with create-react-app. I get this problem in development as well as when serving the build in production.
create-react-app#1.3.3
react-scripts#1.0.10
node#8.2.1
yarn#0.27.5
macOS#10.12.6
chrome#59.0.3071.115
You are missing the brackets around event while catching the event onSubmit. Change it to below code and try:
<form onSubmit= {(e) => this.capture(e)}>
I was still in an electron mindset and did not ever think that MDN was telling me the truth that the browser does not give me access to the hard path of a file on the system for security reasons. This code box that was sent to me in Reactiflux shows a method for obtaining the end goal I was looking for, many thanks to #BTM for this:
https://codesandbox.io/s/lNN5pK6M
I've been trying to add simple email / password signup/login for Firebase to the Polymer Starter Kit app. It comes stock with a Google auth sign in via a single button but there doesn't seem to be any instructions on how to set-up email/password register/login instead.
Here is the specific part of the code from the project's todo-auth.html file I've been struggling with:
<firebase-auth id="authenticate"
user="{{user}}"
location="{{location}}"
ref="{{refauth}}"
provider="">
</firebase-auth>
<paper-dialog modal
opened="[[!user]]"
entry-animation="scale-up-animation"
exit-animation="fade-out-animation">
<h2>Please sign in</h2>
<div>
<!-- Inputs I added to accept user credentials -->
<paper-input id="loginEmailInput"
no-label-float
label="Email"
on-keydown="">
</paper-input>
<paper-input id="loginPasswordInput"
no-label-float
label="Password"
on-keydown="">
</paper-input>
<paper-button on-tap="logIn">Login</paper-button>
<!-- Original Google sign-in code -->
<!-- <div class="google-sign-in"
tabindex="0"
on-tap="signIn">
<span class="google-sign-in-icon"></span>
<span class="google-sign-in-label">Google</span>
</div> -->
</div>
</paper-dialog>
I removed google from the provider property of the <firebase-auth> element and added a couple of input fields but don't really know where to go from there.
Here is the Polymer script part of todo-auth.html
<script>
Polymer({
is: 'todo-auth',
properties: {
user: {
notify: true
}
},
logIn: function() {
this.$.authenticate.login();
},
signOut: function() {
this.$.authenticate.logout();
this.user = null;
}
});
</script>
I've tried to find examples or guide tutorials on how to implement this but everything I've found has used the google based auth as login. Likewise, all other questions I've found here on SO have focused on google login.
I'd be grateful for any directions or pointers or tutorials on how to set it up. Thanks all in advance!
UPDATE
I managed to implement a new page with a form using the demo from the Google Web Components github repo.
I have a my-firebase.html file that imports everything I can think of to make it work. Imports look like this:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/polymerfire/firebase-auth.html">
<link rel="import" href="../../bower_components/polymerfire/firebase-app.html">
<link rel="import" href="../../bower_components/polymerfire/polymerfire.html">
I have also added the following for firebase-app and firebase-auth:
<firebase-app auth-domain="my-polymer-app.firebaseapp.com"
database-url="https://my-polymer-app.firebaseio.com/"
api-key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
</firebase-app>
<firebase-auth id="firebaseLogin" user="{{user}}" status-known="{{statusKnown}}" location="my-polymer-app.firebaseapp.com" provider="{{provider}}" on-error="errorHandler" on-user-created="userSuccessHandler" on-password-changed="us erSuccessHandler" on-password-reset="userSuccessHandler" on-user-removed="userSuccessHandler"></firebase-auth>
I am now getting the following error when I try to login(I have already set up a user in my Firebase App to test):
my-firebase.html:122 Uncaught TypeError: this.$.firebaseLogin.login is not a function
Which refers to this part of the code take from the Google Web Components repo.
login: function() {
var params;
try {
params = JSON.parse(this.params);
} catch (e) {
params = null;
}
if (this.provider == 'password') {
params = params || {};
params.email = this.email;
params.password = this.password;
}
this.$.firebaseLogin.login(params);
}
There are also red boxes around every instance of firebaseLogin on the page. No other errors are showing up so not sure what this means exactly. Again, I'd be grateful if anyone could point out what I'm missing here.
Use signInWithEmailAndPassword function instead of login function,
this.$.firebaseLogin.signInWithEmailAndPassword(username, password);
I'm developing a Firefox Add-On for a client.
When an user is uninstalling the Add-On, I need to show the user a prompt, which contains three checkboxes. These checkboxes will serve as an option to the user for restoring his/her previous browser settings.
I've successfully created a prompt on uninstall/disable, using the confirmCheck method of the nsIPromptService interface :
let value = {value: true};
let confirm = promptService.confirmCheck(
null,
"Uninstall My Extension",
"You are uninstalling My Extension. You can chose these options to restore your settings to previous state.",
"Remove My Extension as the default search engine, homepage, new tab landing page, and restore to my previous settings",
value
);
The only problem is, it only contains a single checkbox, and I need 3 different ones, for "Seach Engine", "Homepage", and "New Tab Url" each.
I'm using chrome code through the Add-On SDK, and am not familiar with XUL.
How should I go about this? Do I really need to learn XUL for creating a simple prompt?
Alright, answering my own question, as I figured it out. The easiest way I found (comparatively) was to use XUL :
This is my prompt.xul :
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<dialog id="myDialog"
title="My Extension"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="init();"
buttons="accept"
buttonlabelaccept="OK"
ondialogaccept="return doContinue();">
<script type="application/x-javascript">
function init() {
}
function doContinue() {
window.arguments[0].CHECK_1 = document.querySelector('#check_1').checked;
window.arguments[0].CHECK_2 = document.querySelector('#check_2').checked;
window.arguments[0].CHECK_3 = document.querySelector('#check_3').checked;
return true;
}
</script>
<html:div style="width: 410px;">
<html:div>
<html:p>You have selected to uninstall My Extension</html:p>
</html:div>
<html:blockquote id="checkboxes_container">
<html:div id="remove_search_container">
<html:input type="checkbox" id="check_1" value="true" checked="true"/>
<html:label for="check_1">Label 1</html:label>
</html:div>
<html:div id="remove_homepage_container">
<html:input type="checkbox" id="check_2" value="true" checked="true"/>
<html:label for="check_2">Label 2</html:label>
</html:div>
<html:div id="remove_newtab_container">
<html:input type="checkbox" id="check_3" value="true" checked="true"/>
<html:label for="check_3">Label 3</html:label>
</html:div>
</html:blockquote>
</html:div>
</dialog>
After adding the chrome package to chrome.manifest, this file should be accessible by :
chrome://YOUR_PACKAGE_NAME/content/PATH_TO_dialog.xul
I'm using chrome code to load the prompt, in main.js :
let Window = Cc["#mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);
let arg = {
CHECK_1: false,
CHECK_2: false,
CHECK_3: false
};
let window = Window.activeWindow.openDialog("chrome://YOUR_PACKAGE_NAME/content/PATH_TO_dialog.xul", "myWindow", "chrome,modal,centerscreen", arg);
After the user has closed the prompt, the arg object will contain the checkbox values of the prompt. For example, if an user ticks all the checkboxes, the arg object will be :
{
CHECK_1 : true,
CHECK_2 : true,
CHECK_3 : true
}
And that did it for me. Have a nice day!