Merge pull request #128 from status-im/feature/#123
Fetch/store commands.js
Former-commit-id: d00e6405c4
This commit is contained in:
commit
2daf477954
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "StatusIm",
|
"name": "StatusIm",
|
||||||
"interface": "reagent",
|
"interface": "reagent",
|
||||||
"androidHost": "localhost",
|
"androidHost": "10.0.3.2",
|
||||||
"modules": [
|
"modules": [
|
||||||
"react-native-contacts",
|
"react-native-contacts",
|
||||||
"react-native-invertible-scroll-view",
|
"react-native-invertible-scroll-view",
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
"dismissKeyboard",
|
"dismissKeyboard",
|
||||||
"react-native-linear-gradient",
|
"react-native-linear-gradient",
|
||||||
"react-native-android-sms-listener",
|
"react-native-android-sms-listener",
|
||||||
|
"react-native-status",
|
||||||
"react-native-camera",
|
"react-native-camera",
|
||||||
"react-native-qrcode",
|
"react-native-qrcode",
|
||||||
"react-native-orientation",
|
"react-native-orientation",
|
||||||
|
|
|
@ -131,9 +131,9 @@ dependencies {
|
||||||
compile project(':react-native-linear-gradient')
|
compile project(':react-native-linear-gradient')
|
||||||
compile project(':ReactNativeAndroidSmsListener')
|
compile project(':ReactNativeAndroidSmsListener')
|
||||||
compile project(':react-native-camera')
|
compile project(':react-native-camera')
|
||||||
|
compile project(':react-native-status')
|
||||||
compile project(':react-native-orientation')
|
compile project(':react-native-orientation')
|
||||||
// compile(name:'geth', ext:'aar')
|
compile(group: 'status-im', name: 'status-go', version: '0.1.0-201606231357-85abe1', ext: 'aar')
|
||||||
compile(group: 'status-im', name: 'android-geth', version: '1.4.0-201604110816-a97a114', ext: 'aar')
|
|
||||||
|
|
||||||
compile fileTree(dir: "node_modules/realm/android/libs", include: ["*.jar"])
|
compile fileTree(dir: "node_modules/realm/android/libs", include: ["*.jar"])
|
||||||
}
|
}
|
||||||
|
@ -143,3 +143,4 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
from configurations.compile
|
from configurations.compile
|
||||||
into 'libs'
|
into 'libs'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
@ -14,7 +13,7 @@ import android.os.Environment;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import com.github.ethereum.go_ethereum.cmd.Geth;
|
import com.github.status_im.status_go.Statusgo;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -78,20 +77,11 @@ public class GethService extends Service {
|
||||||
extStore.getAbsolutePath() :
|
extStore.getAbsolutePath() :
|
||||||
getApplicationInfo().dataDir;
|
getApplicationInfo().dataDir;
|
||||||
|
|
||||||
final Runnable addPeer = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
Log.w("Geth", "adding peer");
|
|
||||||
Geth.run("--exec admin.addPeer(\"enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:55555\") attach http://localhost:8545");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
Geth.run("--shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh,admin --fast --datadir=" + dataFolder);
|
Statusgo.doStartNode(dataFolder);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
handler.postDelayed(addPeer, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signalEvent(String jsonEvent) {
|
public void signalEvent(String jsonEvent) {
|
||||||
|
@ -107,8 +97,7 @@ public class GethService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
System.loadLibrary("gethraw");
|
System.loadLibrary("statusgo");
|
||||||
System.loadLibrary("geth");
|
|
||||||
|
|
||||||
if (!isGethInitialized) {
|
if (!isGethInitialized) {
|
||||||
isGethInitialized = true;
|
isGethInitialized = true;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import com.statusim.Jail.JailPackage;
|
||||||
|
|
||||||
import com.lwansbrough.RCTCamera.*;
|
import com.lwansbrough.RCTCamera.*;
|
||||||
import com.i18n.reactnativei18n.ReactNativeI18n;
|
import com.i18n.reactnativei18n.ReactNativeI18n;
|
||||||
|
@ -176,6 +177,7 @@ public class MainActivity extends ReactActivity {
|
||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
return Arrays.<ReactPackage>asList(
|
return Arrays.<ReactPackage>asList(
|
||||||
new MainReactPackage(),
|
new MainReactPackage(),
|
||||||
|
new JailPackage(),
|
||||||
new RealmReactPackage(),
|
new RealmReactPackage(),
|
||||||
new VectorIconsPackage(),
|
new VectorIconsPackage(),
|
||||||
new ReactNativeContacts(),
|
new ReactNativeContacts(),
|
||||||
|
|
|
@ -18,7 +18,11 @@ include ':react-native-linear-gradient'
|
||||||
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
||||||
include ':ReactNativeAndroidSmsListener'
|
include ':ReactNativeAndroidSmsListener'
|
||||||
project(':ReactNativeAndroidSmsListener').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-sms-listener/android')
|
project(':ReactNativeAndroidSmsListener').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-sms-listener/android')
|
||||||
|
|
||||||
|
include ':react-native-status'
|
||||||
|
project(':react-native-status').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-status/android')
|
||||||
include ':react-native-camera'
|
include ':react-native-camera'
|
||||||
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
|
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
|
||||||
|
|
||||||
include ':react-native-orientation', ':app'
|
include ':react-native-orientation', ':app'
|
||||||
project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
|
project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"react-native-randombytes": "^2.1.0",
|
"react-native-randombytes": "^2.1.0",
|
||||||
"react-native-vector-icons": "^1.3.4",
|
"react-native-vector-icons": "^1.3.4",
|
||||||
"react-native-orientation": "^1.17.0",
|
"react-native-orientation": "^1.17.0",
|
||||||
"realm": "^0.11.1"
|
"realm": "^0.11.1",
|
||||||
|
"react-native-status": "git+ssh://git@github.com/status-im/react-native-status"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
status.command({
|
||||||
|
name: "location",
|
||||||
|
description: "Send location",
|
||||||
|
color: "#9a5dcf"
|
||||||
|
}).param({
|
||||||
|
name: "address",
|
||||||
|
type: status.types.STRING
|
||||||
|
});
|
||||||
|
|
||||||
|
var phones = [
|
||||||
|
{
|
||||||
|
number: "89171111111",
|
||||||
|
description: "Number format 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: "89371111111",
|
||||||
|
description: "Number format 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: "+79171111111",
|
||||||
|
description: "Number format 2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: "9171111111",
|
||||||
|
description: "Number format 3"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function suggestionsContainerStyle(suggestionsCount) {
|
||||||
|
return {
|
||||||
|
marginVertical: 1,
|
||||||
|
marginHorizontal: 0,
|
||||||
|
height: Math.min(150, (56 * suggestionsCount)),
|
||||||
|
backgroundColor: "white",
|
||||||
|
borderRadius: 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var suggestionContainerStyle = {
|
||||||
|
paddingLeft: 16,
|
||||||
|
backgroundColor: "white"
|
||||||
|
};
|
||||||
|
|
||||||
|
var suggestionSubContainerStyle = {
|
||||||
|
height: 56,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: "#0000001f"
|
||||||
|
};
|
||||||
|
|
||||||
|
var valueStyle = {
|
||||||
|
marginTop: 9,
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: "font",
|
||||||
|
color: "#000000de"
|
||||||
|
};
|
||||||
|
|
||||||
|
var descriptionStyle = {
|
||||||
|
marginTop: 1.5,
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: "font",
|
||||||
|
color: "#838c93de"
|
||||||
|
};
|
||||||
|
|
||||||
|
function startsWith(str1, str2) {
|
||||||
|
// String.startsWith(...) doesn't work in otto
|
||||||
|
return str1.lastIndexOf(str2, 0) == 0 && str1 != str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function phoneSuggestions(params) {
|
||||||
|
var ph, suggestions;
|
||||||
|
if (!params.value || params.value == "") {
|
||||||
|
ph = phones;
|
||||||
|
} else {
|
||||||
|
ph = phones.filter(function (phone) {
|
||||||
|
return startsWith(phone.number, params.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ph.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suggestions = ph.map(function (phone) {
|
||||||
|
return status.components.touchable(
|
||||||
|
{onPress: [status.events.SET_VALUE, phone.number]},
|
||||||
|
status.components.view(suggestionContainerStyle,
|
||||||
|
[status.components.view(suggestionSubContainerStyle,
|
||||||
|
[
|
||||||
|
status.components.text(
|
||||||
|
{style: valueStyle},
|
||||||
|
phone.number
|
||||||
|
),
|
||||||
|
status.components.text(
|
||||||
|
{style: descriptionStyle},
|
||||||
|
phone.description
|
||||||
|
)
|
||||||
|
])])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return status.components.scrollView(
|
||||||
|
suggestionsContainerStyle(ph.length),
|
||||||
|
suggestions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
status.response({
|
||||||
|
name: "phone",
|
||||||
|
description: "Send phone number",
|
||||||
|
color: "#5fc48d",
|
||||||
|
params: [{
|
||||||
|
name: "phone",
|
||||||
|
type: status.types.PHONE_NUMBER,
|
||||||
|
suggestions: phoneSuggestions
|
||||||
|
}],
|
||||||
|
handler: function (params) {
|
||||||
|
return {
|
||||||
|
event: "sign-up",
|
||||||
|
params: [params.value]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
status.command({
|
||||||
|
name: "help",
|
||||||
|
description: "Help",
|
||||||
|
color: "#7099e6",
|
||||||
|
params: [{
|
||||||
|
name: "query",
|
||||||
|
type: status.types.STRING
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
status.response({
|
||||||
|
name: "confirmation-code",
|
||||||
|
color: "#7099e6",
|
||||||
|
description: "Confirmation code",
|
||||||
|
params: [{
|
||||||
|
name: "code",
|
||||||
|
type: status.types.NUMBER
|
||||||
|
}],
|
||||||
|
handler: function (params) {
|
||||||
|
return {
|
||||||
|
event: "confirm-sign-up",
|
||||||
|
params: [params.value]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
status.response({
|
||||||
|
name: "keypair",
|
||||||
|
color: "#7099e6",
|
||||||
|
description: "Keypair password",
|
||||||
|
icon: "icon_lock_white",
|
||||||
|
params: [{
|
||||||
|
name: "password",
|
||||||
|
type: status.types.PASSWORD
|
||||||
|
}],
|
||||||
|
handler: function (params) {
|
||||||
|
return {
|
||||||
|
event: "save-password",
|
||||||
|
params: [params.value]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
preview: function (params) {
|
||||||
|
return status.components.text(
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
marginTop: 5,
|
||||||
|
marginHorizontal: 0,
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: "font",
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}, "*****");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
var _status_catalog = {
|
||||||
|
commands: {},
|
||||||
|
responses: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Command() {
|
||||||
|
}
|
||||||
|
function Response() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Command.prototype.addToCatalog = function () {
|
||||||
|
_status_catalog.commands[this.name] = this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Command.prototype.param = function (parameter) {
|
||||||
|
this.params.push(parameter);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Command.prototype.create = function (com) {
|
||||||
|
this.name = com.name;
|
||||||
|
this.description = com.description;
|
||||||
|
this.handler = com.handler;
|
||||||
|
this.color = com.color;
|
||||||
|
this.icon = com.icon;
|
||||||
|
this.params = com.params || [];
|
||||||
|
this.preview = com.preview;
|
||||||
|
this.addToCatalog();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Response.prototype = Object.create(Command.prototype);
|
||||||
|
Response.prototype.addToCatalog = function () {
|
||||||
|
_status_catalog.responses[this.name] = this;
|
||||||
|
};
|
||||||
|
Response.prototype.onReceiveResponse = function (handler) {
|
||||||
|
this.onReceive = handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
function call(pathStr, paramsStr) {
|
||||||
|
var params = JSON.parse(paramsStr),
|
||||||
|
path = JSON.parse(pathStr),
|
||||||
|
fn, res;
|
||||||
|
|
||||||
|
fn = path.reduce(function (catalog, name) {
|
||||||
|
if (catalog && catalog[name]) {
|
||||||
|
return catalog[name];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_status_catalog
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!fn) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = fn(params);
|
||||||
|
|
||||||
|
return JSON.stringify(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function text(options, s) {
|
||||||
|
return ['text', options, s];
|
||||||
|
}
|
||||||
|
|
||||||
|
function view(options, elements) {
|
||||||
|
return ['view', options].concat(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
function image(options) {
|
||||||
|
return ['image', options];
|
||||||
|
}
|
||||||
|
|
||||||
|
function touchable(options, element) {
|
||||||
|
return ['touchable', options, element];
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollView(options, elements) {
|
||||||
|
return ['scroll-view', options].concat(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = {
|
||||||
|
command: function (n, d, h) {
|
||||||
|
var command = new Command();
|
||||||
|
return command.create(n, d, h);
|
||||||
|
},
|
||||||
|
response: function (n, d, h) {
|
||||||
|
var response = new Response();
|
||||||
|
return response.create(n, d, h);
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
STRING: 'string',
|
||||||
|
PHONE_NUMBER: 'phone-number',
|
||||||
|
PASSWORD: 'password'
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
SET_VALUE: 'set-value'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
view: view,
|
||||||
|
text: text,
|
||||||
|
image: image,
|
||||||
|
touchable: touchable,
|
||||||
|
scrollView: scrollView
|
||||||
|
}
|
||||||
|
};
|
|
@ -83,7 +83,6 @@
|
||||||
(dispatch [:load-user-phone-number])
|
(dispatch [:load-user-phone-number])
|
||||||
(dispatch [:load-contacts])
|
(dispatch [:load-contacts])
|
||||||
;; load commands from remote server (todo: uncomment)
|
;; load commands from remote server (todo: uncomment)
|
||||||
;; (dispatch [:load-commands])
|
|
||||||
(dispatch [:init-console-chat])
|
(dispatch [:init-console-chat])
|
||||||
(dispatch [:init-chat])
|
(dispatch [:init-chat])
|
||||||
(init-back-button-handler!)
|
(init-back-button-handler!)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
(ns status-im.chat.constants)
|
||||||
|
|
||||||
|
(def input-height 56)
|
||||||
|
(def request-info-height 61)
|
||||||
|
(def response-height-normal 211)
|
||||||
|
(def minimum-suggestion-height (+ input-height request-info-height))
|
|
@ -3,7 +3,6 @@
|
||||||
[status-im.models.commands :as commands]
|
[status-im.models.commands :as commands]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.components.styles :refer [default-chat-color]]
|
[status-im.components.styles :refer [default-chat-color]]
|
||||||
[status-im.chat.styles.response :refer [request-info-height response-height-normal]]
|
|
||||||
[status-im.chat.suggestions :as suggestions]
|
[status-im.chat.suggestions :as suggestions]
|
||||||
[status-im.protocol.api :as api]
|
[status-im.protocol.api :as api]
|
||||||
[status-im.models.messages :as messages]
|
[status-im.models.messages :as messages]
|
||||||
|
@ -19,8 +18,8 @@
|
||||||
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
||||||
[status-im.utils.phone-number :refer [format-phone-number]]
|
[status-im.utils.phone-number :refer [format-phone-number]]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
[status-im.chat.handlers.animation :refer [update-response-height
|
[status-im.components.jail :as j]
|
||||||
get-response-height]]))
|
[status-im.commands.utils :refer [generate-hiccup]]))
|
||||||
|
|
||||||
(register-handler :set-show-actions
|
(register-handler :set-show-actions
|
||||||
(fn [db [_ show-actions]]
|
(fn [db [_ show-actions]]
|
||||||
|
@ -44,35 +43,64 @@
|
||||||
(assoc-in [:chats current-chat-id :command-input] {})
|
(assoc-in [:chats current-chat-id :command-input] {})
|
||||||
(update-in [:chats current-chat-id :input-text] safe-trim))))
|
(update-in [:chats current-chat-id :input-text] safe-trim))))
|
||||||
|
|
||||||
|
(defn invoke-suggestions-handler!
|
||||||
|
[{:keys [current-chat-id] :as db} _]
|
||||||
|
(let [{:keys [command content]} (get-in db [:chats current-chat-id :command-input])
|
||||||
|
{:keys [name type]} command
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
name
|
||||||
|
:params
|
||||||
|
0
|
||||||
|
:suggestions]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call current-chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [:suggestions-handler {:command command
|
||||||
|
:content content
|
||||||
|
:chat-id current-chat-id} %]))))
|
||||||
|
|
||||||
(register-handler :start-cancel-command
|
(register-handler :start-cancel-command
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(dispatch [:animate-cancel-command]))))
|
(dispatch [:animate-cancel-command]))))
|
||||||
|
|
||||||
(register-handler :set-chat-command-content
|
(register-handler :set-chat-command-content
|
||||||
|
[(after invoke-suggestions-handler!)]
|
||||||
(fn [{:keys [current-chat-id] :as db} [_ content]]
|
(fn [{:keys [current-chat-id] :as db} [_ content]]
|
||||||
(as-> db db
|
(as-> db db
|
||||||
(commands/set-chat-command-content db content)
|
(commands/set-chat-command-content db content)
|
||||||
(assoc-in db [:chats current-chat-id :input-text] nil)
|
(assoc-in db [:chats current-chat-id :input-text] nil))))
|
||||||
(if (commands/get-chat-command-to-msg-id db)
|
|
||||||
(update-response-height db)
|
|
||||||
db))))
|
|
||||||
|
|
||||||
(defn update-input-text
|
(defn update-input-text
|
||||||
[{:keys [current-chat-id] :as db} text]
|
[{:keys [current-chat-id] :as db} text]
|
||||||
(assoc-in db [:chats current-chat-id :input-text] text))
|
(assoc-in db [:chats current-chat-id :input-text] text))
|
||||||
|
|
||||||
|
(defn invoke-command-preview!
|
||||||
|
[{:keys [current-chat-id staged-command]} _]
|
||||||
|
(let [{:keys [command content]} staged-command
|
||||||
|
{:keys [name type]} command
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
name
|
||||||
|
:preview]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call current-chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [:command-preview current-chat-id %]))))
|
||||||
|
|
||||||
(register-handler :stage-command
|
(register-handler :stage-command
|
||||||
|
(after invoke-command-preview!)
|
||||||
(fn [{:keys [current-chat-id] :as db} _]
|
(fn [{:keys [current-chat-id] :as db} _]
|
||||||
(let [db (update-input-text db nil)
|
(let [db (update-input-text db nil)
|
||||||
{:keys [command content]}
|
{:keys [command content]}
|
||||||
(get-in db [:chats current-chat-id :command-input])
|
(get-in db [:chats current-chat-id :command-input])
|
||||||
command-info {:command command
|
command-info {:command command
|
||||||
:content content
|
:content content}]
|
||||||
:handler (:handler command)}]
|
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:chats current-chat-id :command-input :command] nil)
|
;(assoc-in [:chats current-chat-id :command-input :command] nil)
|
||||||
(commands/stage-command command-info)))))
|
(commands/stage-command command-info)
|
||||||
|
(assoc :staged-command command-info)))))
|
||||||
|
|
||||||
(register-handler :set-message-input []
|
(register-handler :set-message-input []
|
||||||
(fn [db [_ input]]
|
(fn [db [_ input]]
|
||||||
|
@ -85,8 +113,10 @@
|
||||||
(.blur message-input)))))
|
(.blur message-input)))))
|
||||||
|
|
||||||
(register-handler :set-response-chat-command
|
(register-handler :set-response-chat-command
|
||||||
[(after #(dispatch [:command-edit-mode]))
|
[(after invoke-suggestions-handler!)
|
||||||
(after #(dispatch [:animate-show-response]))]
|
(after #(dispatch [:command-edit-mode]))
|
||||||
|
;(after #(dispatch [:animate-show-response]))
|
||||||
|
]
|
||||||
(fn [db [_ to-msg-id command-key]]
|
(fn [db [_ to-msg-id command-key]]
|
||||||
(commands/set-response-chat-command db to-msg-id command-key)))
|
(commands/set-response-chat-command db to-msg-id command-key)))
|
||||||
|
|
||||||
|
@ -143,8 +173,8 @@
|
||||||
|
|
||||||
(defn prepare-message
|
(defn prepare-message
|
||||||
[{:keys [identity current-chat-id] :as db} _]
|
[{:keys [identity current-chat-id] :as db} _]
|
||||||
(let [text (get-in db [:chats current-chat-id :input-text])
|
(let [text (get-in db [:chats current-chat-id :input-text])
|
||||||
{:keys [command]} (suggestions/check-suggestion db (str text " "))
|
[command] (suggestions/check-suggestion db (str text " "))
|
||||||
message (check-author-direction
|
message (check-author-direction
|
||||||
db current-chat-id
|
db current-chat-id
|
||||||
{:msg-id (random/id)
|
{:msg-id (random/id)
|
||||||
|
@ -159,17 +189,18 @@
|
||||||
(commands/set-chat-command db command)
|
(commands/set-chat-command db command)
|
||||||
(assoc db :new-message (when-not (str/blank? text) message)))))
|
(assoc db :new-message (when-not (str/blank? text) message)))))
|
||||||
|
|
||||||
(defn prepare-command [identity chat-id staged-command]
|
(defn prepare-command
|
||||||
(let [command-key (get-in staged-command [:command :command])
|
[identity chat-id {:keys [preview preview-string content command]}]
|
||||||
content {:command (name command-key)
|
(let [content {:command (command :name)
|
||||||
:content (:content staged-command)}]
|
:content content}]
|
||||||
{:msg-id (random/id)
|
{:msg-id (random/id)
|
||||||
:from identity
|
:from identity
|
||||||
:to chat-id
|
:to chat-id
|
||||||
:content content
|
:content content
|
||||||
:content-type content-type-command
|
:content-type content-type-command
|
||||||
:outgoing true
|
:outgoing true
|
||||||
:handler (:handler staged-command)}))
|
:preview preview-string
|
||||||
|
:rendered-preview preview}))
|
||||||
|
|
||||||
(defn prepare-staged-commans
|
(defn prepare-staged-commans
|
||||||
[{:keys [current-chat-id identity] :as db} _]
|
[{:keys [current-chat-id identity] :as db} _]
|
||||||
|
@ -222,7 +253,22 @@
|
||||||
(defn save-commands-to-realm!
|
(defn save-commands-to-realm!
|
||||||
[{:keys [new-commands current-chat-id]} _]
|
[{:keys [new-commands current-chat-id]} _]
|
||||||
(doseq [new-command new-commands]
|
(doseq [new-command new-commands]
|
||||||
(messages/save-message current-chat-id (dissoc new-command :handler))))
|
(messages/save-message current-chat-id
|
||||||
|
(dissoc new-command :rendered-preview))))
|
||||||
|
|
||||||
|
(defn invoke-commands-handlers!
|
||||||
|
[{:keys [new-commands current-chat-id]}]
|
||||||
|
(doseq [{:keys [content] :as com} new-commands]
|
||||||
|
(let [{:keys [command content]} content
|
||||||
|
type (:type command)
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
command
|
||||||
|
:handler]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call current-chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [:command-handler! com %])))))
|
||||||
|
|
||||||
(defn handle-commands
|
(defn handle-commands
|
||||||
[{:keys [new-commands]}]
|
[{:keys [new-commands]}]
|
||||||
|
@ -241,6 +287,8 @@
|
||||||
((after send-message!))
|
((after send-message!))
|
||||||
((after save-message-to-realm!))
|
((after save-message-to-realm!))
|
||||||
((after save-commands-to-realm!))
|
((after save-commands-to-realm!))
|
||||||
|
;; todo maybe it is better to track if it was handled or not
|
||||||
|
((after invoke-commands-handlers!))
|
||||||
((after handle-commands))))
|
((after handle-commands))))
|
||||||
|
|
||||||
(register-handler :unstage-command
|
(register-handler :unstage-command
|
||||||
|
@ -249,7 +297,8 @@
|
||||||
|
|
||||||
(register-handler :set-chat-command
|
(register-handler :set-chat-command
|
||||||
[(after #(dispatch [:command-edit-mode]))
|
[(after #(dispatch [:command-edit-mode]))
|
||||||
(after #(dispatch [:animate-show-response]))]
|
;(after #(dispatch [:animate-show-response]))
|
||||||
|
]
|
||||||
(fn [db [_ command-key]]
|
(fn [db [_ command-key]]
|
||||||
(commands/set-chat-command db command-key)))
|
(commands/set-chat-command db command-key)))
|
||||||
|
|
||||||
|
@ -294,9 +343,14 @@
|
||||||
([{:keys [messages current-chat-id] :as db} _]
|
([{:keys [messages current-chat-id] :as db} _]
|
||||||
(assoc-in db [:chats current-chat-id :messages] messages)))
|
(assoc-in db [:chats current-chat-id :messages] messages)))
|
||||||
|
|
||||||
|
(defn load-commands!
|
||||||
|
[{:keys [current-chat-id]}]
|
||||||
|
(dispatch [:load-commands! current-chat-id]))
|
||||||
|
|
||||||
(register-handler :init-chat
|
(register-handler :init-chat
|
||||||
(-> load-messages!
|
(-> load-messages!
|
||||||
((enrich init-chat))
|
((enrich init-chat))
|
||||||
|
((after load-commands!))
|
||||||
debug))
|
debug))
|
||||||
|
|
||||||
(defn initialize-chats
|
(defn initialize-chats
|
||||||
|
@ -340,9 +394,9 @@
|
||||||
|
|
||||||
(defmethod nav/preload-data! :chat
|
(defmethod nav/preload-data! :chat
|
||||||
[{:keys [current-chat-id] :as db} [_ _ id]]
|
[{:keys [current-chat-id] :as db} [_ _ id]]
|
||||||
(let [chat-id (or id current-chat-id)
|
(let [chat-id (or id current-chat-id)
|
||||||
messages (get-in db [:chats chat-id :messages])
|
messages (get-in db [:chats chat-id :messages])
|
||||||
db' (assoc db :current-chat-id chat-id)]
|
db' (assoc db :current-chat-id chat-id)]
|
||||||
(if (seq messages)
|
(if (seq messages)
|
||||||
db'
|
db'
|
||||||
(-> db'
|
(-> db'
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
(ns status-im.chat.handlers.animation
|
(ns status-im.chat.handlers.animation
|
||||||
(:require [re-frame.core :refer [register-handler after dispatch]]
|
(:require [re-frame.core :refer [register-handler after dispatch debug]]
|
||||||
[re-frame.middleware :refer [path]]
|
[re-frame.middleware :refer [path]]
|
||||||
[status-im.models.commands :as commands]
|
|
||||||
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
||||||
[status-im.chat.styles.message-input :refer [input-height]]
|
[status-im.chat.constants :refer [input-height request-info-height
|
||||||
[status-im.chat.styles.response :refer [request-info-height response-height-normal]]
|
response-height-normal minimum-suggestion-height]]
|
||||||
[status-im.chat.styles.response-suggestions :as response-suggestions-styles]
|
|
||||||
[status-im.constants :refer [response-input-hiding-duration]]))
|
[status-im.constants :refer [response-input-hiding-duration]]))
|
||||||
|
|
||||||
(def zero-height input-height)
|
;; todo magic value
|
||||||
|
(def middle-height 270)
|
||||||
|
|
||||||
(defn animation-handler
|
(defn animation-handler
|
||||||
([name handler] (animation-handler name nil handler))
|
([name handler] (animation-handler name nil handler))
|
||||||
|
@ -19,25 +18,21 @@
|
||||||
(after #(dispatch [:text-edit-mode]))
|
(after #(dispatch [:text-edit-mode]))
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(assoc db
|
(assoc db
|
||||||
:to-response-height zero-height
|
:to-response-height input-height
|
||||||
:messages-offset 0)))
|
:messages-offset 0)))
|
||||||
|
|
||||||
(defn get-response-height [db]
|
(defn get-response-height
|
||||||
(let [command (commands/get-chat-command db)
|
[{:keys [current-chat-id] :as db}]
|
||||||
text (commands/get-chat-command-content db)
|
(let [suggestions (get-in db [:suggestions current-chat-id])
|
||||||
suggestions (get-content-suggestions command text)
|
suggestions-height (if suggestions middle-height 0)]
|
||||||
suggestions-height (reduce + 0 (map #(if (:header %)
|
(+ input-height
|
||||||
response-suggestions-styles/header-height
|
|
||||||
response-suggestions-styles/suggestion-height)
|
|
||||||
suggestions))]
|
|
||||||
(+ zero-height
|
|
||||||
(min response-height-normal (+ suggestions-height request-info-height)))))
|
(min response-height-normal (+ suggestions-height request-info-height)))))
|
||||||
|
|
||||||
(defn update-response-height [db]
|
(defn update-response-height [db]
|
||||||
(assoc-in db [:animations :to-response-height] (get-response-height db)))
|
(assoc-in db [:animations :to-response-height] (get-response-height db)))
|
||||||
|
|
||||||
(register-handler :animate-show-response
|
(register-handler :animate-show-response
|
||||||
(after #(dispatch [:command-edit-mode]))
|
[(after #(dispatch [:command-edit-mode]))]
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:animations :messages-offset] request-info-height)
|
(assoc-in [:animations :messages-offset] request-info-height)
|
||||||
|
@ -54,26 +49,28 @@
|
||||||
db))))
|
db))))
|
||||||
|
|
||||||
(register-handler :fix-response-height
|
(register-handler :fix-response-height
|
||||||
(fn [db [_ vy current]]
|
(fn [{:keys [current-chat-id] :as db} [_ vy current]]
|
||||||
(let [max-height (get-in db [:animations :response-height-max])
|
(let [max-height (get-in db [:animations :response-height-max])
|
||||||
;; todo magic value
|
|
||||||
middle 270
|
|
||||||
moving-down? (pos? vy)
|
moving-down? (pos? vy)
|
||||||
moving-up? (not moving-down?)
|
moving-up? (not moving-down?)
|
||||||
under-middle-position? (<= current middle)
|
under-middle-position? (<= current middle-height)
|
||||||
over-middle-position? (not under-middle-position?)
|
over-middle-position? (not under-middle-position?)
|
||||||
min-height (+ zero-height request-info-height)
|
suggestions (get-in db [:suggestions current-chat-id])
|
||||||
new-fixed (cond (and under-middle-position? moving-down?)
|
new-fixed (cond (not suggestions)
|
||||||
min-height
|
minimum-suggestion-height
|
||||||
|
|
||||||
(and under-middle-position? moving-up?)
|
(and under-middle-position? moving-up?)
|
||||||
middle
|
middle-height
|
||||||
|
|
||||||
(and over-middle-position? moving-down?)
|
(and over-middle-position? moving-down?)
|
||||||
middle
|
middle-height
|
||||||
|
|
||||||
(and over-middle-position? moving-up?)
|
(and over-middle-position? moving-up?)
|
||||||
max-height)]
|
max-height
|
||||||
|
|
||||||
|
(and under-middle-position?
|
||||||
|
moving-down?)
|
||||||
|
minimum-suggestion-height)]
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:animations :to-response-height] new-fixed)
|
(assoc-in [:animations :to-response-height] new-fixed)
|
||||||
(update-in [:animations :response-height-changed] inc)))))
|
(update-in [:animations :response-height-changed] inc)))))
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
[status-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
[status-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
||||||
[status-im.components.toolbar :refer [toolbar]]
|
[status-im.components.toolbar :refer [toolbar]]
|
||||||
[status-im.chat.views.message :refer [chat-message]]
|
[status-im.chat.views.message :refer [chat-message]]
|
||||||
[status-im.chat.views.content-suggestions :refer [content-suggestions-view]]
|
|
||||||
[status-im.chat.views.suggestions :refer [suggestions-view]]
|
[status-im.chat.views.suggestions :refer [suggestions-view]]
|
||||||
[status-im.chat.views.response :refer [response-view]]
|
[status-im.chat.views.response :refer [response-view]]
|
||||||
[status-im.chat.views.new-message :refer [chat-message-new]]
|
[status-im.chat.views.new-message :refer [chat-message-new]]
|
||||||
|
|
|
@ -173,7 +173,7 @@
|
||||||
(dispatch [:received-msg
|
(dispatch [:received-msg
|
||||||
{:msg-id msg-id
|
{:msg-id msg-id
|
||||||
:content (command-content
|
:content (command-content
|
||||||
:keypair-password
|
:keypair
|
||||||
(label :t/keypair-generated))
|
(label :t/keypair-generated))
|
||||||
:content-type content-type-command-request
|
:content-type content-type-command-request
|
||||||
:outgoing false
|
:outgoing false
|
||||||
|
@ -184,6 +184,9 @@
|
||||||
(def console-chat
|
(def console-chat
|
||||||
{:chat-id "console"
|
{:chat-id "console"
|
||||||
:name "console"
|
:name "console"
|
||||||
|
; todo remove/change dapp config fot console
|
||||||
|
:dapp-url "http://localhost:8185/resources"
|
||||||
|
:dapp-hash 858845357
|
||||||
:color default-chat-color
|
:color default-chat-color
|
||||||
:group-chat false
|
:group-chat false
|
||||||
:is-active true
|
:is-active true
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
(ns status-im.chat.styles.content-suggestions
|
(ns status-im.chat.styles.content-suggestions
|
||||||
(:require [status-im.components.styles :refer [font
|
(:require [status-im.components.styles :refer [font
|
||||||
color-light-blue-transparent
|
color-light-blue-transparent
|
||||||
color-white
|
color-white
|
||||||
color-black
|
color-black
|
||||||
color-blue
|
color-blue
|
||||||
color-blue-transparent
|
color-blue-transparent
|
||||||
selected-message-color
|
selected-message-color
|
||||||
online-color
|
online-color
|
||||||
separator-color
|
separator-color
|
||||||
text1-color
|
text1-color
|
||||||
text2-color
|
text2-color
|
||||||
text3-color]]))
|
text3-color]]))
|
||||||
|
|
||||||
(def suggestion-height 56)
|
(def suggestion-height 56)
|
||||||
|
|
||||||
(def suggestion-container
|
(def suggestion-container
|
||||||
{:flexDirection :column
|
{:paddingLeft 16
|
||||||
:paddingLeft 16
|
|
||||||
:backgroundColor color-white})
|
:backgroundColor color-white})
|
||||||
|
|
||||||
(def suggestion-sub-container
|
(def suggestion-sub-container
|
||||||
|
@ -37,7 +36,7 @@
|
||||||
:color text2-color})
|
:color text2-color})
|
||||||
|
|
||||||
(defn suggestions-container [suggestions-count]
|
(defn suggestions-container [suggestions-count]
|
||||||
{:flexDirection :row
|
{:flex 1
|
||||||
:marginVertical 1
|
:marginVertical 1
|
||||||
:marginHorizontal 0
|
:marginHorizontal 0
|
||||||
:height (min 150 (* suggestion-height suggestions-count))
|
:height (min 150 (* suggestion-height suggestions-count))
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
(ns status-im.chat.styles.message
|
(ns status-im.chat.styles.message
|
||||||
(:require [status-im.components.styles :refer [font
|
(:require [status-im.components.styles :refer [font
|
||||||
color-light-blue-transparent
|
color-light-blue-transparent
|
||||||
color-white
|
color-white
|
||||||
color-black
|
color-black
|
||||||
color-blue
|
color-blue
|
||||||
selected-message-color
|
selected-message-color
|
||||||
online-color
|
online-color
|
||||||
text1-color
|
text1-color
|
||||||
text2-color]]
|
text2-color]]
|
||||||
[status-im.constants :refer [text-content-type
|
[status-im.constants :refer [text-content-type
|
||||||
content-type-command]]))
|
content-type-command]]))
|
||||||
|
|
||||||
(def style-message-text
|
(def style-message-text
|
||||||
{:fontSize 14
|
{:fontSize 14
|
||||||
|
@ -153,6 +153,14 @@
|
||||||
:backgroundColor (:color command)
|
:backgroundColor (:color command)
|
||||||
:transform [{:scale scale}]})
|
:transform [{:scale scale}]})
|
||||||
|
|
||||||
|
(def command-image-view
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:right 0
|
||||||
|
:width 24
|
||||||
|
:height 24
|
||||||
|
:alignItems :center})
|
||||||
|
|
||||||
(def command-request-image
|
(def command-request-image
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
:top 9
|
:top 9
|
||||||
|
@ -185,11 +193,10 @@
|
||||||
:color color-white})
|
:color color-white})
|
||||||
|
|
||||||
(def command-image
|
(def command-image
|
||||||
{:position :absolute
|
{:margin-top 5
|
||||||
:top 4
|
:width 12
|
||||||
:right 0
|
:height 13
|
||||||
:width 12
|
:tint-color :#a9a9a9cc})
|
||||||
:height 13})
|
|
||||||
|
|
||||||
(def command-text
|
(def command-text
|
||||||
(merge style-message-text
|
(merge style-message-text
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
(ns status-im.chat.styles.message-input
|
(ns status-im.chat.styles.message-input
|
||||||
(:require [status-im.components.styles :refer [color-white
|
(:require [status-im.components.styles :refer [color-white
|
||||||
color-blue]]))
|
color-blue]]
|
||||||
|
[status-im.chat.constants :refer [input-height]]))
|
||||||
(def input-height 56)
|
|
||||||
|
|
||||||
(def message-input-container
|
(def message-input-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
|
|
@ -6,10 +6,8 @@
|
||||||
text2-color
|
text2-color
|
||||||
chat-background
|
chat-background
|
||||||
color-black]]
|
color-black]]
|
||||||
[status-im.chat.styles.message-input :refer [input-height]]))
|
[status-im.chat.constants :refer [input-height request-info-height
|
||||||
|
response-height-normal]]))
|
||||||
(def response-height-normal 211)
|
|
||||||
(def request-info-height 61)
|
|
||||||
|
|
||||||
(def drag-container
|
(def drag-container
|
||||||
{:height 16
|
{:height 16
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
(ns status-im.chat.styles.response-suggestions
|
|
||||||
(:require [status-im.components.styles :refer [font
|
|
||||||
font-medium
|
|
||||||
color-light-blue-transparent
|
|
||||||
color-white
|
|
||||||
color-black
|
|
||||||
color-blue
|
|
||||||
color-blue-transparent
|
|
||||||
selected-message-color
|
|
||||||
online-color
|
|
||||||
separator-color
|
|
||||||
text1-color
|
|
||||||
text2-color
|
|
||||||
text3-color]]))
|
|
||||||
|
|
||||||
(def header-height 50)
|
|
||||||
(def suggestion-height 56)
|
|
||||||
|
|
||||||
(def header-container
|
|
||||||
{:paddingLeft 16
|
|
||||||
:height header-height
|
|
||||||
:backgroundColor color-white})
|
|
||||||
|
|
||||||
(def header-text
|
|
||||||
{:marginTop 18
|
|
||||||
:fontSize 13
|
|
||||||
:fontFamily font-medium
|
|
||||||
:color text2-color})
|
|
||||||
|
|
||||||
(def suggestion-container
|
|
||||||
{:flexDirection :column
|
|
||||||
:paddingLeft 16
|
|
||||||
:height suggestion-height
|
|
||||||
:backgroundColor color-white})
|
|
||||||
|
|
||||||
(def suggestion-sub-container
|
|
||||||
{:height suggestion-height
|
|
||||||
:borderBottomWidth 1
|
|
||||||
:borderBottomColor separator-color})
|
|
||||||
|
|
||||||
(def value-text
|
|
||||||
{:marginTop 10
|
|
||||||
:fontSize 12
|
|
||||||
:fontFamily font
|
|
||||||
:color text1-color})
|
|
||||||
|
|
||||||
(def description-text
|
|
||||||
{:marginTop 2
|
|
||||||
:fontSize 12
|
|
||||||
:fontFamily font
|
|
||||||
:color text2-color})
|
|
||||||
|
|
||||||
(def suggestions-container
|
|
||||||
{:flexDirection :row
|
|
||||||
:flex 1
|
|
||||||
:marginVertical 1
|
|
||||||
:marginHorizontal 0
|
|
||||||
:backgroundColor color-white
|
|
||||||
:borderRadius 5})
|
|
|
@ -1,15 +1,15 @@
|
||||||
(ns status-im.chat.subs
|
(ns status-im.chat.subs
|
||||||
(:require-macros [reagent.ratom :refer [reaction]])
|
(:require-macros [reagent.ratom :refer [reaction]])
|
||||||
(:require [re-frame.core :refer [register-sub dispatch subscribe]]
|
(:require [re-frame.core :refer [register-sub dispatch subscribe path]]
|
||||||
[status-im.db :as db]
|
[status-im.db :as db]
|
||||||
;todo handlers in subs?...
|
|
||||||
[status-im.chat.suggestions :refer
|
[status-im.chat.suggestions :refer
|
||||||
[get-suggestions typing-command?]]
|
[get-suggestions typing-command?]]
|
||||||
[status-im.models.commands :as commands]
|
[status-im.models.commands :as commands]
|
||||||
[status-im.constants :refer [response-suggesstion-resize-duration]]
|
[status-im.constants :refer [response-suggesstion-resize-duration]]
|
||||||
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
||||||
[status-im.chat.views.plain-message :as plain-message]
|
[status-im.chat.views.plain-message :as plain-message]
|
||||||
[status-im.chat.views.command :as command]))
|
[status-im.chat.views.command :as command]
|
||||||
|
[status-im.chat.constants :as c]))
|
||||||
|
|
||||||
(register-sub :chat-properties
|
(register-sub :chat-properties
|
||||||
(fn [db [_ properties]]
|
(fn [db [_ properties]]
|
||||||
|
@ -53,6 +53,18 @@
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(reaction (commands/get-commands @db))))
|
(reaction (commands/get-commands @db))))
|
||||||
|
|
||||||
|
(register-sub :get-responses
|
||||||
|
(fn [db _]
|
||||||
|
(let [current-chat (@db :current-chat-id)]
|
||||||
|
(reaction (or (get-in @db [:chats current-chat :responses]) {})))))
|
||||||
|
|
||||||
|
(register-sub :get-commands-and-responses
|
||||||
|
(fn [db _]
|
||||||
|
(let [current-chat (@db :current-chat-id)]
|
||||||
|
(reaction _ (or (->> (get-in @db [:chats current-chat])
|
||||||
|
((juxt :commands :responses))
|
||||||
|
(apply merge)) {})))))
|
||||||
|
|
||||||
(register-sub :get-chat-input-text
|
(register-sub :get-chat-input-text
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(->> [:chats (:current-chat-id @db) :input-text]
|
(->> [:chats (:current-chat-id @db) :input-text]
|
||||||
|
@ -108,12 +120,10 @@
|
||||||
|
|
||||||
(register-sub :get-content-suggestions
|
(register-sub :get-content-suggestions
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(let [command (reaction (commands/get-chat-command @db))
|
(reaction (get-in @db [:suggestions (:current-chat-id @db)]))))
|
||||||
text (reaction (commands/get-chat-command-content @db))]
|
|
||||||
(reaction (get-content-suggestions @command @text)))))
|
|
||||||
|
|
||||||
(register-sub :command?
|
(register-sub :command?
|
||||||
(fn [db ]
|
(fn [db]
|
||||||
(->> (get-in @db [:edit-mode (:current-chat-id @db)])
|
(->> (get-in @db [:edit-mode (:current-chat-id @db)])
|
||||||
(= :command)
|
(= :command)
|
||||||
(reaction))))
|
(reaction))))
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
(ns status-im.chat.suggestions
|
(ns status-im.chat.suggestions
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
[status-im.db :as db]
|
[status-im.db :as db]
|
||||||
[status-im.models.commands :refer [commands
|
[status-im.models.commands :refer [get-commands
|
||||||
suggestions
|
get-chat-command-request
|
||||||
get-commands
|
get-chat-command-to-msg-id
|
||||||
get-chat-command-request
|
clear-staged-commands]]
|
||||||
get-chat-command-to-msg-id
|
|
||||||
clear-staged-commands]]
|
|
||||||
[status-im.utils.utils :refer [log on-error http-get]]
|
[status-im.utils.utils :refer [log on-error http-get]]
|
||||||
[clojure.string :as s]))
|
[clojure.string :as s]))
|
||||||
|
|
||||||
(defn suggestion? [text]
|
(defn suggestion? [text]
|
||||||
(= (get text 0) "!"))
|
(= (get text 0) "!"))
|
||||||
|
|
||||||
(defn get-suggestions [db text]
|
(defn can-be-suggested? [text]
|
||||||
(if (suggestion? text)
|
(fn [{:keys [name]}]
|
||||||
;; TODO change 'commands' to 'suggestions'
|
(.startsWith (str "!" name) text)))
|
||||||
(filterv #(.startsWith (:text %) text) (get-commands db))
|
|
||||||
[]))
|
(defn get-suggestions
|
||||||
|
[{:keys [current-chat-id] :as db} text]
|
||||||
|
(let [commands (get-in db [:chats current-chat-id :commands])]
|
||||||
|
(if (suggestion? text)
|
||||||
|
(filter (fn [[_ v]] ((can-be-suggested? text) v)) commands)
|
||||||
|
[])))
|
||||||
|
|
||||||
(defn get-command [db text]
|
(defn get-command [db text]
|
||||||
(when (suggestion? text)
|
(when (suggestion? text)
|
||||||
|
@ -45,22 +48,13 @@
|
||||||
staged-commands))
|
staged-commands))
|
||||||
(clear-staged-commands db)))
|
(clear-staged-commands db)))
|
||||||
|
|
||||||
(defn execute-commands-js [body]
|
|
||||||
(.eval js/window body)
|
|
||||||
(let [commands (.-commands js/window)]
|
|
||||||
(dispatch [:set-commands (map #(update % :command keyword)
|
|
||||||
(js->clj commands :keywordize-keys true))])))
|
|
||||||
|
|
||||||
(defn load-commands []
|
|
||||||
(http-get "chat-commands.js" execute-commands-js nil))
|
|
||||||
|
|
||||||
(defn check-suggestion [db message]
|
(defn check-suggestion [db message]
|
||||||
(when-let [suggestion-text (when (string? message)
|
(when-let [suggestion-text (when (string? message)
|
||||||
(re-matches #"^![^\s]+\s" message))]
|
(re-matches #"^![^\s]+\s" message))]
|
||||||
(let [suggestion-text' (s/trim suggestion-text)
|
(let [suggestion-text' (s/trim suggestion-text)]
|
||||||
[suggestion] (filter #(= suggestion-text' (:text %))
|
(->> (get-commands db)
|
||||||
(get-commands db))]
|
(filter #(= suggestion-text' (->> % second :name (str "!"))))
|
||||||
suggestion)))
|
first))))
|
||||||
|
|
||||||
(defn typing-command? [db]
|
(defn typing-command? [db]
|
||||||
(-> db
|
(-> db
|
||||||
|
|
|
@ -35,3 +35,4 @@
|
||||||
[touchable-highlight {:on-press cancel-command-input}
|
[touchable-highlight {:on-press cancel-command-input}
|
||||||
[view st/cancel-container
|
[view st/cancel-container
|
||||||
[icon :close-gray st/cancel-icon]]])
|
[icon :close-gray st/cancel-icon]]])
|
||||||
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
(ns status-im.chat.views.content-suggestions
|
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
|
||||||
[status-im.components.react :refer [view
|
|
||||||
icon
|
|
||||||
text
|
|
||||||
touchable-highlight
|
|
||||||
list-view
|
|
||||||
list-item]]
|
|
||||||
[status-im.chat.styles.content-suggestions :as st]
|
|
||||||
[status-im.utils.listview :refer [to-datasource]]))
|
|
||||||
|
|
||||||
(defn set-command-content [content]
|
|
||||||
(dispatch [:set-chat-command-content content]))
|
|
||||||
|
|
||||||
(defn suggestion-list-item [{:keys [value description]}]
|
|
||||||
[touchable-highlight {:onPress #(set-command-content value)}
|
|
||||||
[view st/suggestion-container
|
|
||||||
[view st/suggestion-sub-container
|
|
||||||
[text {:style st/value-text} value]
|
|
||||||
[text {:style st/description-text} description]]]])
|
|
||||||
|
|
||||||
(defn render-row [row _ _]
|
|
||||||
(list-item [suggestion-list-item row]))
|
|
||||||
|
|
||||||
(defview content-suggestions-view []
|
|
||||||
[suggestions [:get-content-suggestions]]
|
|
||||||
(when-let [values (not-empty (filter :value suggestions))]
|
|
||||||
[view st/container
|
|
||||||
[touchable-highlight {:style st/drag-down-touchable
|
|
||||||
;; TODO hide suggestions?
|
|
||||||
:onPress (fn [])}
|
|
||||||
[view [icon :drag_down st/drag-down-icon]]]
|
|
||||||
[view (st/suggestions-container (count values))
|
|
||||||
[list-view {:dataSource (to-datasource values)
|
|
||||||
:keyboardShouldPersistTaps true
|
|
||||||
:renderRow render-row}]]]))
|
|
|
@ -1,11 +1,12 @@
|
||||||
(ns status-im.chat.views.message
|
(ns status-im.chat.views.message
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [clojure.string :as s]
|
(:require [clojure.string :as s]
|
||||||
[re-frame.core :refer [subscribe dispatch]]
|
[re-frame.core :refer [subscribe dispatch]]
|
||||||
[reagent.core :as r]
|
[reagent.core :as r]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
animated-view
|
|
||||||
text
|
text
|
||||||
image
|
image
|
||||||
|
animated-view
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.components.animation :as anim]
|
[status-im.components.animation :as anim]
|
||||||
[status-im.chat.views.request-message :refer [message-content-command-request]]
|
[status-im.chat.views.request-message :refer [message-content-command-request]]
|
||||||
|
@ -55,24 +56,48 @@
|
||||||
[view st/track-mark]
|
[view st/track-mark]
|
||||||
[text {:style st/track-duration-text} "03:39"]]])
|
[text {:style st/track-duration-text} "03:39"]]])
|
||||||
|
|
||||||
(defn message-content-command [content]
|
(defview message-content-command [content preview]
|
||||||
(let [commands-atom (subscribe [:get-commands])]
|
[commands [:get-commands-and-responses]]
|
||||||
(fn [content]
|
(let [{:keys [command content]} (parse-command-msg-content commands content)
|
||||||
(let [commands @commands-atom
|
{:keys [name icon type]} command]
|
||||||
{:keys [command content]}
|
[view st/content-command-view
|
||||||
(parse-command-msg-content commands content)]
|
[view st/command-container
|
||||||
[view st/content-command-view
|
[view (st/command-view command)
|
||||||
[view st/command-container
|
[text {:style st/command-name}
|
||||||
[view (st/command-view command)
|
(str (if (= :command type) "!" "") name)]]]
|
||||||
[text {:style st/command-name}
|
(when icon
|
||||||
(:text command)]]]
|
[view st/command-image-view
|
||||||
[image {:source (:icon command)
|
[image {:source {:uri icon}
|
||||||
:style st/command-image}]
|
:style st/command-image}]])
|
||||||
[text {:style st/command-text}
|
(if preview
|
||||||
;; TODO isn't smart
|
preview
|
||||||
(if (= (:command command) :keypair-password)
|
[text {:style st/command-text} content])]))
|
||||||
"******"
|
|
||||||
content)]]))))
|
(defn set-chat-command [msg-id command]
|
||||||
|
(dispatch [:set-response-chat-command msg-id (keyword (:name command))]))
|
||||||
|
|
||||||
|
(defn label [{:keys [command]}]
|
||||||
|
(->> (when command (name command))
|
||||||
|
(str "request-")))
|
||||||
|
|
||||||
|
;; todo remove (merging leftover)
|
||||||
|
#_(defview message-content-command-request
|
||||||
|
[{:keys [msg-id content from incoming-group]}]
|
||||||
|
[commands [:get-responses]]
|
||||||
|
(let [{:keys [command content]} (parse-command-request commands content)]
|
||||||
|
[touchable-highlight {:onPress #(set-chat-command msg-id command)
|
||||||
|
:accessibility-label (label command)}
|
||||||
|
[view st/comand-request-view
|
||||||
|
[view st/command-request-message-view
|
||||||
|
(when incoming-group
|
||||||
|
[text {:style st/command-request-from-text} from])
|
||||||
|
[text {:style st/style-message-text} content]]
|
||||||
|
[view (st/command-request-image-view command)
|
||||||
|
[image {:source {:uri (:icon command)}
|
||||||
|
:style st/command-request-image}]]
|
||||||
|
(when-let [request-text (:request-text command)]
|
||||||
|
[view st/command-request-text-view
|
||||||
|
[text {:style st/style-sub-text} request-text]])]]))
|
||||||
|
|
||||||
(defn message-view
|
(defn message-view
|
||||||
[message content]
|
[message content]
|
||||||
|
@ -103,9 +128,9 @@
|
||||||
[message-content-status message])
|
[message-content-status message])
|
||||||
|
|
||||||
(defmethod message-content content-type-command
|
(defmethod message-content content-type-command
|
||||||
[wrapper {:keys [content] :as message}]
|
[wrapper {:keys [content rendered-preview] :as message}]
|
||||||
[wrapper message
|
[wrapper message
|
||||||
[message-view message [message-content-command content]]])
|
[message-view message [message-content-command content rendered-preview]]])
|
||||||
|
|
||||||
(defmethod message-content :default
|
(defmethod message-content :default
|
||||||
[wrapper {:keys [content-type content] :as message}]
|
[wrapper {:keys [content-type content] :as message}]
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
icon
|
icon
|
||||||
touchable-highlight
|
touchable-highlight
|
||||||
text-input]]
|
text-input]]
|
||||||
[status-im.components.animation :as anim]
|
|
||||||
[status-im.chat.views.plain-message :as plain-message]
|
[status-im.chat.views.plain-message :as plain-message]
|
||||||
[status-im.chat.views.command :as command]
|
[status-im.chat.views.command :as command]
|
||||||
[status-im.chat.styles.message-input :as st]
|
[status-im.chat.styles.message-input :as st]
|
||||||
|
|
|
@ -24,11 +24,12 @@
|
||||||
(case (:command command)
|
(case (:command command)
|
||||||
:phone {:input-options {:keyboardType :phone-pad}
|
:phone {:input-options {:keyboardType :phone-pad}
|
||||||
:validator valid-mobile-number?}
|
:validator valid-mobile-number?}
|
||||||
:keypair-password {:input-options {:secureTextEntry true}}
|
:keypair {:input-options {:secureTextEntry true}}
|
||||||
:confirmation-code {:input-options {:keyboardType :numeric}}
|
:confirmation-code {:input-options {:keyboardType :numeric}}
|
||||||
:money {:input-options {:keyboardType :numeric}}
|
:money {:input-options {:keyboardType :numeric}}
|
||||||
:request {:input-options {:keyboardType :numeric}}
|
:request {:input-options {:keyboardType :numeric}}
|
||||||
(throw (js/Error. "Uknown command type"))))])
|
;; todo maybe nil is finr for now :)
|
||||||
|
nil #_(throw (js/Error. "Uknown command type"))))])
|
||||||
|
|
||||||
(defview chat-message-new []
|
(defview chat-message-new []
|
||||||
[staged-commands [:get-chat-staged-commands]]
|
[staged-commands [:get-chat-staged-commands]]
|
||||||
|
|
|
@ -24,15 +24,16 @@
|
||||||
(defn button-animation-logic [{:keys [command? val]}]
|
(defn button-animation-logic [{:keys [command? val]}]
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [to-scale (if @command? 0 1)]
|
(let [to-scale (if @command? 0 1)]
|
||||||
(anim/start (anim/spring val {:toValue to-scale})))))
|
(anim/start (anim/spring val {:toValue to-scale
|
||||||
|
:tension 30})))))
|
||||||
|
|
||||||
(defn list-container [min]
|
(defn list-container [min]
|
||||||
(fn [{:keys [command? width]}]
|
(fn [{:keys [command? width]}]
|
||||||
(let [n-width (if @command? min 56)
|
(let [n-width (if @command? min 56)
|
||||||
delay (if @command? 100 0)]
|
delay (if @command? 100 0)]
|
||||||
(anim/start (anim/timing width {:toValue n-width
|
(anim/start (anim/timing width {:toValue n-width
|
||||||
:duration response-input-hiding-duration
|
:duration response-input-hiding-duration
|
||||||
:delay delay})))))
|
:delay delay})))))
|
||||||
|
|
||||||
(defn commands-button []
|
(defn commands-button []
|
||||||
(let [command? (subscribe [:command?])
|
(let [command? (subscribe [:command?])
|
||||||
|
@ -62,19 +63,20 @@
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [to-scale (if @command? 0 1)]
|
(let [to-scale (if @command? 0 1)]
|
||||||
(when-not @command? (anim/set-value width 56))
|
(when-not @command? (anim/set-value width 56))
|
||||||
(anim/start (anim/spring val {:toValue to-scale})
|
(anim/start (anim/spring val {:toValue to-scale
|
||||||
|
:tension 30})
|
||||||
(fn [e]
|
(fn [e]
|
||||||
(when (and @command? (.-finished e))
|
(when (and @command? (.-finished e))
|
||||||
(anim/set-value width 0.1)))))))
|
(anim/set-value width 0.1)))))))
|
||||||
|
|
||||||
(defn smile-button []
|
(defn smile-button []
|
||||||
(let [command? (subscribe [:command?])
|
(let [command? (subscribe [:command?])
|
||||||
buttons-scale (anim/create-value (if @command? 1 0))
|
buttons-scale (anim/create-value (if @command? 1 0))
|
||||||
container-width (anim/create-value (if @command? 0.1 56))
|
container-width (anim/create-value (if @command? 0.1 56))
|
||||||
context {:command? command?
|
context {:command? command?
|
||||||
:val buttons-scale
|
:val buttons-scale
|
||||||
:width container-width}
|
:width container-width}
|
||||||
on-update (smile-animation-logic context)]
|
on-update (smile-animation-logic context)]
|
||||||
(r/create-class
|
(r/create-class
|
||||||
{:component-did-mount
|
{:component-did-mount
|
||||||
on-update
|
on-update
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
(def request-message-icon-scale-delay 600)
|
(def request-message-icon-scale-delay 600)
|
||||||
|
|
||||||
(defn set-chat-command [msg-id command]
|
(defn set-chat-command [msg-id command]
|
||||||
(dispatch [:set-response-chat-command msg-id (:command command)]))
|
(dispatch [:set-response-chat-command msg-id (keyword (:name command))]))
|
||||||
|
|
||||||
(defn label [{:keys [command]}]
|
(defn label [{:keys [command]}]
|
||||||
(->> (name command)
|
(->> (name command)
|
||||||
|
@ -56,18 +56,19 @@
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn [msg-id command]
|
(fn [msg-id command]
|
||||||
@to-scale
|
@to-scale
|
||||||
[touchable-highlight {:on-press (fn []
|
[touchable-highlight {:on-press (fn []
|
||||||
(reset! loop? false)
|
(reset! loop? false)
|
||||||
(set-chat-command msg-id command))
|
(set-chat-command msg-id command))
|
||||||
:style st/command-request-image-touchable
|
:style st/command-request-image-touchable}
|
||||||
:accessibility-label (label command)}
|
;:accessibility-label (label command)
|
||||||
|
|
||||||
[animated-view {:style (st/command-request-image-view command scale-anim-val)}
|
[animated-view {:style (st/command-request-image-view command scale-anim-val)}
|
||||||
[image {:source (:request-icon command)
|
[image {:source {:uri (:icon command)}
|
||||||
:style st/command-request-image}]]])})))
|
:style st/command-request-image}]]])})))
|
||||||
|
|
||||||
(defn message-content-command-request
|
(defn message-content-command-request
|
||||||
[{:keys [msg-id content from incoming-group]}]
|
[{:keys [msg-id content from incoming-group]}]
|
||||||
(let [commands-atom (subscribe [:get-commands])]
|
(let [commands-atom (subscribe [:get-responses])]
|
||||||
(fn [{:keys [msg-id content from incoming-group]}]
|
(fn [{:keys [msg-id content from incoming-group]}]
|
||||||
(let [commands @commands-atom
|
(let [commands @commands-atom
|
||||||
{:keys [command content]} (parse-command-request commands content)]
|
{:keys [command content]} (parse-command-request commands content)]
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
text-input
|
text-input
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.components.drag-drop :as drag]
|
[status-im.components.drag-drop :as drag]
|
||||||
[status-im.chat.views.response-suggestions :refer [response-suggestions-view]]
|
|
||||||
[status-im.chat.styles.response :as st]
|
[status-im.chat.styles.response :as st]
|
||||||
[status-im.chat.styles.message-input :refer [input-height]]
|
|
||||||
[status-im.components.animation :as anim]
|
[status-im.components.animation :as anim]
|
||||||
[status-im.components.react :as react]))
|
[status-im.components.react :as react]))
|
||||||
|
|
||||||
|
@ -51,7 +49,6 @@
|
||||||
;; todo maybe it is better to use margin-top instead height
|
;; todo maybe it is better to use margin-top instead height
|
||||||
;; it is not obvious
|
;; it is not obvious
|
||||||
to-value (- (prop w) @kb-height (.-moveY gesture))]
|
to-value (- (prop w) @kb-height (.-moveY gesture))]
|
||||||
(println to-value )
|
|
||||||
(anim/start
|
(anim/start
|
||||||
(anim/spring response-height {:toValue to-value}))))))
|
(anim/spring response-height {:toValue to-value}))))))
|
||||||
|
|
||||||
|
@ -88,7 +85,9 @@
|
||||||
(defn container-animation-logic [{:keys [to-value val]}]
|
(defn container-animation-logic [{:keys [to-value val]}]
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [to-value @to-value]
|
(let [to-value @to-value]
|
||||||
(anim/start (anim/spring val {:toValue to-value})))))
|
(anim/start (anim/spring val {:toValue to-value
|
||||||
|
:tension 50
|
||||||
|
:friction 10})))))
|
||||||
|
|
||||||
(defn container [response-height & children]
|
(defn container [response-height & children]
|
||||||
(let [;; todo to-response-height, cur-response-height must be specific
|
(let [;; todo to-response-height, cur-response-height must be specific
|
||||||
|
@ -109,9 +108,18 @@
|
||||||
(into [animated-view {:style (st/response-view response-height)}]
|
(into [animated-view {:style (st/response-view response-height)}]
|
||||||
children))})))
|
children))})))
|
||||||
|
|
||||||
|
(defview placeholder []
|
||||||
|
[suggestions [:get-content-suggestions]]
|
||||||
|
(when (seq suggestions)
|
||||||
|
[view st/input-placeholder]))
|
||||||
|
|
||||||
|
(defview response-suggestions-view []
|
||||||
|
[suggestions [:get-content-suggestions]]
|
||||||
|
(when (seq suggestions) suggestions))
|
||||||
|
|
||||||
(defn response-view []
|
(defn response-view []
|
||||||
(let [response-height (anim/create-value 0)]
|
(let [response-height (anim/create-value 0)]
|
||||||
[container response-height
|
[container response-height
|
||||||
[request-info response-height]
|
[request-info response-height]
|
||||||
[response-suggestions-view]
|
[response-suggestions-view]
|
||||||
[view st/input-placeholder]]))
|
[placeholder]]))
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
(ns status-im.chat.views.response-suggestions
|
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
|
||||||
[status-im.components.react :refer [view
|
|
||||||
icon
|
|
||||||
text
|
|
||||||
touchable-highlight
|
|
||||||
list-view
|
|
||||||
list-item]]
|
|
||||||
[status-im.chat.styles.response-suggestions :as st]
|
|
||||||
[status-im.utils.listview :refer [to-datasource]]))
|
|
||||||
|
|
||||||
(defn set-command-content [content]
|
|
||||||
(dispatch [:set-chat-command-content content]))
|
|
||||||
|
|
||||||
(defn header-list-item [{:keys [header]}]
|
|
||||||
[view st/header-container
|
|
||||||
[text {:style st/header-text} header]])
|
|
||||||
|
|
||||||
(defn suggestion-list-item [{:keys [value description]}]
|
|
||||||
[touchable-highlight {:onPress #(set-command-content value)}
|
|
||||||
[view st/suggestion-container
|
|
||||||
[view st/suggestion-sub-container
|
|
||||||
[text {:style st/value-text} value]
|
|
||||||
[text {:style st/description-text} description]]]])
|
|
||||||
|
|
||||||
(defn render-row [row _ _]
|
|
||||||
(list-item (if (:header row)
|
|
||||||
[header-list-item row]
|
|
||||||
[suggestion-list-item row])))
|
|
||||||
|
|
||||||
(defview response-suggestions-view []
|
|
||||||
[suggestions [:get-content-suggestions]]
|
|
||||||
(when (seq suggestions)
|
|
||||||
[view st/suggestions-container
|
|
||||||
[list-view {:dataSource (to-datasource suggestions)
|
|
||||||
:keyboardShouldPersistTaps true
|
|
||||||
:renderRow render-row}]]))
|
|
|
@ -1,9 +1,9 @@
|
||||||
(ns status-im.chat.views.staged-command
|
(ns status-im.chat.views.staged-command
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
image
|
image
|
||||||
text
|
text
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.resources :as res]
|
[status-im.resources :as res]
|
||||||
[status-im.chat.styles.input :as st]))
|
[status-im.chat.styles.input :as st]))
|
||||||
|
|
||||||
|
@ -16,13 +16,12 @@
|
||||||
[view st/staged-command-background
|
[view st/staged-command-background
|
||||||
[view st/staged-command-info-container
|
[view st/staged-command-info-container
|
||||||
[view (st/staged-command-text-container command)
|
[view (st/staged-command-text-container command)
|
||||||
[text {:style st/staged-command-text} (:text command)]]
|
[text {:style st/staged-command-text} (str "!" (:name command))]]
|
||||||
[touchable-highlight {:style st/staged-command-cancel
|
[touchable-highlight {:style st/staged-command-cancel
|
||||||
:onPress #(cancel-command-input staged-command)}
|
:onPress #(cancel-command-input staged-command)}
|
||||||
[image {:source res/icon-close-gray
|
[image {:source res/icon-close-gray
|
||||||
:style st/staged-command-cancel-icon}]]]
|
:style st/staged-command-cancel-icon}]]]
|
||||||
[text {:style st/staged-command-content}
|
(if-let [preview (:preview staged-command)]
|
||||||
;; TODO isn't smart
|
preview
|
||||||
(if (= (:command command) :keypair-password)
|
[text {:style st/staged-command-content}
|
||||||
"******"
|
(:content staged-command)])]]))
|
||||||
(:content staged-command))]]]))
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
(ns status-im.chat.views.suggestions
|
(ns status-im.chat.views.suggestions
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
text
|
text
|
||||||
|
@ -13,35 +14,35 @@
|
||||||
(dispatch [:set-chat-command command]))
|
(dispatch [:set-chat-command command]))
|
||||||
|
|
||||||
(defn suggestion-list-item
|
(defn suggestion-list-item
|
||||||
[{:keys [description command]
|
[[command {:keys [description]
|
||||||
label :text
|
name :name
|
||||||
:as suggestion}]
|
:as suggestion}]]
|
||||||
[touchable-highlight
|
(let [label (str "!" name)]
|
||||||
{:onPress #(set-command-input (keyword command))}
|
[touchable-highlight
|
||||||
[view st/suggestion-container
|
{:onPress #(set-command-input command)}
|
||||||
[view st/suggestion-sub-container
|
[view st/suggestion-container
|
||||||
[view (st/suggestion-background suggestion)
|
[view st/suggestion-sub-container
|
||||||
[text {:style st/suggestion-text} label]]
|
[view (st/suggestion-background suggestion)
|
||||||
[text {:style st/value-text} label]
|
[text {:style st/suggestion-text} label]]
|
||||||
[text {:style st/description-text} description]]]])
|
[text {:style st/value-text} label]
|
||||||
|
[text {:style st/description-text} description]]]]))
|
||||||
|
|
||||||
(defn render-row [row _ _]
|
(defn render-row [row _ _]
|
||||||
(list-item [suggestion-list-item row]))
|
(list-item [suggestion-list-item row]))
|
||||||
|
|
||||||
(defn suggestions-view []
|
|
||||||
(let [suggestions-atom (subscribe [:get-suggestions])]
|
(defview suggestions-view []
|
||||||
(fn []
|
[suggestions [:get-suggestions]]
|
||||||
(let [suggestions @suggestions-atom]
|
(when (seq suggestions)
|
||||||
(when (seq suggestions)
|
[view st/container
|
||||||
[view st/container
|
[touchable-highlight {:style st/drag-down-touchable
|
||||||
[touchable-highlight {:style st/drag-down-touchable
|
:onPress (fn []
|
||||||
:onPress (fn []
|
;; TODO hide suggestions?
|
||||||
;; TODO hide suggestions?
|
)}
|
||||||
)}
|
[view
|
||||||
[view
|
[icon :drag_down st/drag-down-icon]]]
|
||||||
[icon :drag_down st/drag-down-icon]]]
|
[view (st/suggestions-container (count suggestions))
|
||||||
[view (st/suggestions-container (count suggestions))
|
[list-view {:dataSource (to-datasource suggestions)
|
||||||
[list-view {:dataSource (to-datasource suggestions)
|
:enableEmptySections true
|
||||||
:enableEmptySections true
|
:keyboardShouldPersistTaps true
|
||||||
:keyboardShouldPersistTaps true
|
:renderRow render-row}]]]))
|
||||||
:renderRow render-row}]]])))))
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
(ns status-im.commands.handlers.jail
|
||||||
|
(:require [re-frame.core :refer [register-handler after dispatch subscribe
|
||||||
|
trim-v debug]]
|
||||||
|
[status-im.utils.handlers :as u]
|
||||||
|
[status-im.utils.utils :refer [http-get toast]]
|
||||||
|
[status-im.components.jail :as j]
|
||||||
|
[status-im.utils.types :refer [json->clj]]
|
||||||
|
[status-im.commands.utils :refer [generate-hiccup reg-handler]]
|
||||||
|
[clojure.string :as s]))
|
||||||
|
|
||||||
|
(defn init-render-command!
|
||||||
|
[_ [chat-id command message-id data]]
|
||||||
|
(j/call chat-id [command :render] data
|
||||||
|
#(dispatch [::render-command chat-id message-id %])))
|
||||||
|
|
||||||
|
(defn render-command
|
||||||
|
[db [chat-id message-id markup]]
|
||||||
|
(let [hiccup (generate-hiccup markup)]
|
||||||
|
(assoc-in db [:rendered-commands chat-id message-id] hiccup)))
|
||||||
|
|
||||||
|
(def console-events
|
||||||
|
{:save-password #(dispatch [:save-password %])
|
||||||
|
:sign-up #(dispatch [:sign-up %])
|
||||||
|
:confirm-sign-up #(dispatch [:sign-up-confirm %])})
|
||||||
|
|
||||||
|
(def regular-events {})
|
||||||
|
|
||||||
|
(defn command-hadler!
|
||||||
|
[_ [{:keys [to]} {:keys [result]} ]]
|
||||||
|
(when result
|
||||||
|
(let [{:keys [event params]} result
|
||||||
|
events (if (= "console" to)
|
||||||
|
(merge regular-events console-events)
|
||||||
|
regular-events)]
|
||||||
|
(when-let [handler (events (keyword event))]
|
||||||
|
(apply handler params)))))
|
||||||
|
|
||||||
|
(defn suggestions-handler!
|
||||||
|
[db [{:keys [chat-id]} {:keys [result]} ]]
|
||||||
|
(assoc-in db [:suggestions chat-id] (generate-hiccup result)))
|
||||||
|
|
||||||
|
(defn suggestions-events-handler!
|
||||||
|
[db [[n data]]]
|
||||||
|
(case (keyword n)
|
||||||
|
:set-value (dispatch [:set-chat-command-content data])
|
||||||
|
;; todo show error?
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defn command-preview
|
||||||
|
[db [chat-id {:keys [result]}]]
|
||||||
|
(if result
|
||||||
|
(let [path [:chats chat-id :staged-commands]
|
||||||
|
commands-cnt (count (get-in db path))]
|
||||||
|
;; todo (dec commands-cnt) looks like hack have to find better way to
|
||||||
|
;; do this
|
||||||
|
(update-in db (conj path (dec commands-cnt)) assoc
|
||||||
|
:preview (generate-hiccup result)
|
||||||
|
:preview-string (str result)))
|
||||||
|
db))
|
||||||
|
|
||||||
|
(defn print-error-message! [message]
|
||||||
|
(fn [_ params]
|
||||||
|
(when (:error (last params))
|
||||||
|
(toast (s/join "\n" [message params]))
|
||||||
|
(println message params))))
|
||||||
|
|
||||||
|
(reg-handler :init-render-command! init-render-command!)
|
||||||
|
(reg-handler ::render-command render-command)
|
||||||
|
|
||||||
|
(reg-handler :command-handler!
|
||||||
|
(after (print-error-message! "Error on command handling"))
|
||||||
|
(u/side-effect! command-hadler!))
|
||||||
|
(reg-handler :suggestions-handler
|
||||||
|
[(after #(dispatch [:animate-show-response]))
|
||||||
|
(after (print-error-message! "Error on param suggestions"))]
|
||||||
|
suggestions-handler!)
|
||||||
|
(reg-handler :suggestions-event! (u/side-effect! suggestions-events-handler!))
|
||||||
|
(reg-handler :command-preview
|
||||||
|
(after (print-error-message! "Error on command preview"))
|
||||||
|
command-preview)
|
|
@ -0,0 +1,103 @@
|
||||||
|
(ns status-im.commands.handlers.loading
|
||||||
|
(:require-macros [status-im.utils.slurp :refer [slurp]])
|
||||||
|
(:require [re-frame.core :refer [register-handler after dispatch subscribe
|
||||||
|
trim-v debug]]
|
||||||
|
[status-im.utils.handlers :as u]
|
||||||
|
[status-im.utils.utils :refer [http-get toast]]
|
||||||
|
[clojure.string :as s]
|
||||||
|
[status-im.persistence.realm :as realm]
|
||||||
|
[status-im.components.jail :as j]
|
||||||
|
[status-im.utils.types :refer [json->clj]]
|
||||||
|
[status-im.commands.utils :refer [reg-handler]]))
|
||||||
|
|
||||||
|
(def commands-js "commands.js")
|
||||||
|
|
||||||
|
(defn load-commands!
|
||||||
|
[_ [identity]]
|
||||||
|
(dispatch [::fetch-commands! identity])
|
||||||
|
;; todo uncomment
|
||||||
|
#_(if-let [{:keys [file]} (realm/get-one-by-field :commands :chat-id
|
||||||
|
identity)]
|
||||||
|
(dispatch [::parse-commands! identity file])
|
||||||
|
(dispatch [::fetch-commands! identity])))
|
||||||
|
|
||||||
|
(defn fetch-commands!
|
||||||
|
[db [identity]]
|
||||||
|
(when-let [url (:dapp-url (get-in db [:chats identity]))]
|
||||||
|
(if (= "console" identity)
|
||||||
|
(dispatch [::validate-hash identity (slurp "resources/commands.js")])
|
||||||
|
(http-get (s/join "/" [url commands-js])
|
||||||
|
#(dispatch [::validate-hash identity %])
|
||||||
|
#(dispatch [::loading-failed! identity ::file-was-not-found])))))
|
||||||
|
|
||||||
|
(defn dispatch-loaded!
|
||||||
|
[db [identity file]]
|
||||||
|
(if (::valid-hash db)
|
||||||
|
(dispatch [::parse-commands! identity file])
|
||||||
|
(dispatch [::loading-failed! identity ::wrong-hash])))
|
||||||
|
|
||||||
|
(defn get-hash-by-identity
|
||||||
|
[db identity]
|
||||||
|
(get-in db [:chats identity :dapp-hash]))
|
||||||
|
|
||||||
|
(defn get-hash-by-file
|
||||||
|
[file]
|
||||||
|
;; todo tbd hashing algorithm
|
||||||
|
(hash file))
|
||||||
|
|
||||||
|
(defn parse-commands! [_ [identity file]]
|
||||||
|
(j/parse identity file
|
||||||
|
(fn [result]
|
||||||
|
(let [{:keys [error result]} (json->clj result)]
|
||||||
|
(if error
|
||||||
|
(dispatch [::loading-failed! identity ::error-in-jail error])
|
||||||
|
(dispatch [::add-commands identity file result]))))))
|
||||||
|
|
||||||
|
(defn validate-hash
|
||||||
|
[db [identity file]]
|
||||||
|
(let [valid? true
|
||||||
|
;; todo check
|
||||||
|
#_(= (get-hash-by-identity db identity)
|
||||||
|
(get-hash-by-file file))]
|
||||||
|
(assoc db ::valid-hash valid?)))
|
||||||
|
|
||||||
|
(defn mark-as [as coll]
|
||||||
|
(->> coll
|
||||||
|
(map (fn [[k v]] [k (assoc v :type as)]))
|
||||||
|
(into {})))
|
||||||
|
|
||||||
|
(defn add-commands
|
||||||
|
[db [id _ {:keys [commands responses]}]]
|
||||||
|
(-> db
|
||||||
|
(update-in [:chats id :commands] merge (mark-as :command commands))
|
||||||
|
(update-in [:chats id :responses] merge (mark-as :response responses))))
|
||||||
|
|
||||||
|
(defn save-commands-js!
|
||||||
|
[_ [id file]]
|
||||||
|
(realm/create-object :commands {:chat-id id :file file}))
|
||||||
|
|
||||||
|
(defn loading-failed!
|
||||||
|
[db [id reason details]]
|
||||||
|
(let [url (get-in db [:chats id :dapp-url])]
|
||||||
|
(let [m (s/join "\n" ["commands.js loading failed"
|
||||||
|
url
|
||||||
|
id
|
||||||
|
(name reason)
|
||||||
|
details])]
|
||||||
|
(toast m)
|
||||||
|
(println m))))
|
||||||
|
|
||||||
|
(reg-handler :load-commands! (u/side-effect! load-commands!))
|
||||||
|
(reg-handler ::fetch-commands! (u/side-effect! fetch-commands!))
|
||||||
|
|
||||||
|
(reg-handler ::validate-hash
|
||||||
|
(after dispatch-loaded!)
|
||||||
|
validate-hash)
|
||||||
|
|
||||||
|
(reg-handler ::parse-commands! (u/side-effect! parse-commands!))
|
||||||
|
|
||||||
|
(reg-handler ::add-commands
|
||||||
|
(after save-commands-js!)
|
||||||
|
add-commands)
|
||||||
|
|
||||||
|
(reg-handler ::loading-failed! (u/side-effect! loading-failed!))
|
|
@ -0,0 +1,47 @@
|
||||||
|
(ns status-im.commands.utils
|
||||||
|
(:require [clojure.set :as set]
|
||||||
|
[clojure.walk :as w]
|
||||||
|
[status-im.components.react :refer [text scroll-view view
|
||||||
|
image touchable-highlight]]
|
||||||
|
[re-frame.core :refer [register-handler dispatch trim-v debug]]))
|
||||||
|
|
||||||
|
(defn json->clj [json]
|
||||||
|
(if (= json "undefined")
|
||||||
|
nil
|
||||||
|
(js->clj (.parse js/JSON json) :keywordize-keys true)))
|
||||||
|
|
||||||
|
(def elements
|
||||||
|
{:text text
|
||||||
|
:view view
|
||||||
|
:scroll-view scroll-view
|
||||||
|
:image image
|
||||||
|
:touchable touchable-highlight})
|
||||||
|
|
||||||
|
(defn get-element [n]
|
||||||
|
(elements (keyword (.toLowerCase n))))
|
||||||
|
|
||||||
|
(def events #{:onPress})
|
||||||
|
|
||||||
|
(defn wrap-event [event]
|
||||||
|
#(dispatch [:suggestions-event! event]))
|
||||||
|
|
||||||
|
(defn check-events [m]
|
||||||
|
(let [ks (set (keys m))
|
||||||
|
evs (set/intersection ks events)]
|
||||||
|
(reduce #(update %1 %2 wrap-event) m evs)))
|
||||||
|
|
||||||
|
(defn generate-hiccup [markup]
|
||||||
|
;; todo implement validation
|
||||||
|
(w/prewalk
|
||||||
|
(fn [el]
|
||||||
|
(if (and (vector? el) (string? (first el)))
|
||||||
|
(-> el
|
||||||
|
(update 0 get-element)
|
||||||
|
(update 1 check-events))
|
||||||
|
el))
|
||||||
|
markup))
|
||||||
|
|
||||||
|
(defn reg-handler
|
||||||
|
([name handler] (reg-handler name nil handler))
|
||||||
|
([name middleware handler]
|
||||||
|
(register-handler name [#_debug trim-v middleware] handler)))
|
|
@ -0,0 +1,27 @@
|
||||||
|
(ns status-im.components.jail
|
||||||
|
(:require-macros [status-im.utils.slurp :refer [slurp]])
|
||||||
|
(:require [status-im.components.react :as r]
|
||||||
|
[status-im.utils.types :as t]))
|
||||||
|
|
||||||
|
(def status-js (slurp "resources/status.js"))
|
||||||
|
|
||||||
|
(def jail
|
||||||
|
(when (exists? (.-NativeModules r/react))
|
||||||
|
(.-Jail (.-NativeModules r/react))))
|
||||||
|
|
||||||
|
(when jail
|
||||||
|
(.init jail status-js))
|
||||||
|
|
||||||
|
(defn parse [chat-id file callback]
|
||||||
|
(.parse jail chat-id file callback))
|
||||||
|
|
||||||
|
(defn cljs->json [data]
|
||||||
|
(.stringify js/JSON (clj->js data)))
|
||||||
|
|
||||||
|
(defn call [chat-id path params callback]
|
||||||
|
(println :call chat-id (cljs->json path) (cljs->json params))
|
||||||
|
(let [cb (fn [r]
|
||||||
|
(let [r' (t/json->clj r)]
|
||||||
|
(println r')
|
||||||
|
(callback r')))]
|
||||||
|
(.call jail chat-id (cljs->json path) (cljs->json params) cb)))
|
|
@ -96,7 +96,6 @@
|
||||||
(remove #(identities (:whisper-identity %)))
|
(remove #(identities (:whisper-identity %)))
|
||||||
(map #(vector (:whisper-identity %) %))
|
(map #(vector (:whisper-identity %) %))
|
||||||
(into {}))]
|
(into {}))]
|
||||||
(println new-contacts')
|
|
||||||
(-> db
|
(-> db
|
||||||
(update :contacts merge new-contacts')
|
(update :contacts merge new-contacts')
|
||||||
(assoc :new-contacts (vals new-contacts')))))
|
(assoc :new-contacts (vals new-contacts')))))
|
||||||
|
|
|
@ -5,18 +5,19 @@
|
||||||
[status-im.db :refer [app-db schema]]
|
[status-im.db :refer [app-db schema]]
|
||||||
[status-im.persistence.simple-kv-store :as kv]
|
[status-im.persistence.simple-kv-store :as kv]
|
||||||
[status-im.protocol.state.storage :as storage]
|
[status-im.protocol.state.storage :as storage]
|
||||||
[status-im.models.commands :refer [set-commands]]
|
|
||||||
[status-im.chat.suggestions :refer [load-commands]]
|
|
||||||
[status-im.utils.logging :as log]
|
[status-im.utils.logging :as log]
|
||||||
[status-im.utils.crypt :refer [gen-random-bytes]]
|
[status-im.utils.crypt :refer [gen-random-bytes]]
|
||||||
[status-im.utils.handlers :as u]
|
[status-im.utils.handlers :as u]
|
||||||
status-im.chat.handlers
|
status-im.chat.handlers
|
||||||
|
status-im.chat.handlers.animation
|
||||||
status-im.group-settings.handlers
|
status-im.group-settings.handlers
|
||||||
status-im.navigation.handlers
|
status-im.navigation.handlers
|
||||||
status-im.contacts.handlers
|
status-im.contacts.handlers
|
||||||
status-im.discovery.handlers
|
status-im.discovery.handlers
|
||||||
status-im.new-group.handlers
|
status-im.new-group.handlers
|
||||||
status-im.participants.handlers
|
status-im.participants.handlers
|
||||||
|
status-im.commands.handlers.loading
|
||||||
|
status-im.commands.handlers.jail
|
||||||
status-im.qr-scanner.handlers
|
status-im.qr-scanner.handlers
|
||||||
status-im.protocol.handlers))
|
status-im.protocol.handlers))
|
||||||
|
|
||||||
|
@ -80,17 +81,6 @@
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
(log/debug "crypt initialized"))))
|
(log/debug "crypt initialized"))))
|
||||||
|
|
||||||
(register-handler :load-commands
|
|
||||||
(u/side-effect!
|
|
||||||
(fn [_ [action]]
|
|
||||||
(log/debug action)
|
|
||||||
(load-commands))))
|
|
||||||
|
|
||||||
(register-handler :set-commands
|
|
||||||
(fn [db [action commands]]
|
|
||||||
(log/debug action commands)
|
|
||||||
(set-commands db commands)))
|
|
||||||
|
|
||||||
;; -- User data --------------------------------------------------------------
|
;; -- User data --------------------------------------------------------------
|
||||||
(register-handler :load-user-phone-number
|
(register-handler :load-user-phone-number
|
||||||
(fn [db [_]]
|
(fn [db [_]]
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
(defn get-content-suggestions [command text]
|
(defn get-content-suggestions [command text]
|
||||||
(or (when command
|
(or (when command
|
||||||
(when-let [command-suggestions ((:command command) suggestions)]
|
(when-let [command-suggestions ((keyword (:name command)) suggestions)]
|
||||||
(filterv (fn [s]
|
(filterv (fn [s]
|
||||||
(or (:header s)
|
(or (:header s)
|
||||||
(and (.startsWith (:value s) (or text ""))
|
(and (.startsWith (:value s) (or text ""))
|
||||||
|
|
|
@ -7,72 +7,14 @@
|
||||||
[status-im.components.styles :refer [color-blue color-dark-mint]]
|
[status-im.components.styles :refer [color-blue color-dark-mint]]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.i18n :refer [label]]))
|
||||||
|
|
||||||
;; todo delete
|
(defn get-commands [{:keys [current-chat-id] :as db}]
|
||||||
(def commands [{:command :money
|
(or (get-in db [:chats current-chat-id :commands]) {}))
|
||||||
:text "!money"
|
|
||||||
:description (label :t/money-command-description)
|
|
||||||
:color color-dark-mint
|
|
||||||
:request-icon {:uri "icon_lock_white"}
|
|
||||||
:icon {:uri "icon_lock_gray"}
|
|
||||||
:suggestion true}
|
|
||||||
{:command :location
|
|
||||||
:text "!location"
|
|
||||||
:description (label :t/location-command-description)
|
|
||||||
:color "#9a5dcf"
|
|
||||||
:suggestion true}
|
|
||||||
{:command :phone
|
|
||||||
:text "!phone"
|
|
||||||
:description (label :t/phone-command-description)
|
|
||||||
:color color-dark-mint
|
|
||||||
:request-text (label :t/phone-request-text)
|
|
||||||
:suggestion true
|
|
||||||
:handler #(dispatch [:sign-up %])}
|
|
||||||
{:command :confirmation-code
|
|
||||||
:text "!confirmationCode"
|
|
||||||
:description (label :t/confirmation-code-command-description)
|
|
||||||
:request-text (label :t/confirmation-code-request-text)
|
|
||||||
:color color-blue
|
|
||||||
:request-icon {:uri "icon_lock_white"}
|
|
||||||
:icon {:uri "icon_lock_gray"}
|
|
||||||
:suggestion true
|
|
||||||
:handler #(dispatch [:sign-up-confirm %])}
|
|
||||||
{:command :send
|
|
||||||
:text "!send"
|
|
||||||
:description (label :t/send-command-description)
|
|
||||||
:color "#9a5dcf"
|
|
||||||
:suggestion true}
|
|
||||||
{:command :request
|
|
||||||
:text "!request"
|
|
||||||
:description (label :t/request-command-description)
|
|
||||||
:color "#48ba30"
|
|
||||||
:suggestion true}
|
|
||||||
{:command :keypair-password
|
|
||||||
:text "!keypair-password"
|
|
||||||
:description (label :t/keypair-password-command-description)
|
|
||||||
:color color-blue
|
|
||||||
:request-icon {:uri "icon_lock_white"}
|
|
||||||
:icon {:uri "icon_lock_gray"}
|
|
||||||
:suggestion false
|
|
||||||
:handler #(dispatch [:save-password %])}
|
|
||||||
{:command :help
|
|
||||||
:text "!help"
|
|
||||||
:description (label :t/help-command-description)
|
|
||||||
:color "#9a5dcf"
|
|
||||||
:suggestion true}])
|
|
||||||
|
|
||||||
(defn get-commands [db]
|
(defn get-command [{:keys [current-chat-id] :as db} command-key]
|
||||||
;; todo: temp. must be '(get db :commands)'
|
((or (->> (get-in db [:chats current-chat-id])
|
||||||
;; (get db :commands)
|
((juxt :commands :responses))
|
||||||
commands)
|
(apply merge))
|
||||||
|
{}) command-key))
|
||||||
(defn set-commands [db commands]
|
|
||||||
(assoc db :commands commands))
|
|
||||||
|
|
||||||
;; todo delete
|
|
||||||
(def suggestions (filterv :suggestion commands))
|
|
||||||
|
|
||||||
(defn get-command [db command-key]
|
|
||||||
(first (filter #(= command-key (:command %)) (get-commands db))))
|
|
||||||
|
|
||||||
(defn find-command [commands command-key]
|
(defn find-command [commands command-key]
|
||||||
(first (filter #(= command-key (:command %)) commands)))
|
(first (filter #(= command-key (:command %)) commands)))
|
||||||
|
@ -130,7 +72,7 @@
|
||||||
#(assoc % msg-id handler)))
|
#(assoc % msg-id handler)))
|
||||||
|
|
||||||
(defn parse-command-msg-content [commands content]
|
(defn parse-command-msg-content [commands content]
|
||||||
(update content :command #(find-command commands (keyword %))))
|
(update content :command #((keyword %) commands)))
|
||||||
|
|
||||||
(defn parse-command-request [commands content]
|
(defn parse-command-request [commands content]
|
||||||
(update content :command #(find-command commands (keyword %))))
|
(update content :command #((keyword %) commands)))
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
[status-im.utils.logging :as log]
|
[status-im.utils.logging :as log]
|
||||||
[clojure.string :refer [join split]]
|
[clojure.string :refer [join split]]
|
||||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||||
[status-im.constants :as c]))
|
[status-im.constants :as c]
|
||||||
|
[status-im.commands.utils :refer [generate-hiccup]]))
|
||||||
|
|
||||||
(defn- map-to-str
|
(defn- map-to-str
|
||||||
[m]
|
[m]
|
||||||
|
@ -20,7 +21,8 @@
|
||||||
{:outgoing false
|
{:outgoing false
|
||||||
:to nil
|
:to nil
|
||||||
:same-author false
|
:same-author false
|
||||||
:same-direction false})
|
:same-direction false
|
||||||
|
:preview nil})
|
||||||
|
|
||||||
(defn save-message
|
(defn save-message
|
||||||
;; todo remove chat-id parameter
|
;; todo remove chat-id parameter
|
||||||
|
@ -45,6 +47,24 @@
|
||||||
#{c/content-type-command c/content-type-command-request}
|
#{c/content-type-command c/content-type-command-request}
|
||||||
type))
|
type))
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
(defn get-messages [chat-id]
|
||||||
|
(->> (-> (r/get-by-field :msgs :chat-id chat-id)
|
||||||
|
(r/sorted :timestamp :desc)
|
||||||
|
(r/collection->map))
|
||||||
|
(into '())
|
||||||
|
;; todo why reverse?
|
||||||
|
reverse
|
||||||
|
(map (fn [{:keys [content-type preview] :as message}]
|
||||||
|
(if (command-type? content-type)
|
||||||
|
(-> message
|
||||||
|
(update :content str-to-map)
|
||||||
|
(assoc :rendered-preview (when preview
|
||||||
|
(generate-hiccup
|
||||||
|
(read-string preview))))
|
||||||
|
(dissoc :preview))
|
||||||
|
message)))))
|
||||||
|
=======
|
||||||
(defn get-messages
|
(defn get-messages
|
||||||
([chat-id] (get-messages chat-id 0))
|
([chat-id] (get-messages chat-id 0))
|
||||||
([chat-id from]
|
([chat-id from]
|
||||||
|
@ -58,6 +78,7 @@
|
||||||
(if (command-type? content-type)
|
(if (command-type? content-type)
|
||||||
(update message :content str-to-map)
|
(update message :content str-to-map)
|
||||||
message))))))
|
message))))))
|
||||||
|
>>>>>>> develop
|
||||||
|
|
||||||
(defn update-message! [{:keys [msg-id] :as msg}]
|
(defn update-message! [{:keys [msg-id] :as msg}]
|
||||||
(log/debug "update-message!" msg)
|
(log/debug "update-message!" msg)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
(ns status-im.navigation.handlers
|
(ns status-im.navigation.handlers
|
||||||
(:require [re-frame.core :refer [register-handler dispatch debug enrich
|
(:require [re-frame.core :refer [register-handler dispatch debug enrich after]]))
|
||||||
after]]))
|
|
||||||
|
|
||||||
(defn push-view [db view-id]
|
(defn push-view [db view-id]
|
||||||
(-> db
|
(-> db
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.persistence.realm
|
(ns status-im.persistence.realm
|
||||||
(:require [cljs.reader :refer [read-string]]
|
(:require [cljs.reader :refer [read-string]]
|
||||||
[status-im.components.styles :refer [default-chat-color]]
|
[status-im.components.styles :refer [default-chat-color]]
|
||||||
[status-im.utils.logging :as log]
|
|
||||||
[status-im.utils.types :refer [to-string]]
|
[status-im.utils.types :refer [to-string]]
|
||||||
[status-im.utils.utils :as u])
|
[status-im.utils.utils :as u])
|
||||||
(:refer-clojure :exclude [exists?]))
|
(:refer-clojure :exclude [exists?]))
|
||||||
|
@ -34,7 +33,9 @@
|
||||||
:delivery-status {:type "string"
|
:delivery-status {:type "string"
|
||||||
:optional true}
|
:optional true}
|
||||||
:same-author "bool"
|
:same-author "bool"
|
||||||
:same-direction "bool"}}
|
:same-direction "bool"
|
||||||
|
:preview {:type :string
|
||||||
|
:optional true}}}
|
||||||
{:name :chat-contact
|
{:name :chat-contact
|
||||||
:properties {:identity "string"
|
:properties {:identity "string"
|
||||||
:is-in-chat {:type "bool"
|
:is-in-chat {:type "bool"
|
||||||
|
@ -51,7 +52,15 @@
|
||||||
:timestamp "int"
|
:timestamp "int"
|
||||||
:contacts {:type "list"
|
:contacts {:type "list"
|
||||||
:objectType "chat-contact"}
|
:objectType "chat-contact"}
|
||||||
|
:dapp-url {:type :string
|
||||||
|
:optional true}
|
||||||
|
:dapp-hash {:type :int
|
||||||
|
:optional true}
|
||||||
:last-msg-id "string"}}
|
:last-msg-id "string"}}
|
||||||
|
{:name :commands
|
||||||
|
:primaryKey :chat-id
|
||||||
|
:properties {:chat-id "string"
|
||||||
|
:file "string"}}
|
||||||
{:name :tag
|
{:name :tag
|
||||||
:primaryKey :name
|
:primaryKey :name
|
||||||
:properties {:name "string"
|
:properties {:name "string"
|
||||||
|
@ -94,6 +103,10 @@
|
||||||
([schema-name obj update?]
|
([schema-name obj update?]
|
||||||
(.create realm (to-string schema-name) (clj->js obj) update?)))
|
(.create realm (to-string schema-name) (clj->js obj) update?)))
|
||||||
|
|
||||||
|
(defn create-object
|
||||||
|
[schema-name obj]
|
||||||
|
(write (fn [] (create schema-name obj true))))
|
||||||
|
|
||||||
(defmulti to-query (fn [schema-name operator field value]
|
(defmulti to-query (fn [schema-name operator field value]
|
||||||
operator))
|
operator))
|
||||||
|
|
||||||
|
@ -158,3 +171,6 @@
|
||||||
(defn collection->map [collection]
|
(defn collection->map [collection]
|
||||||
(-> (.map collection (fn [object _ _] object))
|
(-> (.map collection (fn [object _ _] object))
|
||||||
(js->clj :keywordize-keys true)))
|
(js->clj :keywordize-keys true)))
|
||||||
|
|
||||||
|
(defn get-one-by-field [schema-name field value]
|
||||||
|
(single-cljs (get-by-field schema-name field value)))
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
(ns status-im.utils.slurp
|
||||||
|
(:refer-clojure :exclude [slurp]))
|
||||||
|
|
||||||
|
(defmacro slurp [file]
|
||||||
|
(clojure.core/slurp file))
|
|
@ -11,5 +11,6 @@
|
||||||
(defn clj->json [data]
|
(defn clj->json [data]
|
||||||
(.stringify js/JSON (clj->js data)))
|
(.stringify js/JSON (clj->js data)))
|
||||||
|
|
||||||
(defn json->clj [data]
|
(defn json->clj [json]
|
||||||
(js->clj (.parse js/JSON data) :keywordize-keys true))
|
(when-not (= json "undefined")
|
||||||
|
(js->clj (.parse js/JSON json) :keywordize-keys true)))
|
||||||
|
|
|
@ -41,10 +41,8 @@
|
||||||
(toast (str error))))))))
|
(toast (str error))))))))
|
||||||
|
|
||||||
(defn http-get
|
(defn http-get
|
||||||
([action on-success on-error]
|
([url on-success on-error]
|
||||||
(-> (.fetch js/window
|
(-> (.fetch js/window url (clj->js {:method "GET"}))
|
||||||
(str const/server-address action)
|
|
||||||
(clj->js {:method "GET"}))
|
|
||||||
(.then (fn [response]
|
(.then (fn [response]
|
||||||
(log response)
|
(log response)
|
||||||
(.text response)))
|
(.text response)))
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
(ns status-im.test.commands.handlers
|
||||||
|
(:require [cljs.test :refer-macros [deftest is]]
|
||||||
|
[status-im.commands.handlers.loading :as h]))
|
||||||
|
|
||||||
|
(deftest test-validate-hash
|
||||||
|
(let [file "some-js"
|
||||||
|
db (-> {}
|
||||||
|
(assoc-in [:chats :user :dapp-hash] -731917028)
|
||||||
|
(assoc-in [:chats :user2 :dapp-hash] 123))]
|
||||||
|
(is (::h/valid-hash (h/validate-hash db [:user file])))
|
||||||
|
(is (not (::h/valid-hash (h/validate-hash db [:user2 file]))))
|
||||||
|
(is (not (::h/valid-hash (h/validate-hash db [:user3 file]))))))
|
||||||
|
|
||||||
|
(deftest test-add-commands
|
||||||
|
(let [obj {:commands {:test {:name "name"
|
||||||
|
:description "desc"}}
|
||||||
|
:responses {:test-r {:name "r"
|
||||||
|
:description "desc-r"}}}
|
||||||
|
db (h/add-commands {} [:user nil obj])]
|
||||||
|
(is (= obj (select-keys (get-in db [:chats :user]) [:commands :responses])))))
|
|
@ -1,5 +1,7 @@
|
||||||
(ns status-im.test.runner
|
(ns status-im.test.runner
|
||||||
(:require [doo.runner :refer-macros [doo-tests]]
|
(:require [doo.runner :refer-macros [doo-tests]]
|
||||||
[status-im.test.handlers]))
|
[status-im.test.handlers]
|
||||||
|
[status-im.test.commands.handlers]))
|
||||||
|
|
||||||
(doo-tests 'status-im.test.handlers)
|
(doo-tests 'status-im.test.handlers
|
||||||
|
'status-im.test.commands.handlers)
|
||||||
|
|
Loading…
Reference in New Issue