forms seem to work now

This commit is contained in:
or-else
2018-11-04 17:27:25 +03:00
parent bad6232b9a
commit c72819de38
13 changed files with 171 additions and 45 deletions
+16 -5
View File
@@ -558,10 +558,23 @@ table.permission-editor td.checkbox {
min-width: 8rem;
}
.bot-form.hlist {
flex-direction: column;
flex-direction: row;
}
.bot-form div {
min-height: 2rem;
vertical-align: middle;
}
/* Nested bot forms should have not border */
.bot-form .bot-form {
border: none;
}
.bot-form div {
/*
Form element with non-interactive content
needs padding.
*/
.bot-form div.dft {
padding: 0.25rem 1rem;
min-height: 2rem;
vertical-align: middle;
}
@@ -664,7 +677,7 @@ i.search {
.alert-box.info {
display: flex;
background-color: #e1f5fe;
border-bottom: 1px solid #4fc3f7;
border-bottom: 1px solid #b3e5fc;
color: #0288d1;
}
.alert-box .cancel .material-icons {
@@ -1155,7 +1168,6 @@ i.search {
margin: 0;
padding: 0;
align-items: flex-end;
overflow: hidden;
}
.chat-box .right {
@@ -1171,7 +1183,6 @@ i.search {
padding: 0.75rem 0.5rem 0.75rem 1.25rem;
margin: 0;
text-align: left;
border-radius: 0.5rem;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -7,6 +7,7 @@ import Tinode from 'tinode-sdk';
import AvatarUpload from '../widgets/avatar-upload.jsx';
import CheckBox from '../widgets/checkbox.jsx';
import ContactList from '../widgets/contact-list.jsx';
import ErrorPanel from '../widgets/error-panel.jsx';
import GroupManager from '../widgets/group-manager.jsx';
import InPlaceEdit from '../widgets/in-place-edit.jsx';
import MenuCancel from '../widgets/menu-cancel.jsx';
+32 -6
View File
@@ -2,6 +2,7 @@ import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import Tinode from 'tinode-sdk';
const Drafty = Tinode.Drafty;
import ChatMessage from '../widgets/chat-message.jsx';
import ErrorPanel from '../widgets/error-panel.jsx';
@@ -62,6 +63,7 @@ class MessagesView extends React.Component {
this.handleInfoReceipt = this.handleInfoReceipt.bind(this);
this.handleImagePreview = this.handleImagePreview.bind(this);
this.handleCloseImagePreview = this.handleCloseImagePreview.bind(this);
this.handleFormResponse = this.handleFormResponse.bind(this);
this.handleContextClick = this.handleContextClick.bind(this);
this.handleShowContextMenuMessage = this.handleShowContextMenuMessage.bind(this);
this.handleBackNavigation = this.handleBackNavigation.bind(this);
@@ -349,6 +351,30 @@ class MessagesView extends React.Component {
this.setState({ imagePreview: null });
}
handleFormResponse(action, text, data) {
if (action == 'pub') {
this.props.sendMessage(Drafty.attachJSON(Drafty.parse(text), data));
} else if (action == 'url') {
const url = new URL(data.ref);
let params = url.searchParams;
for (let key in data.resp) {
if (data.resp.hasOwnProperty(key)) {
params.set(key, data.resp[key]);
}
}
['name', 'seq'].map(function(key) {
if (data[key]) {
params.set(key, data[key]);
}
});
params.set('uid', this.props.myUserId);
url.search = params;
window.open(url, '_blank');
} else {
console.log("Unknown action in form", action);
}
}
handleContextClick(e) {
e.preventDefault();
e.stopPropagation();
@@ -376,11 +402,10 @@ class MessagesView extends React.Component {
const {formatMessage} = this.props.intl;
let component;
if (this.state.topic) {
const topic = this.props.tinode.getTopic(this.state.topic);
const groupTopic = topic.getType() == 'grp';
let messageNodes = [];
let topic = this.props.tinode.getTopic(this.state.topic);
let groupTopic = topic.getType() == 'grp';
let previousFrom = null;
let chatBoxClass = null;
for (let i=0; i<this.state.messages.length; i++) {
@@ -403,12 +428,12 @@ class MessagesView extends React.Component {
}
previousFrom = msg.from;
let isReply = !(msg.from == this.props.myUserId);
let deliveryStatus = topic.msgStatus(msg);
const isReply = !(msg.from == this.props.myUserId);
const deliveryStatus = topic.msgStatus(msg);
let userName, userAvatar, userFrom;
if (groupTopic) {
let user = topic.userDesc(msg.from);
const user = topic.userDesc(msg.from);
if (user && user.public) {
userName = user.public.fn;
userAvatar = makeImageUrl(user.public.photo);
@@ -430,6 +455,7 @@ class MessagesView extends React.Component {
viewportWidth={this.props.viewportWidth}
showContextMenu={this.handleShowContextMenuMessage}
onImagePreview={this.handleImagePreview}
onFormResponse={this.handleFormResponse}
onError={this.props.onError}
key={msg.seq} />
);
+1 -1
View File
@@ -77,7 +77,7 @@ class SidepanelView extends React.Component {
}
let onCancel;
if (view != 'login') {
if (['login', 'contacts'].indexOf(view) == -1) {
onCancel = this.props.onCancel;
}
+1
View File
@@ -1,6 +1,7 @@
import React from 'react';
import FileProgress from './file-progress.jsx';
import { bytesToHumanSize } from '../lib/strformat.js';
export default class Attachment extends React.Component {
constructor(props) {
+26 -1
View File
@@ -39,7 +39,22 @@ export default class ChatMessage extends React.Component {
handleFormButtonClick(e) {
e.preventDefault();
console.log(e.target);
const data = {
seq: this.props.seq
};
data.resp = {};
if (e.target.dataset.name) {
data.resp[e.target.dataset.name] = e.target.dataset.val ? e.target.dataset.val :
e.target.dataset.val === undefined ? 1 : '' + e.target.dataset.val;
}
if (e.target.dataset.act == 'url') {
data.ref = '' + e.target.dataset.ref;
}
if (e.target.dataset.formname) {
data.name = '' + e.target.dataset.formname;
}
const text = e.target.dataset.title || 'unknown';
this.props.onFormResponse(e.target.dataset.act, text, data);
}
handleContextClick(e) {
@@ -68,6 +83,11 @@ export default class ChatMessage extends React.Component {
const attachments = [];
if (this.props.mimeType == Drafty.getContentType()) {
Drafty.attachments(content, function(att, i) {
if (att.mime == 'application/json') {
// Don't show json objects as attachments.
// They are not meant for users.
return;
}
attachments.push(<Attachment
tinode={this.props.tinode}
downloadUrl={Drafty.getDownloadUrl(att)}
@@ -147,6 +167,11 @@ function draftyFormatter(style, data, values, key) {
case 'FM':
// Form
attr.className = 'bot-form' + ((data && data.layout) ? ' ' + data.layout : '');
// console.log(data, attr);
break;
case 'FE':
// Form element formatting is dependent on element content.
attr.className = data && data.dftp ? data.dftp : '';
break;
}
return React.createElement(el, attr, values);
+2 -3
View File
@@ -87,9 +87,8 @@ class ContactList extends React.Component {
{contactNodes}
</ul>
:
<div className="center-medium-text">
{this.props.emptyListMessage}
</div>}
<div className="center-medium-text" dangerouslySetInnerHTML={{__html: this.props.emptyListMessage}} />
}
</div>
);
}
+1 -1
View File
@@ -4,7 +4,7 @@ import { defineMessages, injectIntl } from 'react-intl';
import { Drafty } from 'tinode-sdk';
import { KEYPRESS_DELAY, MAX_EXTERN_ATTACHMENT_SIZE, MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE } from '../config.js';
import { SUPPORTED_IMAGE_FORMATS, filePasted, imageFileToBase64, imageFileScaledToBase64 } from '../lib/blob-helpers.js';
import { SUPPORTED_IMAGE_FORMATS, filePasted, fileToBase64, imageFileToBase64, imageFileScaledToBase64 } from '../lib/blob-helpers.js';
import { bytesToHumanSize } from '../lib/strformat.js';
const messages = defineMessages({
+87 -24
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long