hide mailman contact

inject mailman's commands

ensure that mailman's commands are injected after loading
prevent loading of default contacts at account creation
This commit is contained in:
Roman Volosovskyi 2017-05-02 17:39:02 +03:00 committed by Roman Volosovskyi
parent 1eaea101dd
commit 3607032a4e
16 changed files with 166 additions and 85 deletions

View File

@ -5,6 +5,12 @@ status.command({
description: I18n.t('location_description'),
color: "#a187d5",
sequentialParams: true,
registeredOnly: true,
params: [{
name: "address",
type: status.types.TEXT,
placeholder: I18n.t('location_address')
}],
preview: function (params) {
var text = status.components.text(
{
@ -42,8 +48,4 @@ status.command({
)
};
}
}).param({
name: "address",
type: status.types.TEXT,
placeholder: I18n.t('location_address')
});

View File

@ -0,0 +1,7 @@
(ns status-im.bots.constants)
(def mailman-bot "mailman")
(defn mailman-bot? [bot-name]
(= mailman-bot bot-name))
(def hidden-bots #{mailman-bot})

View File

@ -122,7 +122,7 @@
:params
parameter-index
:suggestions]
args (-> (get-in db [:chats jail-id :input-text])
args (-> (get-in db [:chats current-chat-id :input-text])
(input-model/split-command-args)
(rest))
params {:parameters {:args args}
@ -221,6 +221,7 @@
(dispatch [::request-command-data
{:command command
:chat-id chat-id
:jail-id (get-in command [:command :bot])
:data-type :preview
:after #(dispatch [::send-message % chat-id])}])))))
@ -278,7 +279,7 @@
(handlers/register-handler
::check-dapp-suggestions
(handlers/side-effect!
(fn [{:keys [current-account-id] :as db} [_ chat-id text]]
(fn [{:keys [current-account-id] :as db} [_ chat-id text]]
(let [data (get-in db [:local-storage chat-id])]
(status/call-function!
{:chat-id chat-id

View File

@ -31,7 +31,8 @@
:timestamp (time/now-ms)
:content (assoc content :handler-data handler-data
:type (name (:type command))
:content-command (:name command))
:content-command (:name command)
:bot (:bot command))
:content-type (or content-type
(if request
content-type-command-request

View File

@ -6,7 +6,8 @@
[status-im.i18n :as i18n]
[status-im.utils.phone-number :as phone-number]
[taoensso.timbre :as log]
[status-im.chat.utils :as chat-utils]))
[status-im.chat.utils :as chat-utils]
[status-im.bots.constants :as bots-constants]))
(defn text-ends-with-space? [text]
(when text
@ -19,8 +20,8 @@
commands' (into {} (map (fn [[k v]] [k [v :any]]) (merge global-commands commands)))
responses' (into {} (map (fn [{:keys [message-id type]}]
[type [(get responses type) message-id]])
requests))]
[type [(get responses type) message-id]])
requests))]
(vals (merge commands' responses'))))
(defn split-command-args [command-text]
@ -63,10 +64,12 @@
command-args (split-command-args input-text)
command-name (first command-args)]
(when (chat-utils/starts-as-command? (or command-name ""))
(when-let [[command to-message-id] (-> (filter (fn [[{:keys [name bot]} message-id]]
(= (or bot name) (subs command-name 1)))
possible-actions)
(first))]
(when-let [[command to-message-id]
(-> (filter (fn [[{:keys [name bot]} message-id]]
(= (or (when-not (bots-constants/mailman-bot? bot) bot) name)
(subs command-name 1)))
possible-actions)
(first))]
{:command command
:metadata (if (not= :any to-message-id)
(assoc input-metadata :to-message-id to-message-id)
@ -75,7 +78,7 @@
(rest command-args)
seq-arguments)}))))
([{:keys [current-chat-id] :as db} chat-id]
(selected-chat-command db chat-id (get-in db [:chats chat-id :input-text]))))
(selected-chat-command db chat-id (get-in db [:chats chat-id :input-text]))))
(defn current-chat-argument-position
[{:keys [args] :as command} input-text seq-arguments]
@ -93,17 +96,17 @@
-1))
(defn argument-position [{:keys [current-chat-id] :as db} chat-id]
(let [chat-id (or chat-id current-chat-id)
input-text (get-in db [:chats chat-id :input-text])
seq-arguments (get-in db [:chats chat-id :seq-arguments])
chat-command (selected-chat-command db chat-id)]
(let [chat-id (or chat-id current-chat-id)
input-text (get-in db [:chats chat-id :input-text])
seq-arguments (get-in db [:chats chat-id :seq-arguments])
chat-command (selected-chat-command db chat-id)]
(current-chat-argument-position chat-command input-text seq-arguments)))
(defn command-completion
([{:keys [current-chat-id] :as db} chat-id]
(let [chat-id (or chat-id current-chat-id)
input-text (get-in db [:chats chat-id :input-text])
chat-command (selected-chat-command db chat-id)]
(let [chat-id (or chat-id current-chat-id)
input-text (get-in db [:chats chat-id :input-text])
chat-command (selected-chat-command db chat-id)]
(command-completion chat-command)))
([{:keys [args] :as chat-command}]
(let [args (remove str/blank? args)

View File

@ -2,7 +2,8 @@
(:require [status-im.constants :refer [console-chat-id
wallet-chat-id]]
[clojure.string :as str]
[status-im.chat.constants :as const]))
[status-im.chat.constants :as const]
[status-im.bots.constants :as bots-constants]))
(defn console? [s]
(= console-chat-id s))
@ -48,9 +49,13 @@
(pos? (count message))))
(defn command-name [{:keys [bot name]}]
(if bot
(str const/bot-char bot)
(str const/command-char name)))
(cond
(bots-constants/mailman-bot? bot)
(str const/command-char name)
bot (str const/bot-char bot)
:else (str const/command-char name)))
(defn starts-as-command? [text]
(and (not (nil? text))

View File

@ -127,10 +127,12 @@
:get-responses
:get-commands)
chat-id]
global-commands [:get :global-commands]
current-chat-id [:get-current-chat-id]
contact-chat [:get-in [:chats (if outgoing to from)]]
preview [:get-in [:message-data :preview message-id :markup]]]
(let [{:keys [command params]} (parse-command-message-content commands content)
(let [{:keys [command params]}
(parse-command-message-content commands global-commands content)
{:keys [name type]
icon-path :icon} command]
[view st/content-command-view
@ -370,15 +372,16 @@
(into [view] children)))
(defn chat-message [{:keys [outgoing message-id chat-id user-statuses from] :as message}]
(let [my-identity (subscribe [:get :current-public-key])
status (subscribe [:get-in [:message-data :user-statuses message-id my-identity]])
preview (subscribe [:get-in [:message-data :preview message-id :markup]])]
(let [my-identity (subscribe [:get :current-public-key])
status (subscribe [:get-in [:message-data :user-statuses message-id my-identity]])
preview (subscribe [:get-in [:message-data :preview message-id :markup]])]
(r/create-class
{:component-will-mount
(fn []
(when (and (get-in message [:content :command])
(not @preview))
(dispatch [:request-command-data message :preview])))
(let [{:keys [bot] :as command} (get-in message [:content])
message' (assoc message :jail-id bot)]
(when (and command (not @preview))
(dispatch [:request-command-data message' :preview]))))
:component-did-mount
(fn []

View File

@ -5,7 +5,6 @@
[status-im.components.react :refer [view image icon text]]
[status-im.components.chat-icon.screen :refer [chat-icon-view-chat-list]]
[status-im.components.context-menu :refer [context-menu]]
[status-im.models.commands :refer [parse-command-message-content]]
[status-im.chats-list.styles :as st]
[status-im.utils.utils :refer [truncate-str]]
[status-im.i18n :refer [get-contact-translated label label-pluralize]]

View File

@ -14,22 +14,27 @@
[status-im.utils.homoglyph :as h]
[status-im.utils.js-resources :as js-res]
[status-im.utils.random :as random]
[status-im.chat.sign-up :as sign-up]))
[status-im.chat.sign-up :as sign-up]
[status-im.bots.constants :as bots-constants]))
(def commands-js "commands.js")
(defn load-commands!
[{:keys [current-chat-id contacts]} [identity callback]]
(let [identity' (or identity current-chat-id)
contact (or (get contacts identity')
sign-up/console-contact)]
[{:keys [current-chat-id contacts]} [contact callback]]
(let [whole-contact? (map? contact)
{:keys [whisper-identity]} contact
identity' (or whisper-identity contact current-chat-id)
contact' (if whole-contact?
contact
(or (get contacts identity')
sign-up/console-contact))]
(when identity'
(dispatch [::fetch-commands! {:contact contact
(dispatch [::fetch-commands! {:contact contact'
:callback callback}])))
;; todo uncomment
#_(if-let [{:keys [file]} (commands/get-by-chat-id identity)]
(dispatch [::parse-commands! identity file])
(dispatch [::fetch-commands! identity])))
#_(if-let [{:keys [file]} (commands/get-by-chat-id contact)]
(dispatch [::parse-commands! contact file])
(dispatch [::fetch-commands! contact])))
(defn http-get-commands [params url]
@ -103,8 +108,9 @@
(defn filter-forbidden-names [account id commands]
(->> commands
(remove (fn [[_ {:keys [registered-only]}]]
(remove (fn [[_ {:keys [registered-only name]}]]
(and (not (:address account))
(not= name "global")
registered-only)))
(remove (fn [[n]]
(and
@ -112,37 +118,63 @@
(h/matches (name n) "password"))))
(into {})))
(defn get-mailmans-commands [db]
(->> (get-in db [:contacts bots-constants/mailman-bot :commands])
(map
(fn [[k v :as com]]
[k (-> v
(update :params (fn [p]
(if (map? p)
((comp vec vals) p)
p)))
(assoc :bot bots-constants/mailman-bot
:type :command))]))
(into {})))
(defn add-commands
[db [id _ {:keys [commands responses subscriptions]}]]
(let [account @(subscribe [:get-current-account])
commands' (filter-forbidden-names account id commands)
global-command (:global commands')
commands'' (apply dissoc commands' [:init :global])
responses' (filter-forbidden-names account id responses)]
(let [account @(subscribe [:get-current-account])
commands' (filter-forbidden-names account id commands)
global-command (:global commands')
commands'' (apply dissoc commands' [:init :global])
responses' (filter-forbidden-names account id responses)
mailman-commands (get-mailmans-commands db)]
(cond-> db
true
(update-in [:contacts id] assoc
:commands-loaded true
:commands (mark-as :command commands'')
:commands (mark-as :command (merge mailman-commands commands''))
:responses (mark-as :response responses')
:subscriptions subscriptions)
global-command
(update :global-commands assoc (keyword id)
(assoc global-command :bot id
:type :command)))))
:type :command))
(= id bots-constants/mailman-bot)
(update db :contacts (fn [contacts]
(reduce (fn [contacts [k _]]
(update-in contacts [k :commands]
(fn [c]
(merge mailman-commands c))))
contacts
contacts))))))
(defn save-commands-js!
[_ [id file]]
#_(commands/save {:chat-id id :file file}))
(defn save-global-command!
[{:keys [global-commands]} [id]]
(let [command (get global-commands (keyword id))]
(when command
(contacts/save {:whisper-identity id
:global-command command}))))
(defn save-commands!
[{:keys [global-commands contacts]} [id]]
(let [command (get global-commands (keyword id))
commands (get-in contacts [id :commands])
responses (get-in contacts [id :commands])]
(contacts/save {:whisper-identity id
:global-command command
:commands (vals commands)
:responses (vals responses)})))
(defn loading-failed!
[db [id reason details]]
@ -173,7 +205,7 @@
(reg-handler ::add-commands
[(after save-commands-js!)
(after save-global-command!)
(after save-commands!)
(after #(dispatch [:check-and-open-dapp!]))
(after #(dispatch [:update-suggestions]))
(after (fn [_ [id]]

View File

@ -223,7 +223,7 @@
(register-handler :load-default-contacts!
(u/side-effect!
(fn [{:keys [chats groups]}]
(fn [{:keys [contacts groups]}]
(let [default-contacts js-res/default-contacts
default-groups js-res/default-contact-groups]
(dispatch [:add-groups (mapv
@ -237,21 +237,23 @@
(doseq [[id {:keys [name photo-path public-key add-chat? has-global-command?
dapp? dapp-url dapp-hash bot-url]}] default-contacts]
(let [id' (clojure.core/name id)]
(when-not (chats id')
(when-not (get contacts id')
(when add-chat?
(dispatch [:add-chat id' {:name (:en name)}]))
(dispatch [:add-contacts [{:whisper-identity id'
:address (public-key->address id')
:name (:en name)
:photo-path photo-path
:public-key public-key
:dapp? dapp?
:dapp-url (:en dapp-url)
:bot-url bot-url
:has-global-command? has-global-command?
:dapp-hash dapp-hash}]])
(when bot-url
(dispatch [:load-commands! id'])))))))))
(let [contact
{:whisper-identity id'
:address (public-key->address id')
:name (:en name)
:photo-path photo-path
:public-key public-key
:dapp? dapp?
:dapp-url (:en dapp-url)
:bot-url bot-url
:has-global-command? has-global-command?
:dapp-hash dapp-hash}]
(dispatch [:add-contacts [contact]])
(when bot-url
(dispatch [:load-commands! contact]))))))))))
(register-handler :add-contacts

View File

@ -2,7 +2,8 @@
(:require-macros [reagent.ratom :refer [reaction]])
(:require [re-frame.core :refer [register-sub subscribe]]
[status-im.utils.identicon :refer [identicon]]
[clojure.string :as str]))
[clojure.string :as str]
[status-im.bots.constants :as bots-constants]))
(register-sub :current-contact
(fn [db [_ k]]
@ -23,10 +24,13 @@
(clojure.string/lower-case name2))))
(vals contacts)))
(register-sub :all-added-contacts
(fn [db _]
(let [contacts (reaction (:contacts @db))]
(->> (remove #(true? (:pending? (second %))) @contacts)
(->> (remove (fn [[_ {:keys [pending? whisper-identity]}]]
(or (true? pending?)
(bots-constants/hidden-bots whisper-identity))) @contacts)
(sort-contacts)
(reaction)))))

View File

@ -2,9 +2,18 @@
(:require [status-im.data-store.realm.contacts :as data-store])
(:refer-clojure :exclude [exists?]))
(defn- command->map-item
[[_ {:keys [name] :as command}]]
[(keyword name) command])
(defn get-all
[]
(data-store/get-all-as-list))
(map
(fn [{:keys [commands responses] :as contact}]
(assoc contact
:commands (into {} (map command->map-item commands))
:responses (into {} (map command->map-item responses))))
(data-store/get-all-as-list)))
(defn get-by-id
[whisper-identity]
@ -15,9 +24,9 @@
(let [{pending-db? :pending?
:as contact-db} (data-store/get-by-id whisper-identity)
contact (assoc contact :pending?
(boolean (if contact-db
(if (nil? pending?) pending-db? pending?)
pending?)))]
(boolean (if contact-db
(if (nil? pending?) pending-db? pending?)
pending?)))]
(data-store/save contact (if contact-db true false))))
(defn save-all

View File

@ -7,6 +7,8 @@
:color {:type :string
:optional true}
:name {:type :string}
:icon {:type :string
:optional true}
:params {:type :list
:objectType :command-parameter}
:title {:type :string
@ -16,7 +18,9 @@
:fullscreen {:type :bool
:default true}
:suggestions-trigger {:type :string
:default "on-change"}}})
:default "on-change"}
:sequential-params {:type :bool
:default false}}})
(defn migration [old-realm new-realm]
(log/debug "migrating chat-contact schema v6"))

View File

@ -23,6 +23,10 @@
:optional true}
:global-command {:type :command
:optional true}
:commands {:type :list
:objectType :command}
:responses {:type :list
:objectType :command}
:dapp-hash {:type :int
:optional true}
:debug? {:type :bool
@ -33,10 +37,10 @@
(let [new-contacts (.objects new-realm "contact")]
(dotimes [i (.-length new-contacts)]
(let [contact (aget new-contacts i)
id (aget contact "whisper-identity")]
id (aget contact "whisper-identity")]
(when (= id "console")
(log/debug (js->clj contact))
(aset contact "dapp-url" nil)
(aset contact "bot-url" "local://console-bot"))
(aset contact "bot-url" "local://console-bot"))
(when (= id "wallet")
(aset contact "dapp-url" "https://status.im/dapps/wallet/"))))))

View File

@ -49,6 +49,7 @@
network-status network first-run]} _]
(data-store/init)
(assoc app-db :current-account-id nil
:contacts {}
:network-status network-status
:status-module-initialized? (or p/ios? js/goog.DEBUG status-module-initialized?)
:status-node-started? status-node-started?
@ -97,7 +98,6 @@
(dispatch [:set :first-run false]))
(when (or (not first-run) (empty? accounts))
(dispatch [:init-console-chat])
(dispatch [:load-default-contacts!])
(dispatch [:load-commands!])
(when callback (callback))))))

View File

@ -1,10 +1,15 @@
(ns status-im.models.commands
(:require [status-im.db :as db]
[tailrecursion.priority-map :refer [priority-map-by]]))
[tailrecursion.priority-map :refer [priority-map-by]]
[status-im.bots.constants :as bots-constants]))
(defn parse-command-message-content [commands content]
(defn parse-command-message-content
[commands global-commands content]
(if (map? content)
(update content :command #((keyword %) commands))
(let [{:keys [command bot]} content]
(if (and bot (not (bots-constants/mailman-bot? bot)))
(update content :command #((keyword bot) global-commands))
(update content :command #((keyword command) commands))))
content))
(defn parse-command-request [commands content]