Skip to content

feat: FBOT-512 add mobile attachment upload #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7,994 changes: 3,431 additions & 4,563 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@types/debounce": "^1.2.4",
"@types/google.analytics": "0.0.40",
"@types/html2canvas": "0.0.36",
"@types/qrcode": "^1.5.5",
"adaptivecards": "^1.1.0",
"bluebird": "^3.5.1",
"botframework-directlinejs": "0.9.15",
Expand All @@ -50,8 +51,10 @@
"jspeech": "^0.1.1",
"markdown-it": "8.3.1",
"microsoft-speech-browser-sdk": "0.0.12",
"qrcode": "^1.4.4",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-drop-zone": "^3.0.7",
"react-redux": "5.0.5",
"redux": "3.7.2",
"redux-observable": "0.13.0",
Expand Down
46 changes: 46 additions & 0 deletions patches/react-drop-zone+3.0.7.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
patch-package
--- a/node_modules/react-drop-zone/dist/DropZone.js
+++ b/node_modules/react-drop-zone/dist/DropZone.js
@@ -43,7 +43,7 @@ var events = {
Object.keys(events).forEach(function (event) {
document.addEventListener(event, function (ev) {
dropZones.forEach(function (zone) {
- return zone[events[event]](ev, true);
+ return zone[events[event]](ev, !ev.target || !ev.target.className || !ev.target.className.includes('DropZone'));
});
});
});
@@ -79,13 +79,13 @@ var DropZone = function (_Component) {

if (value === false && document) {
this.timeout = setTimeout(function () {
- return _this2.setState({ overDocument: false });
+ return !_this2.unmounted && _this2.setState({ overDocument: false });
}, 75);
} else if (value === true && document) {
this.timeout = clearTimeout(this.timeout);
- this.setState({ overDocument: true });
+ !this.unmounted && this.setState({ overDocument: true });
} else {
- this.setState({ over: value });
+ !this.unmounted && this.setState({ over: value });
}
}
}, {
@@ -112,6 +112,7 @@ var DropZone = function (_Component) {
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
+ this.unmounted = true
dropZones.push(this);
}
}, {
@@ -163,6 +164,8 @@ var DropZone = function (_Component) {
key: 'onDrop',
value: function onDrop(event, document) {
event.preventDefault();
+ event.stopPropagation();
+
this.setDragOver(false, document);
if (document) return;

Binary file added samples/.DS_Store
Binary file not shown.
6 changes: 3 additions & 3 deletions samples/feedyou/no-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
<!-- PUT THIS CODE RIGHT BEFORE THE </BODY> TAG (you can also use some tag manager like GTM) AND REPLACE ... WITH BOT ID -->
<!-- • design and behavior of webchat could be configured remotely from Feedyou Designer -->
<!-- • it is needed to append #feedbot-test-mode to the URL to show chatbot window during development -->
<link href="https://cdn.feedyou.ai/webchat/latest/botchat.css" rel="stylesheet" />
<link href="../../botchat.css" rel="stylesheet" />
<script type="text/javascript">
(function (f,y,b,o,t,s){(t = y.createElement(b)), (s = y.getElementsByTagName(b)[0]);t.async = 1;t.src = "https://cdn.feedyou.ai/webchat/latest/botchat-es5.js";t.onload=function(){BotChat.App({
bot: { id: "..." }, // try "feedbot-demo-webchat" during testing
(function (f,y,b,o,t,s){(t = y.createElement(b)), (s = y.getElementsByTagName(b)[0]);t.async = 1;t.src = "../../botchat-es5.js";t.onload=function(){BotChat.App({
bot: { id: "feedbot-msk-hr-recruitment-chat" }, // try "feedbot-demo-webchat" during testing
})};s.parentNode.insertBefore(t, s);})(window, document, "script");
</script>
<!-- --------------------------------------------------------------------------------------- -->
Expand Down
11 changes: 11 additions & 0 deletions src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type AppProps = ChatProps & {
enableScreenshotUpload?: boolean;
openUrlTarget: "new" | "same" | "same-domain";
persist?: "user" | "conversation" | "none";
fileUpload?: "button" | "dnd-and-mobile" | "mobile";
manualCloseExpireInMinutes?: number
};

Expand All @@ -27,6 +28,11 @@ export const App = async (props: AppProps, container?: HTMLElement) => {
...props.user
};

console.log(props)

props.uploadUsingQrCodeOnly = props.fileUpload === "mobile"
props.uploadUsingDndAndQrCode = props.fileUpload === "dnd-and-mobile"

// FEEDYOU fetch DL token from bot when no token or secret found
const remoteConfig =
props.bot &&
Expand Down Expand Up @@ -147,6 +153,11 @@ export const App = async (props: AppProps, container?: HTMLElement) => {
props.introDialog = {id: config.introDialogId}
}

if(config.fileUpload) {
props.uploadUsingQrCodeOnly = config.fileUpload === "mobile"
props.uploadUsingDndAndQrCode = config.fileUpload === "dnd-and-mobile"
}

if (config.userData) {
props.userData = config.userData.reduce(
(data: {[key: string]: any}, row: {storage: string, value: string}) => {
Expand Down
18 changes: 6 additions & 12 deletions src/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import * as React from 'react';
import { findDOMNode } from 'react-dom';

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';

import { Activity, IBotConnection, User, DirectLine, DirectLineOptions, CardActionTypes } from 'botframework-directlinejs';
import { createStore, ChatActions, sendMessage, typingDelay, HistoryAction, ChatStore } from './Store';
import { createStore, ChatActions, HistoryAction, ChatStore } from './Store';
import { Provider } from 'react-redux';
import { SpeechOptions } from './SpeechOptions';
import { Speech } from './SpeechModule';
Expand Down Expand Up @@ -35,15 +34,6 @@ interface GtmEvent {
variables?: Array<{name: string, value: string}>
}

interface SmartsuppHandoffOptions {
key: string
name?: string
email?: string
phone?: string
notification?: string
variables?: {[key: string]: string}
}

export interface ChatProps {
adaptiveCardsHostConfig: any,
chatTitle?: boolean | string,
Expand All @@ -57,6 +47,8 @@ export interface ChatProps {
selectedActivity?: BehaviorSubject<ActivityOrID>,
sendTyping?: boolean,
showUploadButton?: boolean,
uploadUsingQrCodeOnly?: boolean,
uploadUsingDndAndQrCode?: boolean,
uploadCapture?: 'image/*' | 'video/*' | 'audio/*',
disableInputWhenNotNeeded?: boolean,
formatOptions?: FormatOptions,
Expand All @@ -82,6 +74,7 @@ export class Chat extends React.Component<ChatProps, {}> {
private fbPixelEventsSubscription: Subscription;
private gaEventsSubscription: Subscription;
private gtmEventsSubscription: Subscription;
private botEventsSubscribtion: Subscription;
private handoffSubscription: Subscription;
private webchatCollapseSubscribtion: Subscription;
private redirectSubscribtion: Subscription;
Expand Down Expand Up @@ -148,7 +141,7 @@ export class Chat extends React.Component<ChatProps, {}> {
this.store.dispatch<ChatActions>({ type: 'Set_Chat_Title', chatTitle });
}

this.store.dispatch<ChatActions>({ type: 'Toggle_Upload_Button', showUploadButton: props.showUploadButton !== false });
this.store.dispatch<ChatActions>({ type: 'Toggle_Upload_Button', showUploadButton: props.showUploadButton !== false, uploadUsingQrCodeOnly: !!props.uploadUsingQrCodeOnly, uploadUsingDndAndQrCode: !!props.uploadUsingDndAndQrCode });

this.store.dispatch<ChatActions>({ type: 'Set_Upload_Capture', uploadCapture: props.uploadCapture });

Expand Down Expand Up @@ -516,6 +509,7 @@ export class Chat extends React.Component<ChatProps, {}> {
this.fbPixelEventsSubscription.unsubscribe();
this.gaEventsSubscription.unsubscribe();
this.gtmEventsSubscription.unsubscribe();
this.botEventsSubscribtion.unsubscribe();
// this.handoffSubscription.unsubscribe();
this.webchatCollapseSubscribtion.unsubscribe();
this.redirectSubscribtion.unsubscribe();
Expand Down
14 changes: 7 additions & 7 deletions src/MessagePane.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import * as React from 'react';
import { Activity, CardAction, User, Message } from 'botframework-directlinejs';
import { CardAction, Message } from 'botframework-directlinejs';
import { ChatState } from './Store';
import { connect } from 'react-redux';
import { HScroll } from './HScroll';
import { classList, doCardAction, IDoCardAction } from './Chat';
import * as konsole from './Konsole';
import { ChatActions, sendMessage } from './Store';
import { activityWithSuggestedActions } from './activityWithSuggestedActions';
import { twemoji } from './lib.js'

export interface MessagePaneProps {
activityWithSuggestedActions: Message,

showUploadButton: boolean,
doCardAction: IDoCardAction,
takeSuggestedAction: (message: Message) => any,

children: React.ReactNode,
doCardAction: IDoCardAction
}

const MessagePaneView = (props: MessagePaneProps) =>
<div className={ classList('wc-message-pane', props.activityWithSuggestedActions && 'show-actions' ) }>
<div className={ classList('wc-message-pane', props.activityWithSuggestedActions && 'show-actions', props.showUploadButton && 'has-upload-button' ) }>
{ props.children }
<div className="wc-suggested-actions">
<SuggestedActions { ... props }/>
Expand Down Expand Up @@ -74,14 +72,16 @@ export const MessagePane = connect(
// only used to create helper functions below
botConnection: state.connection.botConnection,
user: state.connection.user,
locale: state.format.locale
locale: state.format.locale,
showUploadButton:state.format.showUploadButton,
}), {
takeSuggestedAction: (message: Message) => ({ type: 'Take_SuggestedAction', message } as ChatActions),
// only used to create helper functions below
sendMessage
}, (stateProps: any, dispatchProps: any, ownProps: any): MessagePaneProps => ({
// from stateProps
activityWithSuggestedActions: stateProps.activityWithSuggestedActions,
showUploadButton: stateProps.showUploadButton,
// from dispatchProps
takeSuggestedAction: dispatchProps.takeSuggestedAction,
// from ownProps
Expand Down
Loading
Loading