initial step 4 for online test
This commit is contained in:
@@ -12,8 +12,19 @@ const router = express.Router ();
|
|||||||
|
|
||||||
var app = express ();
|
var app = express ();
|
||||||
|
|
||||||
|
//User data for sending message, this is skill-related and will be in some skill container
|
||||||
|
var Name = null;
|
||||||
|
var Email = null;
|
||||||
|
var Message = null;
|
||||||
|
var State = 0; // states should be defined in seperate file. (Not sending message, Waiting for name, Waiting for email, Waiting for message)
|
||||||
|
//For now :
|
||||||
|
// 0 : Not sending Message
|
||||||
|
// 1 : Waiting for name
|
||||||
|
// 2 : Waiting for email
|
||||||
|
// 3 : Waiting for message
|
||||||
|
|
||||||
// ALWAYS setup the alexa app and attach it to express before anything else.
|
// ALWAYS setup the alexa app and attach it to express before anything else.
|
||||||
var alexaApp = new alexa.app ('step3'); // this means we still work with one skill
|
var alexaApp = new alexa.app ('saburly'); // this means we still work with one skill
|
||||||
|
|
||||||
alexaApp.express ({
|
alexaApp.express ({
|
||||||
expressApp: app,
|
expressApp: app,
|
||||||
@@ -39,6 +50,7 @@ var updateIntentsJSON = function () {
|
|||||||
.loadSkill (config.SKILL_DB_ID)
|
.loadSkill (config.SKILL_DB_ID)
|
||||||
.then (skill => {
|
.then (skill => {
|
||||||
skill.intents.map (intent => {
|
skill.intents.map (intent => {
|
||||||
|
|
||||||
alexaApp.intent (
|
alexaApp.intent (
|
||||||
intent.intentName,
|
intent.intentName,
|
||||||
{
|
{
|
||||||
@@ -50,9 +62,93 @@ var updateIntentsJSON = function () {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
alexaApp.launch ((request, response) => {
|
alexaApp.launch ((request, response) => {
|
||||||
return response.say (skill.invocationAnswer).shouldEndSession(false);
|
return response.say (skill.invocationAnswer).shouldEndSession(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
alexaApp.intent('EmailIntentLaunch',{
|
||||||
|
slots:[],
|
||||||
|
utterances: [
|
||||||
|
'I want to send a message',
|
||||||
|
'I would like to send a message',
|
||||||
|
'I would like to leave a message',
|
||||||
|
'Leave a message'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
function(request,response){
|
||||||
|
Name = null;
|
||||||
|
Email = null;
|
||||||
|
Message = null;
|
||||||
|
State = 1;
|
||||||
|
|
||||||
|
return response.say('Ok. What is your name').shouldEndSession(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//TODO : Watch out for this intent. It will make trouble with other regular intents
|
||||||
|
//if other intents have utterance with just one slot like {Data}
|
||||||
|
//It should be taken care somwhere before this, to check if Email Intent is invoked
|
||||||
|
//This is problem only if we introduce slot options for regular intents for users
|
||||||
|
alexaApp.intent('EmailIntent',{
|
||||||
|
slots:{
|
||||||
|
'Name':'AMAZON.Person',
|
||||||
|
'Email' : 'AMAZON.LITERAL',
|
||||||
|
'Message': 'AMAZON.LITERAL',
|
||||||
|
'Data': 'AMAZON.LITERAL'
|
||||||
|
},
|
||||||
|
utterances: [
|
||||||
|
'My name is {Name}',
|
||||||
|
'I am {Name}',
|
||||||
|
'{Data}',
|
||||||
|
'My email is {Email}',
|
||||||
|
'Send replay to {Email}',
|
||||||
|
'My message is {Message}'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
function(request,response){
|
||||||
|
if (!Name) Name = response.slots['Name'];
|
||||||
|
if (!Email) Email = response.slots['Email'];
|
||||||
|
if (!Message) Message = response.slots['Message'];
|
||||||
|
let Data = reponse.slots['Data'];
|
||||||
|
|
||||||
|
//TODO : Responses could be configurable for each skill ?
|
||||||
|
|
||||||
|
if (State === 1){
|
||||||
|
//Was waiting for name, so if Name is null, name is probably in Data
|
||||||
|
if ((!Name && Data) || Name){
|
||||||
|
//got the name, let's continue for the email
|
||||||
|
State = 2;
|
||||||
|
return response.say('Ok ' + Name + '. What is your email ?').shouldEndSession(false);
|
||||||
|
}else{
|
||||||
|
//Something is wrong, ask for name again
|
||||||
|
return response.say('Sorry, I didnt understand your name. Can you say it again ?').shouldEndSession(false);
|
||||||
|
}
|
||||||
|
}else if (State === 2){
|
||||||
|
//was waiting for email, so if Email is null, email is probably in Data
|
||||||
|
if ((!Email && Data) || Email){
|
||||||
|
//Got the email, first verify email and than continue to message
|
||||||
|
|
||||||
|
//TODO : verify email
|
||||||
|
State = 3;
|
||||||
|
return response.say('Great. Whats the message ?').shouldEndSession(false);
|
||||||
|
}else{
|
||||||
|
//Something is wrong, ask for the email again
|
||||||
|
return response.say('Sorry, I didnt understan you email. Can you say it again ?').shouldEndSession(false);
|
||||||
|
}
|
||||||
|
}else if (State === 3){
|
||||||
|
//Was waiting for message, so if Message is null, message is probably in Data
|
||||||
|
if ((!Message && Data) || Message){
|
||||||
|
//Ok, we got all informations. Exit email intent
|
||||||
|
State = 0;
|
||||||
|
//TODO : Send email
|
||||||
|
return response.say('Message sent. Someone will contact you ASAP');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch (err => {
|
.catch (err => {
|
||||||
console.log (err);
|
console.log (err);
|
||||||
@@ -92,14 +188,15 @@ router.get ('/deleteSkill/:skillID', async (req, res, next) => {
|
|||||||
|
|
||||||
router.post ('/updateSkill/:id', async (req, res, next) => {
|
router.post ('/updateSkill/:id', async (req, res, next) => {
|
||||||
let id = req.params.id;
|
let id = req.params.id;
|
||||||
let skill = req.body;
|
let dataFromWeb = JSON.stringify(req.body);
|
||||||
|
let skill = JSON.parse(dataFromWeb);
|
||||||
|
let updateOnAmazon = skill.updateOnAmazon;
|
||||||
|
delete skill.updateOnAmazon;
|
||||||
delete skill._id;
|
delete skill._id;
|
||||||
console.log('id = ' + id);
|
console.log('id = ' + id);
|
||||||
if (id !== '-1') {
|
if (id !== '-1') {
|
||||||
amazonHelper
|
if (updateOnAmazon){
|
||||||
.updateSkill (skill)
|
amazonHelper.updateSkill(skill).then(amazonResult=>{
|
||||||
.then (amazonResult => {
|
|
||||||
console.log('amazon result : ' + amazonResult);
|
|
||||||
if (amazonResult === 200 || amazonResult === 202) {
|
if (amazonResult === 200 || amazonResult === 202) {
|
||||||
//Skill uploaded, it's ok to update databaseI
|
//Skill uploaded, it's ok to update databaseI
|
||||||
databaseHelper
|
databaseHelper
|
||||||
@@ -109,16 +206,24 @@ router.post ('/updateSkill/:id', async (req, res, next) => {
|
|||||||
updateIntentsJSON ();
|
updateIntentsJSON ();
|
||||||
})
|
})
|
||||||
.catch (e => {
|
.catch (e => {
|
||||||
res.json ({result: -1, message: 'ok'});
|
res.json ({result: -1, message: 'error'});
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
res.json ({result: -1, message: 'Amazon result ' + amazonResult});
|
|
||||||
}
|
}
|
||||||
})
|
}).catch(e=>{
|
||||||
.catch (e => {
|
|
||||||
//skill upload went wrong, don't update database, send error
|
|
||||||
res.json ({result: -1, message: e});
|
res.json ({result: -1, message: e});
|
||||||
});
|
});
|
||||||
|
}else{
|
||||||
|
databaseHelper
|
||||||
|
.updateSkill (id, skill)
|
||||||
|
.then (result => {
|
||||||
|
res.json ({result: 0, message: 'ok'});
|
||||||
|
updateIntentsJSON ();
|
||||||
|
})
|
||||||
|
.catch (e => {
|
||||||
|
res.json ({result: -1, message: 'error'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//no new skills for now
|
//no new skills for now
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,47 @@ var generateInteractionModel = function (skill) {
|
|||||||
allIntents.push ({name: intent.intentName, samples: intent.questions});
|
allIntents.push ({name: intent.intentName, samples: intent.questions});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Special Email Intents :
|
||||||
|
allIntents.push({
|
||||||
|
name: 'EmailIntentLaunch',
|
||||||
|
slots:[],
|
||||||
|
samples: [
|
||||||
|
'I want to send a message',
|
||||||
|
'I would like to send a message',
|
||||||
|
'I would like to leave a message',
|
||||||
|
'Leave a message'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
allIntents.push({
|
||||||
|
name: 'EmailIntent',
|
||||||
|
slots:[
|
||||||
|
{
|
||||||
|
name: 'Name',
|
||||||
|
type: 'AMAZON.Person'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Email',
|
||||||
|
type: 'AMAZON.LITERAL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Message',
|
||||||
|
type: 'AMAZON.LITERAL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Data',
|
||||||
|
type: 'AMAZON.LITERAL'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
samples: [
|
||||||
|
'My name is {Name}',
|
||||||
|
'I am {Name}',
|
||||||
|
'{Data}',
|
||||||
|
'My email is {Email}',
|
||||||
|
'Send replay to {Email}',
|
||||||
|
'My message is {Message}'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
result.interactionModel = {};
|
result.interactionModel = {};
|
||||||
|
|
||||||
result.interactionModel.languageModel = {
|
result.interactionModel.languageModel = {
|
||||||
|
|||||||
134
web/src/App.js
134
web/src/App.js
@@ -4,9 +4,13 @@ import './css/popup.css';
|
|||||||
import IntentList from './components/IntentList';
|
import IntentList from './components/IntentList';
|
||||||
import IntentDetails from './components/IntentDetails';
|
import IntentDetails from './components/IntentDetails';
|
||||||
import LaunchRequest from './components/LaunchRequest';
|
import LaunchRequest from './components/LaunchRequest';
|
||||||
|
import Contact from './components/Contact';
|
||||||
import Popup from 'react-popup';
|
import Popup from 'react-popup';
|
||||||
|
|
||||||
import {getSkill, updateSkill} from './lib/api'
|
import {getSkill, updateSkill} from './lib/api'
|
||||||
|
import {
|
||||||
|
NEW_INTENT_SELECTED_INDEX,
|
||||||
|
LAUNCH_REQUEST_SELECTED_INDEX,
|
||||||
|
CONTACT_SELECTED_INDEX} from './config'
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
|
|
||||||
@@ -20,8 +24,8 @@ class App extends Component {
|
|||||||
invocationAnswer:'We are saburly',
|
invocationAnswer:'We are saburly',
|
||||||
allIntents:[],
|
allIntents:[],
|
||||||
selectedIntent: {intentName:'',questions:[''],answer:''},
|
selectedIntent: {intentName:'',questions:[''],answer:''},
|
||||||
selectedIndex:-1,
|
selectedIndex:NEW_INTENT_SELECTED_INDEX,
|
||||||
launchRequest:false,
|
contactEmail:'',
|
||||||
waiting: false
|
waiting: false
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,7 +34,7 @@ class App extends Component {
|
|||||||
if (jResult===undefined) return;
|
if (jResult===undefined) return;
|
||||||
this.setState({ skillID:jResult.skillID,skillName:jResult.skillName, invocationName: jResult.invocationName,
|
this.setState({ skillID:jResult.skillID,skillName:jResult.skillName, invocationName: jResult.invocationName,
|
||||||
invocationAnswer: jResult.invocationAnswer,
|
invocationAnswer: jResult.invocationAnswer,
|
||||||
allIntents: jResult.intents})
|
allIntents: jResult.intents, contactEmail: jResult.contactEmail})
|
||||||
})
|
})
|
||||||
|
|
||||||
this.handleIntentClick = this.handleIntentClick.bind(this);
|
this.handleIntentClick = this.handleIntentClick.bind(this);
|
||||||
@@ -41,62 +45,67 @@ class App extends Component {
|
|||||||
this.handleSaveLaunchRequestClick = this.handleSaveLaunchRequestClick.bind(this);
|
this.handleSaveLaunchRequestClick = this.handleSaveLaunchRequestClick.bind(this);
|
||||||
this.createSkill = this.createSkill.bind(this);
|
this.createSkill = this.createSkill.bind(this);
|
||||||
this.sendSkill = this.sendSkill.bind(this);
|
this.sendSkill = this.sendSkill.bind(this);
|
||||||
|
this.handleContactClick = this.handleContactClick.bind(this);
|
||||||
|
this.handleSaveEmailClick = this.handleSaveEmailClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
return(
|
||||||
if(this.state.launchRequest){
|
<div className="App">
|
||||||
return (
|
<Popup/>
|
||||||
<div className="App">
|
<div className="App-header">
|
||||||
<Popup/>
|
<h1> Tell All </h1>
|
||||||
<div className="App-header">
|
|
||||||
<h1> Tell All </h1>
|
|
||||||
</div>
|
|
||||||
<IntentList allIntents={this.state.allIntents}
|
|
||||||
onLaunchRequestClick={this.handleLaunchRequestClick}
|
|
||||||
onIntentClick={this.handleIntentClick}
|
|
||||||
onAddIntentClick={this.handleAddIntentClick}
|
|
||||||
selectedIndex={this.state.selectedIndex}
|
|
||||||
waiting={this.state.waiting}>
|
|
||||||
</IntentList>
|
|
||||||
<LaunchRequest invocationName={this.state.invocationName}
|
|
||||||
invocationAnswer={this.state.invocationAnswer}
|
|
||||||
onSaveClick={this.handleSaveLaunchRequestClick}
|
|
||||||
waiting={this.state.waiting}>
|
|
||||||
</LaunchRequest>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<IntentList allIntents={this.state.allIntents}
|
||||||
}else{
|
onLaunchRequestClick={this.handleLaunchRequestClick}
|
||||||
return (
|
onContactClick={this.handleContactClick}
|
||||||
<div className="App">
|
onIntentClick={this.handleIntentClick}
|
||||||
<Popup/>
|
onAddIntentClick={this.handleAddIntentClick}
|
||||||
<div className="App-header">
|
selectedIndex={this.state.selectedIndex}
|
||||||
<h1> Tell All </h1>
|
waiting={this.state.waiting}>
|
||||||
</div>
|
</IntentList>
|
||||||
<IntentList allIntents={this.state.allIntents}
|
{(
|
||||||
onLaunchRequestClick={this.handleLaunchRequestClick}
|
()=>{
|
||||||
onIntentClick={this.handleIntentClick}
|
if (this.state.selectedIndex===LAUNCH_REQUEST_SELECTED_INDEX){
|
||||||
onAddIntentClick={this.handleAddIntentClick}
|
return (
|
||||||
selectedIndex={this.state.selectedIndex}
|
<LaunchRequest invocationName={this.state.invocationName}
|
||||||
waiting={this.state.waiting}>
|
invocationAnswer={this.state.invocationAnswer}
|
||||||
</IntentList>
|
onSaveClick={this.handleSaveLaunchRequestClick}
|
||||||
<IntentDetails selectedIntent={this.state.selectedIntent}
|
waiting={this.state.waiting}>
|
||||||
onDeleteIntentClick={this.handleDeleteIntentClick}
|
</LaunchRequest>
|
||||||
onSaveIntentClick={this.handleSaveIntentClick}
|
);
|
||||||
waiting={this.state.waiting}>
|
}else if (this.state.selectedIndex===CONTACT_SELECTED_INDEX){
|
||||||
</IntentDetails>
|
return (
|
||||||
</div>
|
<Contact
|
||||||
);
|
contactEmail={this.state.contactEmail}
|
||||||
}
|
onSaveEmailClick={this.handleSaveEmailClick}
|
||||||
|
waiting={this.state.waiting}>
|
||||||
|
</Contact>
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
return(
|
||||||
|
<IntentDetails selectedIntent={this.state.selectedIntent}
|
||||||
|
onDeleteIntentClick={this.handleDeleteIntentClick}
|
||||||
|
onSaveIntentClick={this.handleSaveIntentClick}
|
||||||
|
waiting={this.state.waiting}>
|
||||||
|
</IntentDetails>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createSkill(intents, name, answer){
|
createSkill(intents, name, answer, email, updateOnAmazon){
|
||||||
return {
|
return {
|
||||||
_id: this.state._id,
|
_id: this.state._id,
|
||||||
skillID: this.state.skillID,
|
skillID: this.state.skillID,
|
||||||
intents: intents,
|
intents: intents,
|
||||||
invocationName: (name===undefined) ? this.state.invocationName : name,
|
invocationName: name,
|
||||||
invocationAnswer: (answer===undefined)? this.state.invocationAnswer: answer
|
invocationAnswer: answer,
|
||||||
|
contactEmail: email,
|
||||||
|
updateOnAmazon: updateOnAmazon
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,12 +114,21 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleLaunchRequestClick(){
|
handleLaunchRequestClick(){
|
||||||
this.setState({selectedIndex: -2, launchRequest:true});
|
this.setState({selectedIndex: LAUNCH_REQUEST_SELECTED_INDEX});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleContactClick(){
|
||||||
|
this.setState({selectedIndex: CONTACT_SELECTED_INDEX})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSaveLaunchRequestClick(name, answer){
|
handleSaveLaunchRequestClick(name, answer){
|
||||||
this.setState({waiting:true, invocationName:name, invocationAnswer: answer});
|
this.setState({waiting:true, invocationName:name, invocationAnswer: answer});
|
||||||
this.sendSkill(this.state.allIntents,true,{waiting:false},{waiting:false},name,answer);
|
this.sendSkill(this.state.allIntents,true,{waiting:false},{waiting:false},name,answer,this.state.contactEmail,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSaveEmailClick(email){
|
||||||
|
this.setState({waiting:true});
|
||||||
|
this.sendSkill(this.state.allIntents,true,{contactEmail: email, waiting:false},{waiting:false},this.state.invocationName,this.state.invocationAnswer,email,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDeleteIntentClick(selectedIntent){
|
handleDeleteIntentClick(selectedIntent){
|
||||||
@@ -128,7 +146,7 @@ class App extends Component {
|
|||||||
this.setState({waiting:true});
|
this.setState({waiting:true});
|
||||||
|
|
||||||
let newState = {allIntents: newAllIntents, selectedIntent: {intentName:'', questions:[''],answer:''}, waiting:false};
|
let newState = {allIntents: newAllIntents, selectedIntent: {intentName:'', questions:[''],answer:''}, waiting:false};
|
||||||
this.sendSkill(newAllIntents,true,newState,{waiting:false});
|
this.sendSkill(newAllIntents,true,newState,{waiting:false},this.state.invocationName,this.state.invocationAnswer,this.state.contactEmail,true);
|
||||||
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.log("error : " + e);
|
console.log("error : " + e);
|
||||||
@@ -142,7 +160,7 @@ class App extends Component {
|
|||||||
let newAllIntents = JSON.parse(newAllIntentsJSON);
|
let newAllIntents = JSON.parse(newAllIntentsJSON);
|
||||||
|
|
||||||
let newState = null;
|
let newState = null;
|
||||||
if (this.state.selectedIndex === -1){
|
if (this.state.selectedIndex === NEW_INTENT_SELECTED_INDEX){
|
||||||
//new intent
|
//new intent
|
||||||
newAllIntents.push(selectedIntent);
|
newAllIntents.push(selectedIntent);
|
||||||
newState = {allIntents: newAllIntents, selectedIntent: selectedIntent, selectedIndex: newAllIntents.length-1, waiting:false};
|
newState = {allIntents: newAllIntents, selectedIntent: selectedIntent, selectedIndex: newAllIntents.length-1, waiting:false};
|
||||||
@@ -151,16 +169,16 @@ class App extends Component {
|
|||||||
newState = {allIntents: newAllIntents, selectedIntent: selectedIntent, waiting: false};
|
newState = {allIntents: newAllIntents, selectedIntent: selectedIntent, waiting: false};
|
||||||
}
|
}
|
||||||
this.setState({waiting:true});
|
this.setState({waiting:true});
|
||||||
this.sendSkill(newAllIntents, true, newState, {waiting:false});
|
this.sendSkill(newAllIntents, true, newState, {waiting:false}, this.state.invocationName,this.state.invocationAnswer,this.state.contactEmail, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAddIntentClick(){
|
handleAddIntentClick(){
|
||||||
this.setState({allIntents: this.state.allIntents, selectedIndex: -1,launchRequest:false,selectedIntent: {intentName:'',questions:[''], answer:''}});
|
this.setState({allIntents: this.state.allIntents, selectedIndex: NEW_INTENT_SELECTED_INDEX,launchRequest:false,selectedIntent: {intentName:'',questions:[''], answer:''}});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendSkill(newAllIntents, showPopUp, resolveState, rejectState, newName, newAnswer){
|
sendSkill(newAllIntents, showPopUp, resolveState, rejectState, newName, newAnswer, email, updateOnAmazon){
|
||||||
return new Promise((resolve,reject)=>{
|
return new Promise((resolve,reject)=>{
|
||||||
updateSkill(this.createSkill(newAllIntents,newName,newAnswer)).then(l=>l.text()).then(result=>{
|
updateSkill(this.createSkill(newAllIntents,newName,newAnswer,email,updateOnAmazon)).then(l=>l.text()).then(result=>{
|
||||||
let jResult = JSON.parse(result);
|
let jResult = JSON.parse(result);
|
||||||
if (jResult.result !== 0){
|
if (jResult.result !== 0){
|
||||||
if (showPopUp) Popup.alert('Model was not saved. Please try again');
|
if (showPopUp) Popup.alert('Model was not saved. Please try again');
|
||||||
|
|||||||
48
web/src/components/Contact.js
Normal file
48
web/src/components/Contact.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import {Button, TextField} from 'react-md';
|
||||||
|
import '../css/Intent.css'
|
||||||
|
import {EMAIL_MAX_LENGTH} from '../config';
|
||||||
|
|
||||||
|
class Contact extends Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {contactEmail: props.contactEmail};
|
||||||
|
|
||||||
|
this.handleEmailEdit = this.handleEmailEdit.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(props){
|
||||||
|
this.setState({contactEmail: props.contactEmail});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="LaunchRequestBox">
|
||||||
|
<h5 style={{textAlign:'left', marginTop: '30px', marginLeft: '20px'}}> Contact address will be used for direct messaging through Alexa </h5>
|
||||||
|
<TextField
|
||||||
|
id="contact email"
|
||||||
|
lineDirection="center"
|
||||||
|
label="Contact email"
|
||||||
|
className="md-cell md-cell--bottom"
|
||||||
|
style={{width:'60%', marginLeft: '20px'}}
|
||||||
|
maxLength={EMAIL_MAX_LENGTH}
|
||||||
|
onChange={this.handleEmailEdit}
|
||||||
|
value={this.state.contactEmail}/>
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
<Button style={{float:'right', marginRight: '20px'}} flat primary swapTheming
|
||||||
|
onClick={()=>{this.props.onSaveEmailClick(this.state.contactEmail)}}
|
||||||
|
disabled={this.props.waiting}>Save</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleEmailEdit(e){
|
||||||
|
if (e.length === EMAIL_MAX_LENGTH) return;
|
||||||
|
this.setState({contactEmail: e});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Contact;
|
||||||
@@ -2,6 +2,9 @@ import React, { Component } from 'react';
|
|||||||
import {Button} from 'react-md';
|
import {Button} from 'react-md';
|
||||||
import IntentItem from './IntentItem';
|
import IntentItem from './IntentItem';
|
||||||
import '../css/Intent.css'
|
import '../css/Intent.css'
|
||||||
|
import {
|
||||||
|
LAUNCH_REQUEST_SELECTED_INDEX,
|
||||||
|
CONTACT_SELECTED_INDEX} from '../config'
|
||||||
|
|
||||||
class IntentList extends Component {
|
class IntentList extends Component {
|
||||||
constructor (props){
|
constructor (props){
|
||||||
@@ -17,9 +20,15 @@ class IntentList extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="IntentList">
|
<div className="IntentList">
|
||||||
<Button className={this.props.selectedIndex===-2 ? "LaunchRequest-selected" : "LaunchRequest"} flat primary
|
<Button className={this.props.selectedIndex===LAUNCH_REQUEST_SELECTED_INDEX ? "LaunchRequest-selected" : "LaunchRequest"} flat primary
|
||||||
onClick={this.props.onLaunchRequestClick}
|
onClick={this.props.onLaunchRequestClick}
|
||||||
disabled={this.props.waiting} >Launch request</Button>
|
disabled={this.props.waiting} >Launch request</Button>
|
||||||
|
|
||||||
|
<Button className={this.props.selectedIndex===CONTACT_SELECTED_INDEX ? "Contact-selected" : "Contact"} flat primary
|
||||||
|
onClick={this.props.onContactClick}
|
||||||
|
disabled={this.props.waiting} >Contact</Button>
|
||||||
|
|
||||||
|
|
||||||
<div className="IntentList-title">
|
<div className="IntentList-title">
|
||||||
<h3>Intents</h3>
|
<h3>Intents</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,3 +9,9 @@ export const INTENT_TITLE_TOOLTIP_DELAY = 700;
|
|||||||
|
|
||||||
export const INVOCATION_NAME_MAX_LENGTH = 15;
|
export const INVOCATION_NAME_MAX_LENGTH = 15;
|
||||||
export const INVOCATION_ANSWER_MAX_LENGTH = 100;
|
export const INVOCATION_ANSWER_MAX_LENGTH = 100;
|
||||||
|
|
||||||
|
export const EMAIL_MAX_LENGTH = 100;
|
||||||
|
|
||||||
|
export const NEW_INTENT_SELECTED_INDEX = -1;
|
||||||
|
export const LAUNCH_REQUEST_SELECTED_INDEX = -2;
|
||||||
|
export const CONTACT_SELECTED_INDEX = -3;
|
||||||
@@ -24,6 +24,20 @@
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: #f5f5f5; }
|
background-color: #f5f5f5; }
|
||||||
|
|
||||||
|
.Contact {
|
||||||
|
text-align: left;
|
||||||
|
color: #009b8a;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #d8d8d8; }
|
||||||
|
|
||||||
|
.Contact-selected {
|
||||||
|
text-align: left;
|
||||||
|
color: #009b8a;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #f5f5f5; }
|
||||||
|
|
||||||
.AddIntent {
|
.AddIntent {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 12px; }
|
margin: 12px; }
|
||||||
|
|||||||
@@ -31,6 +31,22 @@ $minHeight : calc(100vh - 80px);
|
|||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Contact{
|
||||||
|
text-align: left;
|
||||||
|
color: #009b8a;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #d8d8d8
|
||||||
|
}
|
||||||
|
|
||||||
|
.Contact-selected{
|
||||||
|
text-align: left;
|
||||||
|
color: #009b8a;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
.AddIntent{
|
.AddIntent{
|
||||||
float: right;
|
float: right;
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
|
|||||||
Reference in New Issue
Block a user