I want to use react-native-camera in expo but I get this error.-> Possible Unhandled Promise Rejection (id: 0) Here is code.
import {StatusBar} from 'expo-status-bar';
import React from "react";
import { StyleSheet, Modal, View, Pressable, Text, SafeAreaView, Button, Image,
PushNotificationIOS } from "react-native";
import { useEffect, useRef, useState } from 'react';
import Icon from "react-native-vector-icons/MaterialIcons";
import {shareAsync} from 'expo-sharing';
import * as MediaLibrary from 'expo-media-library';
import { Camera } from 'expo-camera';
export default function App() {
let cameraRef = useRef();
const [hasCameraPermission, setHasCameraPermission] = useState();
const [hasMediaLibraryPermission, setHasMediaLibraryPermission] = useState();
const [photo, setPhoto] = useState();
useEffect(()=>{
(async ()=>{
const cameraPermission = await Camera.requestCameraPermissionsAsync();
constMediaLibraryPermission = await MediaLibrary.requestMediaLibraryPermissionsAsync();
setHasCameraPermission(cameraPermission.status === "granted");
setHasMediaLibraryPermission(MediaLibraryPermission.status === "granted");
})();
},[]);
if (hasCameraPermission === undefined){
return <Text> Requesting permissions...</Text>
} else if (!hasCameraPermission){
return <Text> Permission for camera not granted. Please change this in settinr.</Text>
}
let takePic = async () => {
let options = {
quality :1,
base64: true,
exif : false
};
let newPhoto = await cameraRef.current.takePictureAsync(options);
setPhoto(newPhoto);
};
if(photo){
let sharePic = () => {
shareAsync(photo.uri).then(() => {
setPhoto(undefined);
});
};
let savePhoto = () => {
MediaLibrary.saveToLibraryAsync(photo.uri).then(() =>{
setPhoto(undefined);
});
};
return (
<SafeAreaView style = {styles.container}>
<Image style = {styles.preview} source = {{uri: "data:image/jpg;base64," +
photo.base64}}/>
<Button title = "share" onPress = {sharePic}/>
{hasMediaLibraryPermission ? <Button title = "save" onPress = {savePhoto}/>:undefined}
<Button title = "Discard" onPress = {()=> setPhoto(undefined)}/>
</SafeAreaView>
)
}
return (
<Camera style={styles.container} ref = {cameraRef}>
<View style = {styles.buttonContainer}>
<Button title = "Takc Pic" onPress = {takePic} />
</View>
<StatusBar style="auto" />
</Camera>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
buttonContainer:{
backgroundColor :'#fff',
alignSelf:'flex-end'
},
preview:{
alignSelf:'stretch',
flex:1
}
});
So I try 'catch-throw', but I didn't solve this problem. Because 'try' is necessary.
I checked other questions and answers, but I didn't find a solution.
How can I solve this error?
I want to submit a form when I stop type, I'm using react hook form and call the handleSubmit in a function and it doesn't work, please help me, this is my code, I'm doing a map of this code, I've tried with ref but it doesn't work. This is my component.
import React, {useRef} from 'react';
import {View, Text, TextInput, TouchableOpacity} from 'react-native';
import tailwind from 'tailwind-rn';
import {useDebounce} from 'use-debounce';
import {useForm, Controller} from 'react-hook-form';
import {MAIN_COLOR, GRAY} from '../../constants/theme';
function RegisterFormHook({data, onSubmit, control, errors}) {
const [underlineColor, setUnderlineColor] = React.useState(GRAY);
const [field, setField] = React.useState('');
const [value] = useDebounce(field, 1000);
const inputElement = useRef();
const {handleSubmit} = useForm();
React.useEffect(() => {
if (value.length !== 0) {
handleSubmit(onSubmit({[data.name]: value}));
}
console.log(errors);
}, [value]);
const onFocus = () => {
setUnderlineColor(MAIN_COLOR);
};
const onBlur = () => {
setUnderlineColor(GRAY);
};
return (
<View style={tailwind('px-8')}>
<Controller
control={control}
name={data.name}
rules={data.rules}
render={({field: {onChange, value}}) => (
<TextInput
placeholder={data.placeholder}
ref={inputElement}
style={[
tailwind('text-black p-0 text-xl pb-1 flex-row'),
{
borderBottomWidth: 1,
borderBottomColor: underlineColor,
},
]}
onChangeText={value => {
onChange(value);
setField(value);
}}
onBlur={onBlur}
value={value}
onFocus={() => onFocus()}
/>
)}
/>
<Text>{errors[data.name]?.message}</Text>
</View>
);
}
export default RegisterFormHook;
I want to submit in the useEffect but it just works when I press a button.
Here is a sample how you could implement scheduled action after input has been completed:
import * as React from 'react';
import { TextInput, View, StyleSheet, Alert } from 'react-native';
import Constants from 'expo-constants';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
let timer = React.useRef();
const [text, setText] = React.useState('');
React.useEffect(() => {
if (text) {
timer = setTimeout(() => {
Alert.alert('TEXT : ' + text);
}, 3000);
}
}, [text]);
return (
<View style={styles.container}>
<Card>
<TextInput
placeholder={'Enter the tetxt'}
onChange={(e) => {
clearTimeout(timer);
setText(e.nativeEvent.text);
}}
/>
</Card>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});
How can I display start day of week as Wednesday in material-ui-pickers?
Currently, it is showing as Sunday as start day of week. How can we override that?
Thanks.
moment.js
moment.locale('en', { week: { dow: 3 } }) // 0-6 (Sunday-Saturday)
dow: day of week (https://github.com/moment/momentjs.com/issues/279)
Full example:
import React, { ReactElement, useEffect, useState } from 'react'
import { DatePicker, MuiPickersUtilsProvider } from '#material-ui/pickers'
import MomentUtils from '#date-io/moment'
import moment from 'moment'
import 'moment/locale/de'
export const MomentPicker = (): ReactElement => {
const [selectedDate, handleDateChange] = useState(new Date())
useEffect(() => {
moment.locale('de', { week: { dow: 3 } })
}, [])
return (
<MuiPickersUtilsProvider utils={MomentUtils}>
<DatePicker value={selectedDate} onChange={handleDateChange} />
</MuiPickersUtilsProvider>
)
}
https://material-ui-pickers.dev/localization/moment
date-fns
locale.options.weekStartsOn = 3 // 0-6 (Sunday-Saturday)
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={locale}>
Full example:
import React, { ReactElement, useState } from 'react'
import { DatePicker, MuiPickersUtilsProvider } from '#material-ui/pickers'
import DateFnsUtils from '#date-io/date-fns'
import locale from 'date-fns/locale/en-US'
if (locale && locale.options) {
locale.options.weekStartsOn = 3
}
export const DateFNSPicker = (): ReactElement => {
const [selectedDate, handleDateChange] = useState(new Date())
return (
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={locale}>
<DatePicker value={selectedDate} onChange={handleDateChange} />
</MuiPickersUtilsProvider>
)
}
https://material-ui-pickers.dev/localization/date-fns
I had to set the locale of LocalizationProvider to British.
import enLocale from 'date-fns/locale/en-GB';
...
return (
<LocalizationProvider locale={enLocale} ..>
<CalendarPicker ... />
</LocalizationProvider>
);
I am trying to implement KeyboardDatepicker inside ag grid's cell editor. When I select a date from the datepicker popup, the month value is shown incorrectly. The date I have selected is 30-04-2020 and the date it is showing is 30-30-2020. I tried using formatDate attribute to format the date as well. I am passing the selected value in proper format but the date is showing incorrectly. I am using date-io/moment version 1.3.13 and date-io/date-fns version 0.0.2. Anybody faced this issue before? I am sure this is a trivial issue and I am missing something. Any pointers would be much appreciated. Thanks in advance. Cheers!
Update:
Datepicker_component_grid.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { KeyboardDatePicker, MuiPickersUtilsProvider } from '#material-ui/pickers';
import DateFnsUtils from '#date-io/date-fns'
import moment from 'moment'
import format from 'date-fns/format'
import Grid from '#material-ui/core/Grid'
import { SampleDatePickerWithUtils } from '../Sample_datepicker_with_utils';
export class DateEditor extends Component {
constructor(props) {
super(props)
this.onDateChange = this.onDateChange.bind(this)
this.state = {
value: null
}
}
componentDidMount() {
}
componentWillUnmount() {
}
componentDidUpdate() {
this.focus()
}
focus() {
window.setTimeout(() => {
let dateContainer = ReactDOM.findDOMNode(this.refs.dateContainer)
if (dateContainer) {
dateContainer.focus()
}
})
}
getValue() {
return this.state.value
}
isPopup() {
return false
}
onDateChange(date) {
this.setState({
value: date
},
() => this.props.api.stopEditing()
)
}
render() {
let storeValue = this.props.value
return (
<span
ref='dateContainer'
tabIndex={1}>
<SampleDatePickerWithUtils labelName={' '} schemaLocation='rowDate' isDisabled={false}
displayFormat='yyyy-mm-dd'
disableFuture={false}
onDateChange={this.onDateChange}
disablePast={false}
storeVal={storeValue}
gridSize={{ sm: 2, md: 1, lg: 1 }}></SampleDatePickerWithUtils>
</span>
)
}
}
SampleDatePickerWithUtils.js
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles'
import { updateFieldState, onTabOut, updateFocus } from 'actions/ticket_actions';
import { bindActionCreators } from 'redux';
import { getGridSizing } from 'styles/Sample_core_theme';
import { DatePicker, KeyboardDatePicker, MuiPickersUtilsProvider } from '#material-ui/pickers';
import { formatToYMD } from 'core/schema_translators/utils';
import EventIcon from '#material-ui/icons/Event';
import DateFnsUtils from '#date-io/date-fns'
import { SampleFieldComponent } from './base_components';
import { registerComponent } from 'actions/Sample_core_actions';
import { connect } from 'react-redux';
const moment = require('moment');
class MyDateFnsUtils extends DateFnsUtils {
startOfMonth(date) {
let dat = moment(date).startOf('month').toDate()
return dat
}
}
class _SampleDatePickerWithUtils extends SampleFieldComponent {
constructor(props) {
super(props);
let formattedDate = props.storeVal ? formatToYMD(props.storeVal) : null
this.state = {
value: formattedDate,
errorMsg: '',
isError: false,
}
this.styleProps = { disableUnderline: true }
this.inputLabelProps = { shrink: true }
this.onChangeCallback = this.onChangeCallback.bind(this)
// this.onBlurCallback = this.onBlurCallback.bind(this)
props.registerComponent(props.schemaLocation)
}
componentWillMount() {
this.props.registerComponent(this.props.schemaLocation)
if (this.props.manageValueManually) {
let dateValue = this.props.overriddenValue ? formatToYMD(this.props.overriddenValue) : null
this.props.updateFieldState(this.props.schemaLocation, dateValue)
}
}
componentDidMount() {
if (this.props.focusField) { this.focusDomElement() }
}
componentWillReceiveProps(nextProps) {
if (this.props.manageValueManually) {
if (nextProps.overriddenValue !== this.props.overriddenValue) {
let dateValue = nextProps.overriddenValue ? formatToYMD(nextProps.overriddenValue) : null
this.props.updateFieldState(this.props.schemaLocation, dateValue)
this.props.onTabOut(this.props.schemaLocation)
}
}
}
onChangeCallback(date) {
let formattedDate = date ? formatToYMD(date) : null
if (!this.props.manageValueManually) {
this.props.updateFieldState(this.props.schemaLocation, formattedDate)
this.props.onTabOut(this.props.schemaLocation) //this is required because the value is selected in a date picker
}
this.props.onDateChange(formattedDate)
}
render() {
const gridSizing = getGridSizing(this.props)
const { classes } = this.props
return (
<MuiPickersUtilsProvider utils={MyDateFnsUtils}>
<KeyboardDatePicker
keyboard={(!this.props.isDisabled).toString()}
keyboardIcon={<EventIcon style={{ fontSize: '22px', color: 'red' }} />}
clearable
disabled={this.props.isDisabled}
error={this.state.isError}
helperText={this.state.errorMsg}
InputProps={{ className: classes.inputProps }}
label={this.props.labelName === '' ? this.props.schemaLocation : this.props.labelName}
value='2020-04-30'
onChange={this.onChangeCallback}
// format={this.props.displayFormat}
format='yyyy-mm-dd'
onBlur={this.onBlurCallback}
InputLabelProps={this.inputLabelProps}
disableFuture={this.props.disableFuture}
disablePast={this.props.disablePast}
/>
</MuiPickersUtilsProvider>
);
}
}
const styles = (theme) => ({
inputProps: {
marginTop: '0px !important',
// fontSize: '14px',
border: 0,
'& input': {
fontSize: '14px',
'&:focus': {
boxSizing: 'content-box'
}
}
}
})
const SampleDatePickerWithUtils = withStyles(styles)(_SampleDatePickerWithUtils)
export { SampleDatePickerWithUtils }
Using KeyboardDatePicker with moment the format I use is
format = {moment.localeData().longDateFormat('L')} // In my case dd/mm/yyyy
If you want to use a different locale you can require it first and use it
require("moment/locale/en-us");
moment().locale("en-us");
format = {moment().locale(locale).localeData().longDateFormat('L')}
For the value I use moment date when the date has a value and null otherwise
value={date ? moment(date) : null}
and for the onChange I'm using universal format as I don't want to store it in locale format
{(date: any) => handleChange(path, date?.format('YYYY-MM-DD'))}
I want to combine the inline toolbar with the example from draft.js to insert a link into the editor.
Thanks to the draft.js plugin FAQ I am able to add a decorator to the draft-js-plugin editor which inserts a link on a button click.
Now I want to put this button inside the inline-toolbar from draft-js-plugins. That doesn't seem to work. This is what I've done so far:
Editor.jsx
...
const inlineToolbarPlugin = createInlineToolbarPlugin({
theme: {buttonStyles, toolbarStyles},
structure: [..., LinkButton]
});
const {InlineToolbar} = inlineToolbarPlugin;
const plugins = [inlineToolbarPlugin];
class RMSEditor extends Component {
...
render() {
return (
<div>
<div className={editorStyles.editor}>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={plugins}
decorators={this.decorator}
ref={(element) => {
this.editor = element;
}}
readOnly={this.state.readOnly}
/>
<InlineToolbar />
</div>
</div>
);
}
LinkButton.jsx
import classNames from "classnames/bind";
import React from "react";
import {Glyphicon} from "react-bootstrap";
import styles from "./buttonStyles.less";
const cx = classNames.bind(styles);
const LinkButton = () => {
return (
<div className={cx('buttonWrapper')} onClick={(e) => {
console.log("Div", e);
}}>
<button className={cx('button')} onClick={(e) => {
console.log("Button", e);
}}><Glyphicon glyph="link"/></button>
</div>
)
};
export default LinkButton;
This way, I have managed to get a Button that shows up in the inline toolbar. But when I clicked on that button, nothing happens. I expacted that one of the onClick handlers will fire but that is not the case.
Full source code
Here you can find my full sourcecode as I don't want to put only the relevant parts directly under the questions. Please notice that the code will not work in the run snipped thingy as I have no clue how to get it to work there without setting up the hole wabpack thing.
MentionsEditor.jsx
import {CompositeDecorator, EditorState, RichUtils} from "draft-js";
import {BoldButton, CodeButton, ItalicButton, UnderlineButton, UnorderedListButton} from "draft-js-buttons";
import createInlineToolbarPlugin from "draft-js-inline-toolbar-plugin";
import {defaultSuggestionsFilter} from "draft-js-mention-plugin"; // eslint-disable-line import/no-unresolved
import Editor from "draft-js-plugins-editor"; // eslint-disable-line import/no-unresolved
import React, {Component, PropTypes} from "react";
import {Button} from "react-bootstrap";
import buttonStyles from "./buttonStyles";
import editorStyles from "./editorStyles";
import LinkButton from "./InsertLinkButton";
import toolbarStyles from "./toolbarStyles";
const inlineToolbarPlugin = createInlineToolbarPlugin({
theme: {buttonStyles, toolbarStyles},
structure: [BoldButton, ItalicButton, UnderlineButton, CodeButton, UnorderedListButton, LinkButton]
});
const {InlineToolbar} = inlineToolbarPlugin;
const plugins = [inlineToolbarPlugin];
class RMSEditor extends Component {
constructor(props) {
super(props);
}
decorator = [
{
strategy: function findLinkEntities(contentBlock, callback, contentState) {
contentBlock.findEntityRanges(
(character) => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === 'LINK'
);
},
callback
);
},
component: function (props) {
const {url} = props.contentState.getEntity(props.entityKey).getData();
return (
<a href={url}>
{props.children}
</a>
);
}
}
];
state = {
editorState: EditorState.createEmpty(),
};
onChange = (editorState) => {
this.setState({
editorState,
});
};
editorLink = function (props) {
const {url} = props.contentState.getEntity(props.entityKey).getData();
return (
<a href={url} style={{color: "blue"}}>
{props.children}
</a>
);
};
focus = () => {
this.editor.focus();
};
insertLink = (e) => {
e.preventDefault();
const {editorState} = this.state;
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity(
'LINK',
'MUTABLE',
{url: "https://example.com"}
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, {currentContent: contentStateWithEntity});
this.setState({
editorState: RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
)
}, () => {
setTimeout(() => {
this.focus()
}, 0);
});
};
render() {
return (
<div>
<Button onClick={this.insertLink}>insert URL</Button>
<div className={editorStyles.editor}>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={plugins}
decorators={this.decorator}
ref={(element) => {
this.editor = element;
}}
readOnly={this.state.readOnly}
/>
<InlineToolbar />
</div>
</div>
);
}
}
RMSEditor.propTypes = {
stakeholder: PropTypes.object.isRequired
};
export default RMSEditor;
LinkButton.jsx
import classNames from "classnames/bind";
import React from "react";
import {Glyphicon} from "react-bootstrap";
import styles from "./buttonStyles.less";
const cx = classNames.bind(styles);
const LinkButton = () => {
return (
<div className={cx('buttonWrapper')} onClick={(e) => {
console.log("Div", e);
}}>
<button className={cx('button')} onClick={(e) => {
console.log("Button", e);
}}><Glyphicon glyph="link"/></button>
</div>
)
};
export default LinkButton;
This works for me:
const MyButton = (props) => {
return (
<div className={props.className} onMouseDown={(e)=>e.preventDefault()}>
<button onClick={() => props.createComment('Hello')}>
Comment
</button>
</div>
)
}
const inlineToolbarPlugin = createInlineToolbarPlugin({
structure: [props => <MyButton {...props} createComment={(text) => alert(text)} />]
});
const { InlineToolbar } = inlineToolbarPlugin;
export default class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { editorState } = this.state;
return (
<div className="editor">
<Editor
editorState={editorState}
onChange={this.onChange}
plugins={[inlineToolbarPlugin]}
ref={(element) => { this.editor = element; }}
/>
<InlineToolbar />
</div>
)
}
}
Basically, this is what you need to do:
1) import the inline toolbar plugin (bonus there is a separator in there)
import createInlineToolbarPlugin, {Separator} from 'draft-js-inline-toolbar-plugin'
2) instantciate the plugin like this:
const inlineToolbarPlugin = createInlineToolbarPlugin({
structure: [
BoldButton,
ItalicButton,
UnderlineButton,
CodeButton,
Separator,
],
})
2.1) you can get those components and more from draft-js-buttons
3) add to the array more components (let's add a video button component)
AddVideoButton
this is what it looks like
import React, { Component, PropTypes } from 'react'
import classnames from 'classnames'
import { AtomicBlockUtils, RichUtils } from 'draft-js'
import createVideoPlugin from 'draft-js-video-plugin'
const {types} = createVideoPlugin()
export default class AddVideoButton extends Component {
static propTypes = {
getEditorState: PropTypes.func,
setEditorState: PropTypes.func,
style: PropTypes.shape(),
theme: PropTypes.shape(),
}
// toggleStyle(event){
// const { setEditorState, getEditorState, style } = this.props
//
// event.preventDefault()
// setEditorState(
// RichUtils.toggleInlineStyle(
// getEditorState(),
// style
// )
// )
// }
toggleVideo(event){
const { setEditorState, getEditorState } = this.props
event.preventDefault()
const style = { width: 100}
const editorState = getEditorState()
const currentContent = editorState.getCurrentContent()
const selectionState = editorState.getSelection()
const anchorKey = selectionState.getAnchorKey()
const currentContentBlock = currentContent.getBlockForKey(anchorKey)
const start = selectionState.getStartOffset()
const end = selectionState.getEndOffset()
const src = currentContentBlock.getText().slice(start, end)
if (RichUtils.getCurrentBlockType(editorState) === types.ATOMIC) {
return editorState
}
const contentState = editorState.getCurrentContent()
const contentStateWithEntity = contentState.createEntity(
types.VIDEOTYPE,
'IMMUTABLE',
{ src, style }
)
const entityKey = contentStateWithEntity.getLastCreatedEntityKey()
const newEditorState = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ')
return setEditorState(newEditorState)
}
render(){
const { theme, style, getEditorState } = this.props
const styleIsActive = () => getEditorState().getCurrentInlineStyle().has(style)
return (
<div
className={theme.buttonWrapper}
onMouseDown={(e)=>e.preventDefault()}
>
<button
className={classnames({
[theme.active]:styleIsActive(),
[theme.button]:true,
})}
onClick={::this.toggleVideo}
>
<svg height="24" viewBox="0 0 120 100" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M111.374,20.922c-3.151-3.159-7.557-5.128-12.374-5.125H29c-4.817-0.002-9.222,1.966-12.375,5.125 c-3.159,3.152-5.128,7.557-5.125,12.375v40.038c-0.002,4.818,1.966,9.223,5.125,12.375c3.152,3.158,7.557,5.129,12.375,5.125h70 c4.817,0.004,9.224-1.967,12.375-5.125c3.159-3.152,5.128-7.557,5.125-12.375V33.296C116.503,28.479,114.534,24.074,111.374,20.922z M104.624,78.959c-1.454,1.447-3.413,2.328-5.624,2.33H29c-2.211-0.002-4.17-0.883-5.625-2.33c-1.447-1.455-2.328-3.414-2.33-5.625 V33.296c0.002-2.211,0.883-4.17,2.33-5.625c1.455-1.447,3.413-2.328,5.625-2.33h70c2.211,0.002,4.17,0.883,5.625,2.33 c1.447,1.455,2.327,3.413,2.329,5.625v40.038C106.952,75.545,106.072,77.504,104.624,78.959z" fill="#232323"/><path d="M77.519,50.744L57.45,39.161c-0.46-0.266-0.971-0.397-1.483-0.397c-0.513,0-1.023,0.131-1.484,0.397 c-0.918,0.528-1.483,1.509-1.483,2.569v23.171c0,1.061,0.565,2.04,1.483,2.57c0.46,0.267,0.971,0.396,1.484,0.396 c0.513,0,1.023-0.13,1.483-0.396l20.069-11.586c0.918-0.531,1.482-1.51,1.482-2.571C79.001,52.253,78.437,51.274,77.519,50.744z" fill="#232323"/>
<path d="M0 0h24v24H0z" fill="none" />
</svg>
</button>
</div>
)
}
}
or
you can imitate anything out of the draft-js-buttons
Let me know if I helped or if you have any other questions