import React from 'react'; import PropTypes from 'prop-types'; import QRCodeReader from '@Components/QRCodeReader'; import { secretPattern } from '@Lib/otp'; import { TwitterPicker } from 'react-color'; import { SKAlert } from 'sn-stylekit'; import { contextualColors, defaultBgColor, getAllContextualColors, getEntryColor } from '@Lib/utils'; export default class EditEntry extends React.Component { static defaultProps = { entry: { service: '', account: '', secret: '', notes: '' } }; constructor(props) { super(props); this.state = { id: this.props.id, entry: this.props.entry, showColorPicker: false, qrCodeError: false }; } formatSecret(secret) { return secret.replace(/\s/g, '').toUpperCase(); } handleInputChange = event => { const target = event.target; const name = target.name; const value = name === 'secret' ? this.formatSecret(target.value) : target.value; this.setState(state => ({ entry: { ...state.entry, [name]: value } })); }; handleSwatchClick = () => { this.setState({ showColorPicker: !this.state.showColorPicker }); }; handleColorPickerClose = () => { this.setState({ showColorPicker: false }); }; removeColor = () => { this.setState((state) => { delete state.entry.color; return { entry: state.entry }; }); }; onSave = () => { const { id, entry } = this.state; this.props.onSave({ id, entry }); }; onQRCodeSuccess = otpData => { const { issuer: labelIssuer, account } = otpData.label; const { issuer: queryIssuer, secret } = otpData.query; this.setState({ entry: { service: labelIssuer || queryIssuer || '', account, secret: this.formatSecret(secret) } }); }; onQRCodeError = message => { this.setState({ qrCodeError: message }); }; dismissQRCodeError = () => { this.setState({ qrCodeError: false }); }; render() { const { id, entry, showColorPicker, qrCodeError } = this.state; const qrCodeAlert = new SKAlert({ title: 'Error', text: qrCodeError, buttons: [ { text: 'OK', style: 'info', action: this.dismissQRCodeError } ] }); if (qrCodeError) { qrCodeAlert.present(); } const entryColor = getEntryColor(document, entry); const swatchStyle = { width: '36px', height: '14px', borderRadius: '2px', background: `${entryColor ?? defaultBgColor}`, }; const themeColors = getAllContextualColors(document); const defaultColorOptions = [ ...themeColors, '#658bdb', '#4CBBFC', '#FF794D', '#EF5276', '#91B73D', '#9B7ECF' ]; const handleColorChange = (color) => { let selectedColor = color.hex.toUpperCase(); const colorIndex = defaultColorOptions.indexOf(selectedColor); if (colorIndex > -1 && colorIndex <= themeColors.length - 1) { selectedColor = contextualColors[colorIndex]; } this.setState(state => ({ entry: { ...state.entry, color: selectedColor } })); }; return (
{id != null ? 'Edit entry' : 'Add new entry'}
{id == null && ( )} <> {entryColor && (
Clear color
)}
{showColorPicker && (
{ const hoveredColor = color.hex.toUpperCase(); if (themeColors.includes(hoveredColor)) { event.target.setAttribute( 'title', 'This color will change depending on your active theme.' ); } }} />
)}
); } } EditEntry.propTypes = { id: PropTypes.number, entry: PropTypes.object.isRequired, onSave: PropTypes.func.isRequired, onCancel: PropTypes.func.isRequired };