Andrey Shovkoplyas 2018-01-08 23:31:15 +03:00
parent a90dba04f9
commit 0cf452207e
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
29 changed files with 228 additions and 100 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
{
"name": "status-desktop",
"name": "Status",
"version": "0.0.1",
"main": "js/main.js"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

30
package-lock.json generated
View File

@ -102,6 +102,9 @@
"tweetnacl": "0.14.5"
}
},
"bignumber.js": {
"version": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89"
},
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
@ -513,6 +516,14 @@
"verror": "1.10.0"
}
},
"linkify-it": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz",
"integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=",
"requires": {
"uc.micro": "1.0.3"
}
},
"loose-envify": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
@ -861,6 +872,13 @@
"prop-types": "15.6.0"
}
},
"react-native-hyperlink": {
"version": "git+https://github.com/flexsurfer/react-native-hyperlink.git#3cd0b0f6bd2cc7dc4ccefe6fbc18699b72f68219",
"requires": {
"linkify-it": "1.2.4",
"react-native-web": "0.1.12"
}
},
"react-native-web": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.1.12.tgz",
@ -1046,6 +1064,11 @@
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
},
"uc.micro": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz",
"integrity": "sha1-ftUNXg+an7ClczeSWfKndFjVAZI="
},
"uid-number": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
@ -1077,18 +1100,13 @@
}
},
"web3": {
"version": "github:status-im/web3.js#17b13f26044e60ac824d1b97052bfad1be5af9cc",
"version": "github:status-im/web3.js#aca66029d7ffac8ed2803b2fc7f0fec01e335ca3",
"requires": {
"bignumber.js": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89",
"crypto-js": "3.1.8",
"utf8": "2.1.2",
"xhr2": "0.1.4",
"xmlhttprequest": "1.8.0"
},
"dependencies": {
"bignumber.js": {
"version": "github:status-im/bignumber.js#cc066a0a3d6bfe0c436c9957f4ea8344bf963c89"
}
}
},
"whatwg-fetch": {

View File

@ -3,17 +3,18 @@
"version": "0.0.1",
"description": "Status Desktop (React Native Web and Electron)",
"dependencies": {
"react": "16.0.0",
"react-dom": "16.0.0",
"react-native-web": "0.1.12",
"awesome-phonenumber": "^1.0.13",
"chance": "1.0.4",
"eccjs": "0.3.1",
"emojilib": "^2.2.1",
"homoglyph-finder": "^1.1.1",
"identicon.js": "github:status-im/identicon.js",
"awesome-phonenumber": "^1.0.13",
"emojilib": "^2.2.1",
"web3": "github:status-im/web3.js#status-develop",
"status-nodejs": "git+https://github.com/status-im/status-nodejs.git"
"react": "16.0.0",
"react-dom": "16.0.0",
"react-native-hyperlink": "git+https://github.com/flexsurfer/react-native-hyperlink.git",
"react-native-web": "0.1.12",
"status-nodejs": "git+https://github.com/status-im/status-nodejs.git",
"web3": "github:status-im/web3.js#status-develop"
},
"license": "MPL-2.0",
"repository": "https://github.com/status-im/status-electron"

View File

@ -30,12 +30,12 @@
["cljsbuild" "once" "prod-front"]]
;; electron packager for production
"desktop-app-osx" ["shell" "electron-packager" "./app/prod" "status-desktop" "--platform=darwin" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules" "--icon=assets/icon1024.icns"]
"desktop-app-linux" ["shell" "electron-packager" "./app/prod" "status-desktop" "--platform=linux" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules" "--icon=assets/icon1024.png"]
"desktop-app-osx" ["shell" "electron-packager" "./app/prod" "Status" "--platform=darwin" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules" "--icon=assets/icon1024.icns"]
"desktop-app-linux" ["shell" "electron-packager" "./app/prod" "Status" "--platform=linux" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules" "--icon=assets/icon1024.png"]
"desktop-app-store" ["shell" "electron-packager" "./app/prod" "status-desktop" "--platform=mas" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]
"desktop-app-win64" ["shell" "cmd.exe" "/c" "electron-packager" "./app/prod" "status-desktop" "--platform=win32" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]
"desktop-app-win32" ["shell" "cmd.exe" "/c" "electron-packager" "./app/prod" "status-desktop" "--platform=win32" "--arch=ia32" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]}
"desktop-app-store" ["shell" "electron-packager" "./app/prod" "Status" "--platform=mas" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]
"desktop-app-win64" ["shell" "cmd.exe" "/c" "electron-packager" "./app/prod" "Status" "--platform=win32" "--arch=x64" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]
"desktop-app-win32" ["shell" "cmd.exe" "/c" "electron-packager" "./app/prod" "Status" "--platform=win32" "--arch=ia32" "--electron-version=1.8.2-beta.3" "--extraResource=./node_modules"]}
:hooks [leiningen.cljsbuild]
:cljsbuild {:builds {:dev-main {:source-paths ["src"]

View File

@ -25,7 +25,7 @@
(.on app "ready"
(fn []
(reset! *win* (BrowserWindow. (clj->js {:width 1200 :height 800 :icon (.resolve path (js* "__dirname") "../status.icns")})))
(reset! *win* (BrowserWindow. (clj->js {:width 1200 :height 800})))
;; when no optimize comment out
(.loadURL @*win* (str "file://" (.resolve path (js* "__dirname") "../index.html")))
@ -50,14 +50,15 @@
(.on ipcMain "StartNode"
(fn [event config]
(let [config (.GenerateConfig status-go (.resolve path (js* "__dirname") "../ethereum") 3 0)
(let [app-path (.getPath app "userData")
config (.GenerateConfig status-go (str app-path "/ethereum") 3 0)
config' (.parse js/JSON config)
_ (set! (.-LogLevel config') "INFO")
_ (set! (.-LogFile config') (.resolve path (js* "__dirname") "../node.log"))
_ (set! (.-LogFile config') (str app-path "/node.log"))
_ (set! (.-Enabled (.-UpstreamConfig config')) true)
config'' (.stringify js/JSON config')
res (.StartNode status-go config'')]
(.log js/console (str "Node started at " (.resolve path (js* "__dirname") "../ethereum")))
(.log js/console (str "Node started at " (str app-path "/ethereum")))
(set! (.-returnValue event) (str "Config " config'' " Node result: " res)))))
(.on ipcMain "CreateAccount"

View File

@ -30,7 +30,7 @@
{ :role "quit"}]})))
(.append menu
(MenuItem.
(clj->js {:label "Status" :submenu [{ :label "Logs" :click #(re-frame/dispatch [:logs]) :accelerator "CmdOrCtrl+L"}]})))
(clj->js {:label "Dev" :submenu [{ :label "Logs" :click #(re-frame/dispatch [:logs]) :accelerator "CmdOrCtrl+L"}]})))
(.setApplicationMenu Menu menu))
(mount-root)
(re-frame/dispatch-sync [:initialize-app]))

View File

@ -8,11 +8,21 @@
;;;; DESKTOP
(def audio {:notif01 (js/Audio. (str js/__dirname "/resources/notif01.mp3"))
:notif02 (js/Audio. (str js/__dirname "/resources/notif02.mp3"))
:notif03 (js/Audio. (str js/__dirname "/resources/notif03.mp3"))
:notif04 (js/Audio. (str js/__dirname "/resources/notif04.mp3"))
:notif05 (js/Audio. (str js/__dirname "/resources/notif05.mp3"))
:notif06 (js/Audio. (str js/__dirname "/resources/notif06.mp3"))
:notif07 (js/Audio. (str js/__dirname "/resources/notif07.mp3"))
:notif08 (js/Audio. (str js/__dirname "/resources/notif08.mp3"))})
(re-frame/reg-fx
:send-desktop-notification
(fn [{:keys [content from]}]
(fn [{:keys [content from sound]}]
(when-not (.hasFocus js/document)
(js/Notification. from (clj->js {:body content})))))
(when sound (.play (get audio sound)))
(js/Notification. from (clj->js {:body content :silent true})))))
;;;; old events
@ -100,8 +110,8 @@
(re-frame/reg-fx
:update-message
(fn [message]))
;(msg-store/update-message message)))
(fn [message]
(storage/update-message message)))
(re-frame/reg-fx
:save-message

View File

@ -3,7 +3,8 @@
[status-desktop-front.web3-provider :as web3-provider]
[status-im.protocol.handlers :as protocol.handlers]
[status-im.constants :as constants]
[status-im.utils.handlers :as handlers]))
[status-im.utils.handlers :as handlers]
[status-desktop-front.storage :as storage]))
;;;; COFX
@ -15,7 +16,7 @@
(re-frame/reg-cofx
::protocol.handlers/get-chat-groups
(fn [coeffects _]
(assoc coeffects :groups [])))
(assoc coeffects :groups (storage/get-active-group-chats))))
(re-frame/reg-cofx
::protocol.handlers/get-pending-messages

View File

@ -1,7 +1,8 @@
(ns status-desktop-front.storage
(:require [alandipert.storage-atom :refer [local-storage]]
[status-im.data-store.messages :as data-store.messages]
[status-im.utils.random :as random]))
[status-im.utils.random :as random]
[status-im.constants :as constants]))
;;;; ACCOUNTS
;; I would love to have something similar in status-react instead realm
@ -24,7 +25,7 @@
;;;; CONTACTS
(defn save-contact [contact]
(swap! (:contacts @account) assoc (:whisper-identity contact) contact))
(swap! (:contacts @account) update-in (:whisper-identity contact) merge contact))
(defn save-contacts [contacts]
(mapv save-contact contacts))
@ -59,6 +60,19 @@
(> timestamp removed-from-at)
(> timestamp added-at))))
(defn- groups [active?]
(filter #(and (:group-chat %) (= (:is-active %) active?)) (get-all-chats)))
(defn get-active-group-chats []
(map (fn [{:keys [chat-id public-key private-key public?]}]
(let [group {:group-id chat-id
:public? public?}]
(if (and public-key private-key)
(assoc group :keypair {:private private-key
:public public-key})
group)))
(groups true)))
;;;; MESSAGE
(defn save-message [{:keys [message-id content] :as message}]
@ -69,11 +83,24 @@
:timestamp (random/timestamp)})]
(swap! (:messages @account) assoc message-id message')))
(defn update-message [{:keys [message-id content] :as message}]
(swap! (:messages @account) update-in [message-id] merge message))
(defn get-message-by-id [message-id]
(get @(:messages @account) message-id))
(defn get-messages-by-chat-id [chat-id]
(filter #(= chat-id (:chat-id %)) (vals @(:messages @account))))
(defn get-messages-by-chat-id
([chat-id]
(get-messages-by-chat-id chat-id 0))
([chat-id from]
(let [chats (sort-by :timestamp > (filter #(= chat-id (:chat-id %)) (vals @(:messages @account))))
to (+ from constants/default-number-of-messages)]
(if (< to (count chats))
;;TODO yeah i know i know
(subvec (into [] chats)
from
to)
chats))))
(defn get-last-message [chat-id]
(->> (vals @(:messages @account))

View File

@ -4,7 +4,14 @@
[status-desktop-front.ui.components.icons :as icons]
[status-im.ui.components.common.styles :as styles]
[status-im.ui.components.action-button.styles :as st]
[status-im.ui.components.styles :as common]))
[status-im.ui.components.styles :as common]
[status-im.ui.components.checkbox.styles :as checkbox.styles]))
(defn checkbox [{:keys [on-value-change checked?]}]
[react/touchable-highlight {:style checkbox.styles/wrapper :on-press #(do (when on-value-change (on-value-change (not checked?))))}
[react/view {:style (checkbox.styles/icon-check-container checked?)}
(when checked?
[icons/icon :icons/ok {:style checkbox.styles/check-icon}])]])
;; TODO copy-pate with minimum modifications of status-react components

View File

@ -1,7 +1,9 @@
(ns status-desktop-front.ui.screens.chat.profile.views
(:require [status-desktop-front.react-native-web :as react]
[status-im.ui.screens.profile.styles :as styles]
[status-desktop-front.ui.components.views :as components]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.utils.utils :refer [hash-tag?]]
[clojure.string :as string]
[cljs.nodejs :as nodejs])
@ -76,6 +78,36 @@
[profile-info-address-item contact]
[profile-info-public-key-item public-key contact]])
(views/defview sound-view [sound label sound-name]
[react/view {:style (merge styles/profile-setting-item {:height 30})}
[react/text {:style styles/profile-setting-text} label]
[react/view {:style {:flex 1}}]
[components/checkbox {:on-value-change
#(re-frame/dispatch [:set-in [:desktop :notifications :sound] sound-name])
:checked?
(= sound sound-name)}]])
(views/defview notifications []
(views/letsubs [notifications-enabled? [:get-in [:desktop :notifications :enabled?]]
sound [:get-in [:desktop :notifications :sound]]]
[react/view
[react/view {:style styles/profile-setting-item}
[react/text {:style styles/profile-setting-text} "Notifications"]
[react/view {:style {:flex 1}}]
[components/checkbox {:on-value-change
#(re-frame/dispatch [:set-in [:desktop :notifications :enabled?] %])
:checked?
notifications-enabled?}]]
[sound-view sound "Sound 1" :notif01]
[sound-view sound "Sound 2" :notif02]
[sound-view sound "Sound 3" :notif03]
[sound-view sound "Sound 4" :notif04]
[sound-view sound "Sound 5" :notif05]
[sound-view sound "Sound 6" :notif06]
[sound-view sound "Sound 7" :notif07]
[sound-view sound "Sound 8" :notif08]]))
(views/defview profile []
(views/letsubs [{:keys [status public-key] :as current-account} [:get-current-account]]
[react/view {:style (merge styles/profile {:background-color :white})}
@ -84,4 +116,5 @@
[profile-badge current-account]
[profile-status status true]]
[react/view {:style styles/profile-info-container}
[my-profile-info current-account]]]]))
[my-profile-info current-account]]
[notifications]]]))

View File

@ -6,20 +6,23 @@
[status-desktop-front.ui.components.icons :as icons]
[status-desktop-front.web3-provider :as protocol]
[clojure.string :as string]
[status-im.chat.views.message.message :as message.views]
[status-im.chat.styles.message.message :as message.style]
[status-im.utils.gfycat.core :as gfycat.core]
[status-im.utils.gfycat.core :as gfycat]
[status-im.ui.screens.chats-list.styles :as chats-list.styles]
[status-im.constants :as constants])
[status-im.constants :as constants]
[status-desktop-front.react-native-hyperlink :as rn-hl])
(:require-macros [status-im.utils.views :as views]))
(views/defview message-author-name [{:keys [outgoing from] :as message}]
(views/letsubs [current-account [:get-current-account]
incoming-name [:contact-name-by-identity from]]
(when-let [name (if outgoing
(:name current-account)
(or incoming-name "Unknown contact"))]
[react/text {:style message.style/author} name])))
incoming-name [:contact-name-by-identity from]]
(if outgoing
[react/text {:style message.style/author} (:name current-account)]
(let [name (or incoming-name (gfycat/generate-gfy from))]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-contact-dialog from name (boolean incoming-name)])}
[react/text {:style message.style/author} name]]))))
(defn message [text me? {:keys [outgoing message-id chat-id message-status user-statuses
from current-public-key content-type group-chat] :as message}]
@ -36,90 +39,115 @@
:message-id message-id}]))
:reagent-render
(fn []
[react/view {:style (merge {:padding-bottom 8}
(if me?
{:align-items :flex-end
:padding-left 90
:padding-right 60}
{:align-items :flex-start
:padding-left 60
:padding-right 90}))}
[react/view {:style (merge
{:padding-bottom 8}
(if me?
{:align-items :flex-end
:padding-left 90
:padding-right 60}
{:align-items :flex-start
:padding-left 60
:padding-right 90}))}
[react/view {:style {:padding 12 :background-color :white :border-radius 8}}
(when group-chat [message-author-name message])
[react/text
text]]])})))
[rn-hl/hyperlink {:linkStyle {:color "#2980b9"} :on-press #(re-frame/dispatch [:show-link-dialog %1])}
[react/text
text]]]])})))
(views/defview messages-view [{:keys [chat-id group-chat]}]
(let [scroll-ref (atom nil)
messages (re-frame/subscribe [:get-chat-messages chat-id])
current-public-key (re-frame/subscribe [:get-current-public-key])]
[react/view {:style {:flex 1 :background-color "#eef2f5"}}
[react/scroll-view {:onContentSizeChange #(.scrollToEnd @scroll-ref) :ref #(reset! scroll-ref %)}
[react/view {:style {:padding-vertical 60}}
(for [[index {:keys [from content message-id] :as message-obj}] (map-indexed vector (reverse @messages))]
^{:key message-id} [message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)])]]]))
(views/letsubs [chat-id* (atom nil)
scroll-ref (atom nil)
scroll-timer (atom nil)
scroll-height (atom nil)]
(let [_ (when (or (not @chat-id*) (not= @chat-id* chat-id))
(reset! chat-id* chat-id)
(println "dirty hack")
(js/setTimeout #(when scroll-ref (.scrollToEnd @scroll-ref)) 400))
messages (re-frame/subscribe [:get-chat-messages chat-id])
current-public-key (re-frame/subscribe [:get-current-public-key])]
[react/view {:style {:flex 1 :background-color "#eef2f5"}}
[react/scroll-view {:scrollEventThrottle 16
:on-scroll (fn [e]
(let [ne (.-nativeEvent e)
y (.-y (.-contentOffset ne))]
(when (zero? y)
(when @scroll-timer (js/clearTimeout @scroll-timer))
(reset! scroll-timer (js/setTimeout #(re-frame/dispatch [:load-more-messages]) 300)))
(reset! scroll-height (+ y (.-height (.-layoutMeasurement ne))))))
:on-content-size-change #(when (or (not @scroll-height) (< (- %2 @scroll-height) 500))
(.scrollToEnd @scroll-ref))
:ref #(reset! scroll-ref %)}
[react/view {:style {:padding-vertical 60}}
(for [[index {:keys [from content message-id] :as message-obj}] (map-indexed vector (reverse @messages))]
^{:key message-id} [message content (= from @current-public-key) (assoc message-obj :group-chat group-chat)])]]])))
(views/defview status-view []
[react/view {:style {:flex 1 :background-color "#eef2f5" :align-items :center :justify-content :center}}
[react/view {:style {:flex 1 :background-color "#eef2f5" :align-items :center :justify-content :center}}
[react/text {:style {:font-size 18 :color "#939ba1"}}
"Status.im"]])
(views/defview toolbar-chat-view []
(views/letsubs [name [:chat :name]
chat-id [:get-current-chat-id]
(views/letsubs [name [:chat :name]
chat-id [:get-current-chat-id]
pending-contact? [:current-contact :pending?]
public-key [:chat :public-key]]
public-key [:chat :public-key]]
(let [chat-name (if (string/blank? name)
(gfycat.core/generate-gfy public-key)
(or name;(get-contact-translated chat-id :name name)
"Chat name"))];(label :t/chat-name)))]
(or name ;(get-contact-translated chat-id :name name)
"Chat name"))] ;(label :t/chat-name)))]
[react/view {:style {:height 64 :align-items :center :padding-horizontal 11 :justify-content :center}}
[react/text {:style {:font-size 16 :color :black :font-weight "600"}}
chat-name]
(when pending-contact?
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:add-pending-contact chat-id])}
[react/view ;style/add-contact
[react/view ;style/add-contact
[react/text {:style {:font-size 14 :color "#939ba1" :margin-top 3}}
"Add to contacts"]]])])))
;[react/text {:style {:font-size 14 :color "#939ba1" :margin-top 3}}
;"Contact status not implemented"]])))
;[react/text {:style {:font-size 14 :color "#939ba1" :margin-top 3}}
;"Contact status not implemented"]])))
(views/defview chat-text-input []
(views/letsubs [input-text [:chat :input-text]
inp-ref (atom nil)]
[react/view {:style {:height 90 :margin-horizontal 16 :margin-bottom 16 :background-color :white :border-radius 12
:box-shadow "0 0.5px 4.5px 0 rgba(0, 0, 0, 0.04)"}}
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16 :flex 1 :margin-bottom 16}}
[react/view {:style {:flex 1}}
[react/text-input {:default-value (or input-text "")
:placeholder "Type a message..."
:auto-focus true
:multiline true
:blur-on-submit true
:style {:flex 1}
:ref #(reset! inp-ref %)
:on-key-press (fn [e]
(let [native-event (.-nativeEvent e)
key (.-key native-event)]
(when (= key "Enter")
(js/setTimeout #(do
(.clear @inp-ref)
(.focus @inp-ref)) 200)
(re-frame/dispatch [:send-current-message]))))
:on-change (fn [e]
(let [native-event (.-nativeEvent e)
text (.-text native-event)]
(re-frame/dispatch [:set-chat-input-text text])))}]]
[react/touchable-highlight {:on-press (fn []
(js/setTimeout #(do (.clear @inp-ref)(.focus @inp-ref)) 200)
(re-frame/dispatch [:send-current-message]))}
[react/view {:style {:margin-left 16 :width 30 :height 30 :border-radius 15 :background-color "#eef2f5" :align-items :center
:justify-content :center}}
[icons/icon :icons/dropdown-up]]]]]))
(views/defview chat-view []
(views/letsubs [current-chat [:get-current-chat]
input-text [:chat :input-text]
inp-ref (atom nil)]
(views/letsubs [current-chat [:get-current-chat]]
[react/view {:style {:flex 1 :background-color "#eef2f5"}}
[toolbar-chat-view]
[react/view {:style {:height 1 :background-color "#e8ebec" :margin-horizontal 16}}]
[messages-view current-chat]
[react/view {:style {:height 90 :margin-horizontal 16 :margin-bottom 16 :background-color :white :border-radius 12
:box-shadow "0 0.5px 4.5px 0 rgba(0, 0, 0, 0.04)"}}
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16 :flex 1 :margin-bottom 16}}
[react/view {:style {:flex 1}}
[react/text-input {:value (or input-text "")
:placeholder "Type a message..."
:auto-focus true
:multiline true
:blur-on-submit true
:style {:flex 1}
:ref #(reset! inp-ref %)
:on-key-press (fn [e]
(let [native-event (.-nativeEvent e)
key (.-key native-event)]
(when (= key "Enter")
(js/setTimeout #(.focus @inp-ref) 200)
(re-frame/dispatch [:send-current-message]))))
:on-change (fn [e]
(let [native-event (.-nativeEvent e)
text (.-text native-event)]
(re-frame/dispatch [:set-chat-input-text text])))}]]
[react/touchable-highlight {:on-press (fn []
(js/setTimeout #(.focus @inp-ref) 200)
(re-frame/dispatch [:send-current-message]))}
[react/view {:style {:margin-left 16 :width 30 :height 30 :border-radius 15 :background-color "#eef2f5" :align-items :center
:justify-content :center}}
[icons/icon :icons/dropdown-up]]]]]]))
[chat-text-input]]))
(views/defview new-contact []
(views/letsubs [new-contact-identity [:get :contacts/new-identity]
@ -151,6 +179,7 @@
[react/view {:style {:height 90 :margin-horizontal 16 :margin-bottom 16 :background-color :white :border-radius 12
:box-shadow "0 0.5px 4.5px 0 rgba(0, 0, 0, 0.04)"}}
[react/view {:style {:flex-direction :row :margin-horizontal 16 :margin-top 16}}
[react/text "#"]
[react/view {:style {:flex 1}}
[react/text-input {:placeholder "topic"
:on-change (fn [e]

View File

@ -8,7 +8,8 @@
status-desktop-front.override.login
status-desktop-front.override.account
status-desktop-front.override.contacts
status-desktop-front.override.recieve-message))
status-desktop-front.override.recieve-message
status-desktop-front.ui.screens.chat.events))
(handlers/register-handler-fx
:create-desktop-account