diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index ae8f747d2b..7015df6723 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -7,7 +7,8 @@ [status-im.protocol.api :as api] [status-im.models.messages :as messages] [status-im.constants :refer [text-content-type - content-type-command]] + content-type-command + content-type-command-request]] [status-im.utils.random :as random] [status-im.chat.sign-up :as sign-up-service] [status-im.models.chats :as chats] @@ -381,6 +382,7 @@ (dispatch [:load-commands! current-chat-id])) (register-handler :init-chat + (after #(dispatch [:load-requests!])) (-> load-messages! ((enrich init-chat)) ((after load-commands!)))) @@ -408,6 +410,11 @@ [{:keys [new-message]} [_ {chat-id :from}]] (messages/save-message chat-id new-message)) +(defn dispatch-request! + [{:keys [new-message]} [_ {chat-id :from}]] + (when (= (:content-type new-message) content-type-command-request) + (dispatch [:add-request chat-id new-message]))) + (defn receive-message [db [_ {chat-id :from :as message}]] (let [message' (check-author-direction db chat-id message)] @@ -416,8 +423,9 @@ (assoc :new-message message')))) (register-handler :received-msg - (-> receive-message - ((after store-message!)))) + [(after store-message!) + (after dispatch-request!)] + receive-message) (register-handler :group-received-msg (u/side-effect! @@ -429,6 +437,7 @@ (let [chat-id (or id current-chat-id) messages (get-in db [:chats chat-id :messages]) db' (assoc db :current-chat-id chat-id)] + (dispatch [:load-requests! chat-id]) (if (seq messages) db' (-> db' diff --git a/src/status_im/chat/handlers/animation.cljs b/src/status_im/chat/handlers/animation.cljs index 9a98c088f0..dd5218ac0a 100644 --- a/src/status_im/chat/handlers/animation.cljs +++ b/src/status_im/chat/handlers/animation.cljs @@ -1,7 +1,6 @@ (ns status-im.chat.handlers.animation - (:require [re-frame.core :refer [after dispatch debug]] + (:require [re-frame.core :refer [after dispatch debug path]] [status-im.utils.handlers :refer [register-handler]] - [re-frame.middleware :refer [path]] [status-im.handlers.content-suggestions :refer [get-content-suggestions]] [status-im.chat.constants :refer [input-height request-info-height minimum-command-suggestions-height diff --git a/src/status_im/chat/handlers/requests.cljs b/src/status_im/chat/handlers/requests.cljs new file mode 100644 index 0000000000..828e952b81 --- /dev/null +++ b/src/status_im/chat/handlers/requests.cljs @@ -0,0 +1,41 @@ +(ns status-im.chat.handlers.requests + (:require [re-frame.core :refer [after]] + [status-im.utils.handlers :refer [register-handler]] + [status-im.persistence.realm :as realm])) + +(defn store-request! + [{:keys [new-request]}] + (realm/write + (fn [] + (realm/create :requests new-request)))) + +(defn add-request + [db [_ chat-id {:keys [msg-id content]}]] + (let [request {:chat-id chat-id + :message-id msg-id + :type (:command content) + :added (js/Date.)} + request' (update request :type keyword)] + (-> db + (update-in [:chats chat-id :requests] conj request') + (assoc :new-request request)))) + +(defn load-requests! + [{:keys [current-chat-id] :as db} [_ chat-id]] + (let [chat-id' (or chat-id current-chat-id) + requests (-> :requests + ;; todo maybe limit is needed + (realm/get-by-fieds {:chat-id chat-id' + :status "open"}) + (realm/sorted :added :desc) + (realm/collection->map)) + requests' (->> requests + (map #(update % :type keyword)) + (into '()))] + (assoc-in db [:chats chat-id' :requests] requests'))) + +(register-handler :add-request + (after store-request!) + add-request) + +(register-handler :load-requests! load-requests!) diff --git a/src/status_im/chat/styles/suggestions.cljs b/src/status_im/chat/styles/suggestions.cljs index 15ae5a1b9a..e21cd4c620 100644 --- a/src/status_im/chat/styles/suggestions.cljs +++ b/src/status_im/chat/styles/suggestions.cljs @@ -3,6 +3,7 @@ color-light-blue-transparent color-white color-black + color-gray color-blue color-blue-transparent selected-message-color @@ -26,6 +27,15 @@ :borderBottomColor separator-color :flex-direction :row}) +(def command-description-container + {:flex 0.6}) + +(def command-label-container + {:flex 0.4 + :flex-direction :column + :align-items :flex-end + :margin-right 16}) + (defn suggestion-background [{:keys [color]}] {:marginTop 10 @@ -40,6 +50,14 @@ :fontFamily font :color color-white}) +(def title-container + {:margin-left 57 + :margin-bottom 16}) + +(def title-text + {:font-size 13 + :color :#8f838c93}) + (def value-text {:marginTop 6 :fontSize 14 @@ -52,15 +70,6 @@ :fontFamily font :color text2-color}) -(defn suggestions-container [suggestions-count] - {:flexDirection :row - :marginVertical 1 - :marginHorizontal 0 - :flex 1 - :height (min 168 (* suggestion-height suggestions-count)) - :backgroundColor color-white - :borderRadius 5}) - (defn container [height] {:flexDirection :column :position :absolute @@ -70,3 +79,38 @@ :height height :backgroundColor color-white :elevation 2}) + +(def request-container + {:height 56 + :flex-direction :row}) + +(def request-icon-container + {:height 56 + :width 57 + :align-items :center + :justifyContent :center}) + +(defn request-icon-background [color] + {:height 32 + :width 32 + :border-radius 32 + :background-color color + :align-items :center + :justifyContent :center}) + +(def request-icon + {:width 12 + :height 12}) + +(def request-info-container + {:height 56 + :padding-top 10}) + +(def request-info-description + {:font-size 12 + :color color-black}) + +(def request-message-info + {:font-size 12 + :margin-top 2 + :color color-gray}) diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index eee09009cf..0a8d999432 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -157,3 +157,13 @@ (reaction (if (= :command @type) @width 0))))) + +(register-sub :get-requests + (fn [db] + (let [chat-id (subscribe [:get-current-chat-id])] + (reaction (get-in @db [:chats @chat-id :requests]))))) + +(register-sub :get-response + (fn [db [_ n]] + (let [chat-id (subscribe [:get-current-chat-id])] + (reaction (get-in @db [:chats @chat-id :responses n]))))) diff --git a/src/status_im/chat/views/suggestions.cljs b/src/status_im/chat/views/suggestions.cljs index 53f7f68b5c..1c91b8d89f 100644 --- a/src/status_im/chat/views/suggestions.cljs +++ b/src/status_im/chat/views/suggestions.cljs @@ -5,6 +5,7 @@ scroll-view text icon + image touchable-highlight list-view list-item @@ -15,13 +16,30 @@ [reagent.core :as r] [status-im.components.animation :as anim] [status-im.components.drag-drop :as drag] - [status-im.components.react :as react] [status-im.chat.suggestions-responder :as resp] [status-im.chat.constants :as c])) (defn set-command-input [command] (dispatch [:set-chat-command command])) +(defview request-item [{:keys [type message-id]}] + [{:keys [color icon description] :as response} [:get-response type]] + [touchable-highlight + {:on-press #(dispatch [:set-response-chat-command message-id type])} + [view st/request-container + [view st/request-icon-container + [view (st/request-icon-background color) + [image {:source {:uri icon} + :style st/request-icon}]]] + [view st/request-info-container + [text {:style st/request-info-description} description] + ;; todo stub + [text {:style st/request-message-info} + "By console, today at 14:50"]]]]) + +(defn render-request-row [row _ _] + (list-item [request-item row])) + (defn suggestion-list-item [[command {:keys [description] name :name @@ -29,16 +47,13 @@ (let [label (str "!" name)] [touchable-highlight {:onPress #(set-command-input command) - :style st/suggestion-highlight} + :style st/suggestion-highlight} [view st/suggestion-container [view st/suggestion-sub-container - [view {:flex 0.6} + [view st/command-description-container [text {:style st/value-text} label] [text {:style st/description-text} description]] - [view {:flex 0.4 - :flex-direction :column - :align-items :flex-end - :margin-right 16} + [view st/command-label-container [view (st/suggestion-background suggestion) [text {:style st/suggestion-text} label]]]]]])) @@ -46,18 +61,21 @@ (list-item [suggestion-list-item row])) (defn title [s] - [view {:margin-left 57 - :margin-bottom 16} - [text {:style {:font-size 13 - :color :#8f838c93}} s]]) + [view st/title-container + [text {:style st/title-text} s]]) (defview suggestions-view [] [suggestions [:get-suggestions] - requests [:get :chat-requests]] + requests [:get-requests]] [scroll-view (when requests [title "Requests"]) + (when requests + [view + [list-view {:dataSource (to-datasource requests) + :keyboardShouldPersistTaps true + :renderRow render-request-row}]]) [title "Commands"] - [view (st/suggestions-container (count suggestions)) + [view [list-view {:dataSource (to-datasource suggestions) :keyboardShouldPersistTaps true :renderRow render-row}]]]) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index fa6e3a7632..d01788d834 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -16,4 +16,4 @@ (def response-input-hiding-duration 100) (def response-suggesstion-resize-duration 100) -(def default-number-of-messages 10) +(def default-number-of-messages 20) diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs index 7829563fe5..1c656f5514 100644 --- a/src/status_im/handlers.cljs +++ b/src/status_im/handlers.cljs @@ -19,7 +19,8 @@ status-im.commands.handlers.loading status-im.commands.handlers.jail status-im.qr-scanner.handlers - status-im.protocol.handlers)) + status-im.protocol.handlers + status-im.chat.handlers.requests)) ;; -- Middleware ------------------------------------------------------------ ;; diff --git a/src/status_im/persistence/realm.cljs b/src/status_im/persistence/realm.cljs index 8ed342537a..277da95dc3 100644 --- a/src/status_im/persistence/realm.cljs +++ b/src/status_im/persistence/realm.cljs @@ -2,7 +2,8 @@ (:require [cljs.reader :refer [read-string]] [status-im.components.styles :refer [default-chat-color]] [status-im.utils.types :refer [to-string]] - [status-im.utils.utils :as u]) + [status-im.utils.utils :as u] + [clojure.string :as str]) (:refer-clojure :exclude [exists?])) (def opts {:schema [{:name :contacts @@ -14,6 +15,13 @@ :optional true} :photo-path {:type "string" :optinal true}}} + {:name :requests + :properties {:message-id :string + :chat-id :string + :type :string + :status {:type :string + :default "open"} + :added :date}} {:name :kv-store :primaryKey :key :properties {:key "string" @@ -107,12 +115,16 @@ [schema-name obj] (write (fn [] (create schema-name obj true)))) +(defn and-q [queries] + (str/join " and " queries)) + (defmulti to-query (fn [schema-name operator field value] operator)) (defmethod to-query :eq [schema-name operator field value] (let [value (to-string value) - query (str (name field) "=" (if (= "string" (field-type schema-name field)) + query (str (name field) "=" (if (= "string" (name (field-type + schema-name field))) (str "\"" value "\"") value))] query)) @@ -125,6 +137,12 @@ (let [q (to-query schema-name :eq field value)] (.filtered (.objects realm (name schema-name)) q))) +(defn get-by-fieds [schema-name fields] + (let [queries (map (fn [[k v]] + (to-query schema-name :eq k v)) + fields)] + (.filtered (.objects realm (name schema-name)) (and-q queries)))) + (defn get-all [schema-name] (.objects realm (to-string schema-name)))