react-native-awesome-alert
Version:
Modal component with checkoptions for react native, it works on iOS and Android.
269 lines (240 loc) • 7.92 kB
JavaScript
import React, { Component } from "react"
import CheckBox from "react-native-check-box"
import { StyleSheet, Text, View, Image, TouchableOpacity, Alert, Modal } from "react-native"
import PropTypes from "prop-types"
import AlertStorageManager from "./AlertStorageManager"
import TimeManager from "./TimeManager"
import checkAlertStyles from "./CheckAlert.style"
const styles = {}
const NEVER_ALERT_PREFIX = "neverAskAlert:"
const RANDOM_ALERT_PREFIX = "randomAskAlert:"
export default class CheckAlert extends Component {
static propTypes = {
styles: PropTypes.object,
leftCheck: PropTypes.bool
}
static defaultProps = {
styles: checkAlertStyles,
leftCheck: true
}
constructor(props) {
super(props)
this.state = {
modalVisible: false,
askAlways: true,
alertsArr: []
}
this.checkbox = true
this.modalID = null
this.checkSaveBtnIdx = null
this.title = " "
this.messagesView = null
this.buttons = []
this.checkText = " "
this.invisibleTime = null
new AlertStorageManager()
.getObjDatasArr()
.then(objDatas => {
this.setState({ alertsArr: objDatas })
})
.catch(err => console.warn(err.message))
if (this.props.styles) {
Object.keys(checkAlertStyles).forEach(key => {
styles[key] = StyleSheet.flatten([checkAlertStyles[key], this.props.styles[key]])
})
} else {
styles = checkAlertStyles
}
}
shouldComponentUpdate(nextProps, nextState) {
const beforeAskAlways = this.state.askAlways
const beforeModalVisible = this.state.modalVisible
const { askAlways, modalVisible } = nextState
if (beforeAskAlways != askAlways || beforeModalVisible != modalVisible) {
return true
} else {
return false
}
}
typeChecker(title, messagesView, buttons, checkText, invisibleTime) {
if (
typeof title !== "string" ||
!React.isValidElement(messagesView) ||
!Array.isArray(buttons) ||
typeof checkText !== "string" ||
typeof invisibleTime !== "number"
) {
return true
} else {
return false
}
}
parseButton(buttons, isNeverAsk) {
// Search button's id
for (let i in buttons) {
if (buttons[i].hasOwnProperty("id")) {
this.modalID = isNeverAsk
? NEVER_ALERT_PREFIX + buttons[i].id
: RANDOM_ALERT_PREFIX + buttons[i].id
this.checkSaveBtnIdx = parseInt(i)
break
}
}
}
alert(title, messagesView, buttons) {
const typeError = this.typeChecker(title, messagesView, buttons, " ", 0)
if (typeError) {
console.warn("TypeError, check the alert parameter")
return
}
this.title = title
this.messagesView = messagesView
this.buttons = buttons
this.checkbox = false
this.openModal()
}
checkAlert(title, messagesView, buttons, checkText, invisibleTime, isNeverAsk) {
const typeError = this.typeChecker(title, messagesView, buttons, checkText, invisibleTime)
if (typeError) {
console.warn("TypeError, check the alert parameter")
return
}
let newID = true
let alertData = null
this.parseButton(buttons, isNeverAsk)
if (this.modalID != null) {
this.title = title
this.messagesView = messagesView
this.buttons = buttons
this.checkbox = true
this.checkText = checkText
this.invisibleTime = invisibleTime
if (this.state.alertsArr != null) {
for (let alert of this.state.alertsArr) {
if (alert.id == this.modalID) {
newID = false
alertData = alert
break
}
}
}
if (newID) {
alertData = { id: this.modalID, show: true, savedTime: Date.now() }
new AlertStorageManager().saveAlert(alertData).then(() => {
this.openModal(alertData)
new AlertStorageManager()
.getObjDatasArr()
.then(objDatas => this.setState({ alertsArr: objDatas }))
.catch(err => console.warn(err.message))
})
} else {
this.openModal(alertData)
}
} else {
console.warn("you missed Alert button's ID")
}
}
neverAskAlert(title, messagesView, buttons, checkText = " ") {
this.checkAlert(title, messagesView, buttons, checkText, 0, true)
}
randomAskAlert(title, messagesView, buttons, checkText = " ", invisibleTime) {
this.checkAlert(title, messagesView, buttons, checkText, invisibleTime, false)
}
setModalVisible(visible, buttonIdx = null) {
if (!visible && !this.state.askAlways && buttonIdx === this.checkSaveBtnIdx) {
const alertStorageManager = new AlertStorageManager()
alertStorageManager.showFalse(this.modalID, () =>
alertStorageManager
.getObjDatasArr()
.then(objDatas => this.setState({ alertsArr: objDatas }))
.catch(err => console.warn(err.message))
)
}
this.setState({ modalVisible: visible, askAlways: true })
}
openModal(alertData = null) {
if (alertData == null) {
this.setModalVisible(true)
return
}
if (alertData.id.includes(RANDOM_ALERT_PREFIX)) {
const overDay = TimeManager.randomeTimeCheck(
alertData.savedTime,
Date.now(),
this.invisibleTime
)
if (overDay && !alertData.show) {
const alertStorageManager = new AlertStorageManager()
alertStorageManager.showTrue(this.modalID, () =>
alertStorageManager
.getObjDatasArr()
.then(objDatas => this.setState({ alertsArr: objDatas }))
.catch(err => console.warn(err.message))
)
this.setModalVisible(true)
}
}
alertData.show ? this.setModalVisible(true) : this.buttons[this.checkSaveBtnIdx].onPress()
}
render() {
const buttonTextStyle = []
// apply button's style
for (let button of this.buttons) {
const textStyle = StyleSheet.flatten([styles.buttonText, button.style])
buttonTextStyle.push(textStyle)
}
return (
<View>
<Modal
{...this.props.modalProps}
visible={this.state.modalVisible}
onRequestClose={() => this.setModalVisible(false)}
>
<View style={styles.modalContainer}>
<View style={styles.modalView}>
<Text style={styles.titleText}>
{this.title}
</Text>
{this.messagesView}
{this.checkbox && this.renderCheckBox()}
<View style={styles.buttonContainer}>
{this.buttons.map((button, index) => {
return (
<TouchableOpacity
key={index}
onPress={() => {
button.onPress()
this.setModalVisible(false, index)
}}
style={styles.button}
>
<Text style={buttonTextStyle[index]}>
{button.text}
</Text>
</TouchableOpacity>
)
})}
</View>
</View>
</View>
</Modal>
</View>
)
}
renderCheckBox() {
return (
<CheckBox
style={styles.checkBox}
onClick={() => this.setState({ askAlways: !this.state.askAlways })}
isChecked={!this.state.askAlways}
rightTextStyle={this.props.leftCheck ? styles.checkBoxText : null}
rightText={this.props.leftCheck ? this.checkText : null}
leftText={this.props.leftCheck ? null : this.checkText}
letTextStyle={this.props.leftCheck ? null : styles.checkBoxText}
checkedImage={this.props.checkedImage}
unCheckedImage={this.props.unCheckedImage}
checkBoxColor={this.props.checkBoxColor}
/>
)
}
}