import React, {PropTypes, PureComponent} from 'react';
import autobind from 'autobind-decorator';
import {remote} from 'electron';
import {DEBOUNCE_MILLIS, isMac} from '../../common/constants';
import {Dropdown, DropdownButton, DropdownDivider, DropdownHint, DropdownItem} from './base/dropdown';
import {trackEvent} from '../../analytics';
import {showPrompt} from './modals/index';
import MethodDropdown from './dropdowns/method-dropdown';
import PromptButton from './base/prompt-button';
import OneLineEditor from './codemirror/one-line-editor';
@autobind
class RequestUrlBar extends PureComponent {
constructor (props) {
super(props);
this.state = {
currentInterval: null,
currentTimeout: null,
downloadPath: null
};
this._urlChangeDebounceTimeout = null;
this._lastPastedText = null;
}
_setDropdownRef (n) {
this._dropdown = n;
}
_setInputRef (n) {
this._input = n;
}
_handleMetaClickSend (e) {
e.preventDefault();
this._dropdown.show();
}
_handleFormSubmit (e) {
e.preventDefault();
e.stopPropagation();
this._handleSend();
}
_handleMethodChange (method) {
this.props.onMethodChange(method);
trackEvent('Request', 'Method Change', method);
}
_handleUrlChange (url) {
clearTimeout(this._urlChangeDebounceTimeout);
this._urlChangeDebounceTimeout = setTimeout(async () => {
const pastedText = this._lastPastedText;
// If no pasted text in the queue, just fire the regular change handler
if (!pastedText) {
this.props.onUrlChange(url);
return;
}
// Reset pasted text cache
this._lastPastedText = null;
// Attempt to import the pasted text
const importedRequest = await this.props.handleImport(pastedText);
// Update depending on whether something was imported
if (!importedRequest) {
this.props.onUrlChange(url);
}
}, DEBOUNCE_MILLIS);
}
_handleUrlPaste (e) {
// NOTE: We're not actually doing the import here to avoid races with onChange
this._lastPastedText = e.clipboardData.getData('text/plain');
}
_handleGenerateCode () {
this.props.handleGenerateCode();
trackEvent('Request', 'Generate Code', 'Send Action');
}
_handleSetDownloadLocation () {
const options = {
title: 'Select Download Location',
buttonLabel: 'Select',
properties: ['openDirectory']
};
remote.dialog.showOpenDialog(options, paths => {
if (!paths || paths.length === 0) {
trackEvent('Response', 'Download Select Cancel');
return;
}
this.setState({downloadPath: paths[0]});
});
}
_handleClearDownloadLocation () {
this.setState({downloadPath: null});
}
_handleKeyDown (e) {
if (!this._input) {
return;
}
// meta+l
const metaPressed = isMac() ? e.metaKey : e.ctrlKey;
if (metaPressed && e.keyCode === 76) {
e.preventDefault();
this._input.focus();
this._input.selectAll();
}
}
_handleSend () {
// Don't stop interval because duh, it needs to keep going!
// XXX this._handleStopInterval(); XXX
this._handleStopTimeout();
const {downloadPath} = this.state;
if (downloadPath) {
this.props.handleSendAndDownload(downloadPath);
} else {
this.props.handleSend();
}
}
_handleSendAfterDelay () {
showPrompt({
inputType: 'decimal',
title: 'Send After Delay',
label: 'Delay in seconds',
defaultValue: 3,
submitName: 'Start',
onComplete: seconds => {
this._handleStopTimeout();
this._sendTimeout = setTimeout(this._handleSend, seconds * 1000);
this.setState({currentTimeout: seconds});
trackEvent('Request', 'Send on Delay', 'Send Action', seconds);
}
});
}
_handleSendOnInterval () {
showPrompt({
inputType: 'decimal',
title: 'Send on Interval',
label: 'Interval in seconds',
defaultValue: 3,
submitName: 'Start',
onComplete: seconds => {
this._handleStopInterval();
this._sendInterval = setInterval(this._handleSend, seconds * 1000);
this.setState({currentInterval: seconds});
trackEvent('Request', 'Send on Interval', 'Send Action', seconds);
}
});
}
_handleStopInterval () {
clearTimeout(this._sendInterval);
if (this.state.currentInterval) {
this.setState({currentInterval: null});
trackEvent('Request', 'Stop Send Interval');
}
}
_handleStopTimeout () {
clearTimeout(this._sendTimeout);
if (this.state.currentTimeout) {
this.setState({currentTimeout: null});
trackEvent('Request', 'Stop Send Timeout');
}
}
_handleResetTimeouts () {
this._handleStopTimeout();
this._handleStopInterval();
}
_handleClickSend (e) {
const metaPressed = isMac() ? e.metaKey : e.ctrlKey;
// If we're pressing a meta key, let the dropdown open
if (metaPressed) {
e.preventDefault(); // Don't submit the form
return;
}
// If we're not pressing a meta key, cancel dropdown and send the request
e.stopPropagation(); // Don't trigger the dropdown
this._handleFormSubmit(e);
}
componentDidMount () {
document.body.addEventListener('keydown', this._handleKeyDown);
}
componentWillUnmount () {
document.body.removeEventListener('keydown', this._handleKeyDown);
}
componentWillReceiveProps (nextProps) {
if (nextProps.requestId !== this.props.requestId) {
this._handleResetTimeouts();
}
}
renderSendButton () {
const {currentInterval, currentTimeout, downloadPath} = this.state;
let cancelButton = null;
if (currentInterval) {
cancelButton = (
);
} else if (currentTimeout) {
cancelButton = (
);
}
let sendButton;
if (!cancelButton) {
sendButton = (