2016-06-14 11:19:56 +00:00
|
|
|
var _status_catalog = {
|
2016-10-11 14:24:52 +00:00
|
|
|
commands: {},
|
2016-10-20 13:51:37 +00:00
|
|
|
responses: {},
|
2017-03-23 16:52:38 +00:00
|
|
|
functions: {},
|
|
|
|
subscriptions: {}
|
2016-10-11 14:24:52 +00:00
|
|
|
},
|
|
|
|
status = {};
|
2016-06-14 11:19:56 +00:00
|
|
|
|
2018-01-17 13:58:44 +00:00
|
|
|
// This is default 'common sense' scope for commands/response which don't
|
|
|
|
// define any.
|
|
|
|
// We want the command/response to apply for 1-1 chats with registered user,
|
|
|
|
// as most of the bot developers will expect the sole registered user (for
|
|
|
|
// things like sending, etc.) and it will be non global, available only
|
|
|
|
// for that particular bot (that's what "dapps" in scope)
|
|
|
|
var defaultScope = ["personal-chats", "registered", "dapps"];
|
|
|
|
|
2017-08-07 21:29:54 +00:00
|
|
|
function scopeToBitMask(scope) {
|
2017-11-04 12:59:19 +00:00
|
|
|
// this function transforms scopes array to a single integer by generating a bit mask
|
2018-01-17 13:58:44 +00:00
|
|
|
return ((scope.indexOf("global") > -1) ? 1 : 0) |
|
|
|
|
((scope.indexOf("personal-chats") > -1) ? 2 : 0) |
|
|
|
|
((scope.indexOf("group-chats") > -1) ? 4 : 0) |
|
|
|
|
((scope.indexOf("anonymous") > -1) ? 8 : 0) |
|
|
|
|
((scope.indexOf("registered") > -1) ? 16 : 0) |
|
|
|
|
((scope.indexOf("dapps") > -1) ? 32 : 0) |
|
|
|
|
((scope.indexOf("humans") > -1) ? 64 : 0) |
|
|
|
|
((scope.indexOf("public-chats") > -1) ? 128 : 0);
|
2017-08-07 21:29:54 +00:00
|
|
|
}
|
|
|
|
|
2016-06-14 11:19:56 +00:00
|
|
|
function Command() {
|
|
|
|
}
|
|
|
|
function Response() {
|
|
|
|
}
|
|
|
|
|
|
|
|
Command.prototype.addToCatalog = function () {
|
2017-11-04 12:59:19 +00:00
|
|
|
_status_catalog.commands[[this.name, this["scope-bitmask"]]] = this;
|
2016-06-14 11:19:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Command.prototype.param = function (parameter) {
|
|
|
|
this.params.push(parameter);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
Command.prototype.create = function (com) {
|
|
|
|
this.name = com.name;
|
2016-11-10 08:33:44 +00:00
|
|
|
this.title = com.title;
|
2016-06-14 11:19:56 +00:00
|
|
|
this.description = com.description;
|
|
|
|
this.handler = com.handler;
|
2017-08-07 21:29:54 +00:00
|
|
|
this["has-handler"] = com.handler !== null;
|
|
|
|
this["async-handler"] = (com.handler != null) && com.asyncHandler;
|
2016-07-07 16:09:16 +00:00
|
|
|
this.validator = com.validator;
|
2016-06-14 11:19:56 +00:00
|
|
|
this.color = com.color;
|
|
|
|
this.icon = com.icon;
|
|
|
|
this.params = com.params || [];
|
2016-06-14 14:36:39 +00:00
|
|
|
this.preview = com.preview;
|
2018-01-30 16:17:20 +00:00
|
|
|
this["short-preview"] = com.shortPreview;
|
2016-07-18 07:38:24 +00:00
|
|
|
this.fullscreen = com.fullscreen;
|
2017-04-29 11:08:49 +00:00
|
|
|
this.actions = com.actions;
|
2016-10-20 13:51:37 +00:00
|
|
|
this.request = com.request;
|
2017-03-07 17:29:59 +00:00
|
|
|
this["execute-immediately?"] = com.executeImmediately;
|
2017-04-06 22:09:55 +00:00
|
|
|
this["sequential-params"] = com.sequentialParams;
|
2017-07-10 10:29:58 +00:00
|
|
|
this["hide-send-button"] = com.hideSendButton;
|
2017-08-07 21:29:54 +00:00
|
|
|
|
|
|
|
// scopes
|
2018-01-17 13:58:44 +00:00
|
|
|
this.scope = com.scope || defaultScope;
|
2017-11-04 12:59:19 +00:00
|
|
|
this["scope-bitmask"] = scopeToBitMask(this["scope"]);
|
2017-08-07 21:29:54 +00:00
|
|
|
|
2016-06-14 11:19:56 +00:00
|
|
|
this.addToCatalog();
|
|
|
|
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Response.prototype = Object.create(Command.prototype);
|
|
|
|
Response.prototype.addToCatalog = function () {
|
2017-11-04 12:59:19 +00:00
|
|
|
_status_catalog.responses[[this.name, this["scope-bitmask"]]] = this;
|
2016-06-14 11:19:56 +00:00
|
|
|
};
|
|
|
|
Response.prototype.onReceiveResponse = function (handler) {
|
|
|
|
this.onReceive = handler;
|
|
|
|
};
|
|
|
|
|
2017-04-27 13:43:38 +00:00
|
|
|
var context = {};
|
2016-10-11 14:24:52 +00:00
|
|
|
|
2017-04-27 13:43:38 +00:00
|
|
|
|
|
|
|
function addContext(key, value) {
|
|
|
|
context[status.message_id][key] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getContext(key) {
|
|
|
|
return context[status.message_id][key];
|
2016-10-11 14:24:52 +00:00
|
|
|
}
|
|
|
|
|
2016-06-14 11:19:56 +00:00
|
|
|
function call(pathStr, paramsStr) {
|
|
|
|
var params = JSON.parse(paramsStr),
|
|
|
|
path = JSON.parse(pathStr),
|
2016-10-11 14:24:52 +00:00
|
|
|
fn, callResult, message_id;
|
|
|
|
|
|
|
|
if (typeof params.context !== "undefined" &&
|
|
|
|
typeof params.context["message-id"] !== "undefined") {
|
|
|
|
message_id = params.context["message-id"];
|
|
|
|
} else {
|
|
|
|
message_id = null;
|
|
|
|
}
|
|
|
|
context[message_id] = {};
|
|
|
|
status.message_id = message_id;
|
2016-06-14 11:19:56 +00:00
|
|
|
|
|
|
|
fn = path.reduce(function (catalog, name) {
|
|
|
|
if (catalog && catalog[name]) {
|
|
|
|
return catalog[name];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_status_catalog
|
|
|
|
);
|
|
|
|
|
2016-07-18 13:22:32 +00:00
|
|
|
if (!fn) {
|
2016-06-25 13:28:45 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-11-02 07:20:50 +00:00
|
|
|
context.messages = [];
|
|
|
|
|
2016-10-11 14:24:52 +00:00
|
|
|
callResult = fn(params.parameters, params.context);
|
|
|
|
result = {
|
|
|
|
returned: callResult,
|
2016-11-02 07:20:50 +00:00
|
|
|
context: context[message_id],
|
|
|
|
messages: context.messages
|
2016-10-11 14:24:52 +00:00
|
|
|
};
|
2016-06-14 11:19:56 +00:00
|
|
|
|
2016-10-11 14:24:52 +00:00
|
|
|
return JSON.stringify(result);
|
2016-06-14 11:19:56 +00:00
|
|
|
}
|
|
|
|
|
2017-06-27 21:26:46 +00:00
|
|
|
function view(options, elements) {
|
|
|
|
return ['view', options].concat(elements);
|
|
|
|
}
|
|
|
|
|
2016-06-14 12:56:03 +00:00
|
|
|
function text(options, s) {
|
2016-11-02 07:20:50 +00:00
|
|
|
s = Array.isArray(s) ? s : [s];
|
|
|
|
return ['text', options].concat(s);
|
2016-06-14 12:56:03 +00:00
|
|
|
}
|
|
|
|
|
2017-12-01 09:50:20 +00:00
|
|
|
function chatPreviewText(options, s) {
|
|
|
|
return ['chat-preview-text', options, s];
|
|
|
|
}
|
|
|
|
|
2017-06-27 21:26:46 +00:00
|
|
|
function textInput(options) {
|
|
|
|
return ['text-input', options];
|
|
|
|
}
|
|
|
|
|
|
|
|
function image(options) {
|
|
|
|
return ['image', options];
|
|
|
|
}
|
|
|
|
|
|
|
|
function qrCode(options) {
|
|
|
|
return ['qr-code', options];
|
|
|
|
}
|
|
|
|
|
|
|
|
function linking(options) {
|
|
|
|
return ['linking', options];
|
2016-06-14 12:56:03 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 16:52:38 +00:00
|
|
|
function slider(options) {
|
|
|
|
return ['slider', options];
|
|
|
|
}
|
|
|
|
|
2016-06-14 12:56:03 +00:00
|
|
|
function image(options) {
|
|
|
|
return ['image', options];
|
|
|
|
}
|
|
|
|
|
|
|
|
function touchable(options, element) {
|
|
|
|
return ['touchable', options, element];
|
|
|
|
}
|
|
|
|
|
2017-06-27 21:26:46 +00:00
|
|
|
function activityIndicator(options) {
|
|
|
|
return ['activity-indicator', options];
|
|
|
|
}
|
|
|
|
|
2016-06-14 12:56:03 +00:00
|
|
|
function scrollView(options, elements) {
|
|
|
|
return ['scroll-view', options].concat(elements);
|
|
|
|
}
|
|
|
|
|
2017-03-23 16:52:38 +00:00
|
|
|
function subscribe(path) {
|
|
|
|
return ['subscribe', path];
|
|
|
|
}
|
|
|
|
|
|
|
|
function dispatch(path) {
|
|
|
|
return ['dispatch', path];
|
|
|
|
}
|
|
|
|
|
2016-07-18 07:38:24 +00:00
|
|
|
function webView(url) {
|
|
|
|
return ['web-view', {
|
|
|
|
source: {
|
|
|
|
uri: url
|
|
|
|
},
|
|
|
|
javaScriptEnabled: true
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2017-03-12 11:20:56 +00:00
|
|
|
function bridgedWebView(url) {
|
|
|
|
return ['bridged-web-view', {
|
|
|
|
url: url
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2016-07-18 13:22:32 +00:00
|
|
|
function validationMessage(titleText, descriptionText) {
|
2017-03-12 11:20:56 +00:00
|
|
|
return ['validation-message', {
|
|
|
|
title: titleText,
|
|
|
|
description: descriptionText
|
|
|
|
}];
|
2016-07-18 13:22:32 +00:00
|
|
|
}
|
|
|
|
|
2017-05-10 16:42:52 +00:00
|
|
|
function chooseContact(titleText, botDbKey, argumentIndex) {
|
|
|
|
return ['choose-contact', {
|
|
|
|
title: titleText,
|
|
|
|
"bot-db-key": botDbKey,
|
|
|
|
index: argumentIndex
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2018-06-15 15:20:50 +00:00
|
|
|
function chooseAsset(botDbKey, argumentIndex) {
|
|
|
|
return ['choose-asset', {
|
|
|
|
"bot-db-key": botDbKey,
|
|
|
|
index: argumentIndex
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-10 10:29:58 +00:00
|
|
|
function separator() {
|
|
|
|
return ['separator'];
|
|
|
|
}
|
|
|
|
|
2016-06-14 11:19:56 +00:00
|
|
|
var status = {
|
2016-07-07 16:09:16 +00:00
|
|
|
command: function (h) {
|
2016-06-14 11:19:56 +00:00
|
|
|
var command = new Command();
|
2016-07-07 16:09:16 +00:00
|
|
|
return command.create(h);
|
2016-06-14 11:19:56 +00:00
|
|
|
},
|
2016-07-07 16:09:16 +00:00
|
|
|
response: function (h) {
|
2016-06-14 11:19:56 +00:00
|
|
|
var response = new Response();
|
2016-07-07 16:09:16 +00:00
|
|
|
return response.create(h);
|
2016-06-14 11:19:56 +00:00
|
|
|
},
|
2017-04-27 13:43:38 +00:00
|
|
|
addListener: function (name, fn) {
|
2016-10-20 13:51:37 +00:00
|
|
|
_status_catalog.functions[name] = fn;
|
|
|
|
},
|
2017-01-23 15:57:40 +00:00
|
|
|
localizeNumber: function (num, del, sep) {
|
|
|
|
return I18n.toNumber(
|
|
|
|
num.replace(",", "."),
|
2017-02-28 09:14:55 +00:00
|
|
|
{
|
|
|
|
precision: 10,
|
|
|
|
strip_insignificant_zeros: true,
|
|
|
|
delimiter: del,
|
|
|
|
separator: sep
|
|
|
|
});
|
2017-01-23 15:57:40 +00:00
|
|
|
},
|
2016-06-14 11:19:56 +00:00
|
|
|
types: {
|
2016-06-27 15:38:44 +00:00
|
|
|
TEXT: 'text',
|
|
|
|
NUMBER: 'number',
|
2016-06-14 11:19:56 +00:00
|
|
|
PASSWORD: 'password'
|
|
|
|
},
|
|
|
|
events: {
|
2017-03-12 11:20:56 +00:00
|
|
|
SET_VALUE: 'set-value',
|
2017-05-10 16:42:52 +00:00
|
|
|
SET_COMMAND_ARGUMENT: 'set-command-argument',
|
|
|
|
UPDATE_DB: 'set',
|
|
|
|
SET_COMMAND_ARGUMENT_FROM_DB: 'set-command-argument-from-db',
|
|
|
|
SET_VALUE_FROM_DB: 'set-value-from-db',
|
|
|
|
FOCUS_INPUT: 'focus-input'
|
2016-06-14 12:56:03 +00:00
|
|
|
},
|
2017-04-29 11:08:49 +00:00
|
|
|
actions: {
|
|
|
|
WEB_VIEW_BACK: 'web-view-back',
|
|
|
|
WEB_VIEW_FORWARD: 'web-view-forward',
|
|
|
|
FULLSCREEN: 'fullscreen',
|
|
|
|
CUSTOM: 'custom',
|
|
|
|
},
|
2016-06-14 12:56:03 +00:00
|
|
|
components: {
|
|
|
|
view: view,
|
|
|
|
text: text,
|
2017-12-01 09:50:20 +00:00
|
|
|
chatPreviewText: chatPreviewText,
|
2017-06-27 21:26:46 +00:00
|
|
|
textInput: textInput,
|
2017-05-10 16:42:52 +00:00
|
|
|
slider: slider,
|
2016-06-14 12:56:03 +00:00
|
|
|
image: image,
|
2017-06-27 21:26:46 +00:00
|
|
|
qrCode: qrCode,
|
|
|
|
linking: linking,
|
|
|
|
slider: slider,
|
2016-06-14 12:56:03 +00:00
|
|
|
touchable: touchable,
|
2017-06-27 21:26:46 +00:00
|
|
|
activityIndicator: activityIndicator,
|
2016-07-18 07:38:24 +00:00
|
|
|
scrollView: scrollView,
|
2016-07-18 13:22:32 +00:00
|
|
|
webView: webView,
|
2017-03-12 11:20:56 +00:00
|
|
|
validationMessage: validationMessage,
|
2017-03-23 16:52:38 +00:00
|
|
|
bridgedWebView: bridgedWebView,
|
2018-06-15 15:20:50 +00:00
|
|
|
chooseAsset: chooseAsset,
|
2017-05-10 16:42:52 +00:00
|
|
|
chooseContact: chooseContact,
|
2017-03-23 16:52:38 +00:00
|
|
|
subscribe: subscribe,
|
2017-07-10 10:29:58 +00:00
|
|
|
dispatch: dispatch,
|
|
|
|
separator: separator
|
2017-04-27 13:43:38 +00:00
|
|
|
},
|
2017-06-05 12:01:11 +00:00
|
|
|
showSuggestions: function (view) {
|
2017-09-12 11:46:07 +00:00
|
|
|
status.sendSignal("show-suggestions", view);
|
2017-04-27 13:43:38 +00:00
|
|
|
},
|
2017-03-23 16:52:38 +00:00
|
|
|
setDefaultDb: function (db) {
|
|
|
|
addContext("default-db", db);
|
|
|
|
},
|
|
|
|
updateDb: function (db) {
|
|
|
|
addContext("update-db", db)
|
|
|
|
},
|
2017-06-06 12:13:08 +00:00
|
|
|
sendMessage: function (message) {
|
|
|
|
if(typeof message !== "string") {
|
|
|
|
message = JSON.stringify(message);
|
|
|
|
}
|
2017-09-12 11:46:07 +00:00
|
|
|
status.sendSignal("send-message", message);
|
2017-04-27 13:43:38 +00:00
|
|
|
},
|
|
|
|
addLogMessage: function (type, message) {
|
|
|
|
var message = {
|
|
|
|
type: type,
|
|
|
|
message: JSON.stringify(message)
|
|
|
|
};
|
|
|
|
var logMessages = getContext("log-messages");
|
|
|
|
if (!logMessages) {
|
|
|
|
logMessages = [];
|
|
|
|
}
|
|
|
|
logMessages.push(message);
|
|
|
|
addContext("log-messages", logMessages);
|
2017-03-23 16:52:38 +00:00
|
|
|
},
|
|
|
|
defineSubscription: function (name, subscriptions, handler) {
|
|
|
|
_status_catalog.subscriptions[name] = {
|
|
|
|
subscriptions: subscriptions,
|
|
|
|
handler: handler
|
|
|
|
};
|
2017-09-12 11:46:07 +00:00
|
|
|
},
|
|
|
|
sendSignal: function (eventName, data) {
|
|
|
|
var event = {
|
|
|
|
event: eventName,
|
|
|
|
data: data
|
|
|
|
};
|
|
|
|
|
|
|
|
statusSignals.sendSignal(JSON.stringify(event));
|
2016-06-14 11:19:56 +00:00
|
|
|
}
|
|
|
|
};
|
2017-04-27 13:43:38 +00:00
|
|
|
|
2017-03-23 16:52:38 +00:00
|
|
|
function calculateSubscription(parameters, context) {
|
|
|
|
var subscriptionConfig = _status_catalog.subscriptions[parameters.name];
|
|
|
|
if (!subscriptionConfig) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return subscriptionConfig.handler(parameters.subscriptions);
|
|
|
|
}
|
|
|
|
|
|
|
|
status.addListener("subscription", calculateSubscription);
|
2017-04-27 13:43:38 +00:00
|
|
|
|
|
|
|
console = (function (old) {
|
|
|
|
return {
|
|
|
|
log: function (text) {
|
|
|
|
old.log(text);
|
|
|
|
status.addLogMessage('log', text);
|
|
|
|
},
|
|
|
|
debug: function (text) {
|
|
|
|
old.debug(text);
|
|
|
|
status.addLogMessage('debug', text);
|
|
|
|
},
|
|
|
|
info: function (text) {
|
|
|
|
old.info(text);
|
|
|
|
status.addLogMessage('info', text);
|
|
|
|
},
|
|
|
|
warn: function (text) {
|
|
|
|
old.warn(text);
|
|
|
|
status.addLogMessage('warn', text);
|
|
|
|
},
|
|
|
|
error: function (text) {
|
|
|
|
old.error(text);
|
|
|
|
status.addLogMessage('error', text);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}(console));
|
2017-06-05 10:50:34 +00:00
|
|
|
|
2017-09-12 11:46:07 +00:00
|
|
|
var localStorage = {};
|
|
|
|
|
2017-06-05 10:50:34 +00:00
|
|
|
localStorage.setItem = function(key, value) {
|
2017-06-05 12:01:11 +00:00
|
|
|
if(value === null) {
|
|
|
|
delete localStorageData[key];
|
|
|
|
} else {
|
|
|
|
localStorageData[key] = value;
|
|
|
|
}
|
|
|
|
|
2017-09-12 11:46:07 +00:00
|
|
|
status.sendSignal("local-storage", JSON.stringify(localStorageData));
|
2017-06-05 10:50:34 +00:00
|
|
|
};
|
|
|
|
|
2017-06-05 12:01:11 +00:00
|
|
|
localStorage.getItem = function (key) {
|
|
|
|
if (typeof localStorageData[key] === "undefined") {
|
|
|
|
return null;
|
|
|
|
}
|
2017-06-05 10:50:34 +00:00
|
|
|
return localStorageData[key];
|
|
|
|
};
|