Merge pull request #279 from status-im/feature/database-migration-#262
Database migrations #262
This commit is contained in:
commit
4303570ebc
|
@ -1,5 +1,5 @@
|
|||
(ns status-im.accounts.handlers
|
||||
(:require [status-im.models.accounts :as accounts-model]
|
||||
(:require [status-im.data-store.accounts :as accounts-store]
|
||||
[re-frame.core :refer [register-handler after dispatch dispatch-sync debug]]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.protocol.core :as protocol]
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
|
||||
(defn save-account [_ [_ account]]
|
||||
(accounts-model/save-accounts [account] true))
|
||||
(accounts-store/save account true))
|
||||
|
||||
(register-handler
|
||||
:add-account
|
||||
|
@ -54,9 +54,9 @@
|
|||
password
|
||||
#(account-created % password)))))
|
||||
|
||||
(defn save-account-to-realm!
|
||||
(defn save-account!
|
||||
[{:keys [current-account-id accounts]} _]
|
||||
(accounts-model/save-accounts [(get accounts current-account-id)] true))
|
||||
(accounts-store/save (get accounts current-account-id) true))
|
||||
|
||||
(defn send-account-update
|
||||
[{:keys [current-account-id current-public-key web3 accounts]} _]
|
||||
|
@ -79,7 +79,7 @@
|
|||
account (-> (get accounts current-account-id)
|
||||
(merge data))]
|
||||
(assoc-in db [:accounts current-account-id] account)))
|
||||
((after save-account-to-realm!))
|
||||
((after save-account!))
|
||||
((after send-account-update))))
|
||||
|
||||
(register-handler
|
||||
|
@ -103,7 +103,7 @@
|
|||
(register-handler :set-current-account set-current-account)
|
||||
|
||||
(defn load-accounts! [db _]
|
||||
(let [accounts (->> (accounts-model/get-accounts)
|
||||
(let [accounts (->> (accounts-store/get-all)
|
||||
(map (fn [{:keys [address] :as account}]
|
||||
[address account]))
|
||||
(into {}))]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[taoensso.timbre :as log]
|
||||
[status-im.utils.types :refer [json->clj]]
|
||||
[status-im.db :refer [default-view]]
|
||||
[status-im.persistence.realm.core :as realm]
|
||||
[status-im.data-store.core :as data-store]
|
||||
[status-im.components.status :as status]
|
||||
[status-im.constants :refer [console-chat-id]]))
|
||||
|
||||
|
@ -29,24 +29,24 @@
|
|||
(dispatch [:navigate-to default-view]))))
|
||||
|
||||
(register-handler
|
||||
:change-realm-account
|
||||
:change-account
|
||||
(u/side-effect!
|
||||
(fn [db [_ address new-account? callback]]
|
||||
(realm/change-account-realm address new-account?
|
||||
#(callback % address new-account?)))))
|
||||
(data-store/change-account address new-account?
|
||||
#(callback % address new-account?)))))
|
||||
|
||||
(defn on-account-changed
|
||||
[error address new-account?]
|
||||
(if (nil? error)
|
||||
(initialize-account address new-account?)
|
||||
(log/debug "Error changing acount realm: " error)))
|
||||
(log/debug "Error changing acount: " error)))
|
||||
|
||||
(defn logged-in
|
||||
[db address]
|
||||
(let [is-login-screen? (= (:view-id db) :login)
|
||||
new-account? (not is-login-screen?)]
|
||||
(log/debug "Logged in: ")
|
||||
(dispatch [:change-realm-account address new-account? on-account-changed])))
|
||||
(dispatch [:change-account address new-account? on-account-changed])))
|
||||
|
||||
(register-handler
|
||||
:login-account
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.accounts.recover.validations
|
||||
(:require [cljs.spec :as s]
|
||||
[cljsjs.web3]
|
||||
[status-im.persistence.realm.core :as realm]))
|
||||
[cljsjs.web3]))
|
||||
|
||||
(s/def ::not-empty-string (s/and string? not-empty))
|
||||
(s/def ::passphrase ::not-empty-string)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
[status-im.group-settings.screen :refer [group-settings]]
|
||||
[status-im.profile.screen :refer [profile my-profile]]
|
||||
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
|
||||
status-im.persistence.realm.core
|
||||
status-im.data-store.core
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.components.status :as status]))
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
[status-im.components.styles :refer [default-chat-color]]
|
||||
[status-im.chat.suggestions :as suggestions]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.models.contacts :as contacts]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.models.pending-messages :as pending-messages]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.pending-messages :as pending-messages]
|
||||
[status-im.constants :refer [text-content-type
|
||||
content-type-command
|
||||
content-type-command-request
|
||||
|
@ -18,7 +18,6 @@
|
|||
[status-im.chat.sign-up :as sign-up-service]
|
||||
[status-im.navigation.handlers :as nav]
|
||||
[status-im.utils.handlers :refer [register-handler] :as u]
|
||||
[status-im.persistence.realm.core :as r]
|
||||
[status-im.handlers.server :as server]
|
||||
[status-im.utils.phone-number :refer [format-phone-number
|
||||
valid-mobile-number?]]
|
||||
|
@ -61,7 +60,7 @@
|
|||
db
|
||||
(let [messages-path [:chats current-chat-id :messages]
|
||||
messages (get-in db messages-path)
|
||||
new-messages (messages/get-messages current-chat-id (count messages))
|
||||
new-messages (messages/get-by-chat-id current-chat-id (count messages))
|
||||
all-loaded? (> default-number-of-messages (count new-messages))]
|
||||
(-> db
|
||||
(assoc :loading-allowed false)
|
||||
|
@ -179,8 +178,8 @@
|
|||
(if (chats console-chat-id)
|
||||
db
|
||||
(do
|
||||
(chats/create-chat new-chat)
|
||||
(contacts/save-contacts [sign-up-service/console-contact])
|
||||
(chats/save new-chat)
|
||||
(contacts/save-all [sign-up-service/console-contact])
|
||||
(sign-up-service/intro)
|
||||
(when existing-account?
|
||||
(sign-up-service/start-signup))
|
||||
|
@ -228,7 +227,7 @@
|
|||
(defn load-messages!
|
||||
([db] (load-messages! db nil))
|
||||
([{:keys [current-chat-id] :as db} _]
|
||||
(assoc db :messages (messages/get-messages current-chat-id))))
|
||||
(assoc db :messages (messages/get-by-chat-id current-chat-id))))
|
||||
|
||||
(defn init-chat
|
||||
([db] (init-chat db nil))
|
||||
|
@ -261,7 +260,7 @@
|
|||
|
||||
(defn load-chats!
|
||||
[db _]
|
||||
(assoc db :loaded-chats (chats/chats-list)))
|
||||
(assoc db :loaded-chats (chats/get-all)))
|
||||
|
||||
;TODO: check if its new account / signup status / create console chat
|
||||
(register-handler :initialize-chats
|
||||
|
@ -304,7 +303,7 @@
|
|||
|
||||
(defn save-new-chat!
|
||||
[{:keys [new-chat]} _]
|
||||
(chats/create-chat new-chat))
|
||||
(chats/save new-chat))
|
||||
|
||||
(defn open-chat!
|
||||
[_ [_ chat-id _ navigation-type]]
|
||||
|
@ -341,7 +340,7 @@
|
|||
; todo do we really need this message?
|
||||
(defn leaving-message!
|
||||
[{:keys [current-chat-id]} _]
|
||||
(messages/save-message
|
||||
(messages/save
|
||||
current-chat-id
|
||||
{:from "system"
|
||||
:message-id (random/id)
|
||||
|
@ -351,24 +350,15 @@
|
|||
(defn delete-messages!
|
||||
[{:keys [current-chat-id]} [_ chat-id]]
|
||||
(let [id (or chat-id current-chat-id)]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(r/delete :account
|
||||
(r/get-by-field :account :message :chat-id id))))))
|
||||
(messages/delete-by-chat-id id)))
|
||||
|
||||
(defn delete-chat!
|
||||
[_ [_ chat-id]]
|
||||
(r/write :account
|
||||
(fn [] :account
|
||||
(when-let [chat (->> (r/get-by-field :account :chat :chat-id chat-id)
|
||||
(r/single))]
|
||||
(doto chat
|
||||
(aset "is-active" false)
|
||||
(aset "removed-at" (.getTime (js/Date.))))))))
|
||||
(chats/delete chat-id))
|
||||
|
||||
(defn remove-pending-messages!
|
||||
[_ [_ chat-id]]
|
||||
(pending-messages/remove-all-by-chat chat-id))
|
||||
(pending-messages/delete-all-by-chat-id chat-id))
|
||||
|
||||
(register-handler :leave-group-chat
|
||||
;; todo oreder of operations tbd
|
||||
|
@ -435,8 +425,8 @@
|
|||
:message-id message-id}}))))
|
||||
(register-handler :send-seen!
|
||||
[(after (fn [_ [_ {:keys [message-id]}]]
|
||||
(messages/update-message! {:message-id message-id
|
||||
:message-status :seen})))
|
||||
(messages/update {:message-id message-id
|
||||
:message-status :seen})))
|
||||
(after (fn [_ [_ {:keys [chat-id]}]]
|
||||
(dispatch [:remove-unviewed-messages chat-id])))]
|
||||
(u/side-effect! send-seen!))
|
||||
|
@ -457,7 +447,7 @@
|
|||
|
||||
(defn update-chat!
|
||||
[_ [_ chat]]
|
||||
(chats/update-chat chat))
|
||||
(chats/save chat))
|
||||
|
||||
(register-handler :update-chat!
|
||||
(-> (fn [db [_ {:keys [chat-id] :as chat}]]
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(ns status-im.chat.handlers.receive-message
|
||||
(:require [status-im.utils.handlers :refer [register-handler] :as u]
|
||||
[re-frame.core :refer [enrich after debug dispatch path]]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.chat.utils :as cu]
|
||||
[status-im.commands.utils :refer [generate-hiccup]]
|
||||
[status-im.constants :refer [content-type-command-request]]
|
||||
[cljs.reader :refer [read-string]]
|
||||
[status-im.models.chats :as c]))
|
||||
[status-im.data-store.chats :as chats]))
|
||||
|
||||
(defn check-preview [{:keys [content] :as message}]
|
||||
(if-let [preview (:preview content)]
|
||||
|
@ -17,7 +17,7 @@
|
|||
message))
|
||||
|
||||
(defn store-message [{chat-id :chat-id :as message}]
|
||||
(messages/save-message chat-id (dissoc message :rendered-preview :new?)))
|
||||
(messages/save chat-id (dissoc message :rendered-preview :new?)))
|
||||
|
||||
(defn get-current-identity
|
||||
[{:keys [current-account-id accounts]}]
|
||||
|
@ -25,11 +25,11 @@
|
|||
|
||||
(defn receive-message
|
||||
[db [_ {:keys [from group-id chat-id message-id] :as message}]]
|
||||
(let [same-message (messages/get-message message-id)
|
||||
(let [same-message (messages/get-by-id message-id)
|
||||
current-identity (get-current-identity db)
|
||||
chat-id' (or group-id chat-id from)
|
||||
exists? (c/chat-exists? chat-id')
|
||||
active? (c/is-active? chat-id')]
|
||||
exists? (chats/exists? chat-id')
|
||||
active? (chats/is-active? chat-id')]
|
||||
(when (and (not same-message)
|
||||
(not= from current-identity)
|
||||
(or (not exists?) active?))
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
(ns status-im.chat.handlers.requests
|
||||
(:require [re-frame.core :refer [after dispatch enrich]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.models.requests :as requests]
|
||||
[status-im.utils.handlers :refer [register-handler] :as u]
|
||||
[status-im.persistence.realm.core :as realm]))
|
||||
[status-im.data-store.requests :as requests]
|
||||
[status-im.utils.handlers :refer [register-handler] :as u]))
|
||||
|
||||
(defn store-request!
|
||||
[{:keys [new-request] :as db}]
|
||||
(requests/save-request new-request))
|
||||
(requests/save new-request))
|
||||
|
||||
(defn add-request
|
||||
[db [_ chat-id {:keys [message-id content]}]]
|
||||
|
@ -23,23 +22,14 @@
|
|||
(defn load-requests!
|
||||
[{:keys [current-chat-id] :as db} [_ chat-id]]
|
||||
(let [chat-id' (or chat-id current-chat-id)
|
||||
requests (-> ;; todo maybe limit is needed
|
||||
(realm/get-by-fields :account :request :and [[:chat-id chat-id']
|
||||
[:status "open"]])
|
||||
(realm/sorted :added :desc)
|
||||
(realm/realm-collection->list))
|
||||
;; todo maybe limit is needed
|
||||
requests (requests/get-open-by-chat-id chat-id')
|
||||
requests' (map #(update % :type keyword) requests)]
|
||||
(assoc-in db [:chats chat-id' :requests] requests')))
|
||||
|
||||
(defn mark-request-as-answered!
|
||||
[_ [_ chat-id message-id]]
|
||||
(realm/write :account
|
||||
(fn []
|
||||
(-> (realm/get-by-fields :account :request :and [[:chat-id chat-id]
|
||||
[:message-id message-id]])
|
||||
(realm/single)
|
||||
(.-status)
|
||||
(set! "answered")))))
|
||||
(requests/mark-as-answered chat-id message-id))
|
||||
|
||||
(register-handler :add-request
|
||||
(after store-request!)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im.chat.handlers.send-message
|
||||
(:require [status-im.utils.handlers :refer [register-handler] :as u]
|
||||
[clojure.string :as s]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.components.status :as status]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.utils.datetime :as time]
|
||||
|
@ -97,7 +97,7 @@
|
|||
(register-handler ::save-command!
|
||||
(u/side-effect!
|
||||
(fn [{:keys [current-public-key]} [_ {:keys [command chat-id]}]]
|
||||
(messages/save-message
|
||||
(messages/save
|
||||
chat-id
|
||||
(dissoc command :rendered-preview :to-message :has-handler)))))
|
||||
|
||||
|
@ -154,7 +154,7 @@
|
|||
(dispatch [::send-message! params])))
|
||||
(u/side-effect!
|
||||
(fn [_ [_ {:keys [chat-id message]}]]
|
||||
(messages/save-message chat-id message))))
|
||||
(messages/save chat-id message))))
|
||||
|
||||
(register-handler ::send-message!
|
||||
(u/side-effect!
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
(ns status-im.chat.handlers.unviewed-messages
|
||||
(:require [re-frame.core :refer [after enrich path dispatch]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.persistence.realm.core :as realm]))
|
||||
|
||||
(defn delivered-messages []
|
||||
(-> (realm/get-by-fields :account :message :and {:outgoing false
|
||||
:message-status nil})
|
||||
(realm/realm-collection->list)))
|
||||
[status-im.data-store.messages :as messages]))
|
||||
|
||||
(defn set-unviewed-messages [db]
|
||||
(let [messages (->> (::raw-unviewed-messages db)
|
||||
|
@ -20,7 +15,7 @@
|
|||
(dissoc ::raw-unviewed-messages))))
|
||||
|
||||
(defn load-messages! [db]
|
||||
(let [messages (delivered-messages)]
|
||||
(let [messages (messages/get-unviewed)]
|
||||
(assoc db ::raw-unviewed-messages messages)))
|
||||
|
||||
(register-handler ::set-unviewed-messages set-unviewed-messages)
|
||||
|
@ -39,4 +34,4 @@
|
|||
(register-handler :remove-unviewed-messages
|
||||
(path :unviewed-messages)
|
||||
(fn [db [_ chat-id]]
|
||||
(dissoc db chat-id)))
|
||||
(dissoc db chat-id)))
|
|
@ -44,4 +44,4 @@
|
|||
{:margin-top 10.5
|
||||
:margin-left 12
|
||||
:width 15
|
||||
:height 15})
|
||||
:height 15})
|
|
@ -3,7 +3,7 @@
|
|||
(:require [re-frame.core :refer [register-sub dispatch subscribe path]]
|
||||
[status-im.utils.platform :refer [ios?]]
|
||||
[status-im.models.commands :as commands]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.constants :refer [response-suggesstion-resize-duration]]
|
||||
[status-im.chat.constants :as c]
|
||||
[status-im.chat.views.plain-message :as plain-message]
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
(register-sub :get-chat-by-id
|
||||
(fn [_ [_ chat-id]]
|
||||
(reaction (chats/chat-by-id chat-id))))
|
||||
(reaction (chats/get-by-id chat-id))))
|
||||
|
||||
(register-sub :get-responses
|
||||
(fn [db _]
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
[status-im.chat.views.request-message :refer [message-content-command-request]]
|
||||
[status-im.chat.styles.message :as st]
|
||||
[status-im.chat.styles.command-pill :as pill-st]
|
||||
[status-im.models.chats :refer [chat-by-id]]
|
||||
[status-im.models.commands :refer [parse-command-message-content
|
||||
parse-command-request]]
|
||||
[status-im.resources :as res]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
[status-im.utils.handlers :as u]
|
||||
[status-im.utils.utils :refer [http-get show-popup]]
|
||||
[clojure.string :as s]
|
||||
[status-im.persistence.realm.core :as realm]
|
||||
[status-im.data-store.commands :as commands]
|
||||
[status-im.components.status :as status]
|
||||
[status-im.utils.types :refer [json->clj]]
|
||||
[status-im.commands.utils :refer [reg-handler]]
|
||||
|
@ -16,8 +16,7 @@
|
|||
[_ [identity]]
|
||||
(dispatch [::fetch-commands! identity])
|
||||
;; todo uncomment
|
||||
#_(if-let [{:keys [file]} (realm/get-one-by-field :account :command
|
||||
:chat-id identity)]
|
||||
#_(if-let [{:keys [file]} (commands/get-by-chat-id identity)]
|
||||
(dispatch [::parse-commands! identity file])
|
||||
(dispatch [::fetch-commands! identity])))
|
||||
|
||||
|
@ -85,7 +84,7 @@
|
|||
|
||||
(defn save-commands-js!
|
||||
[_ [id file]]
|
||||
(realm/create-object :account :command {:chat-id id :file file}))
|
||||
(commands/save {:chat-id id :file file}))
|
||||
|
||||
(defn loading-failed!
|
||||
[db [id reason details]]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im.contacts.handlers
|
||||
(:require [re-frame.core :refer [after dispatch]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.models.contacts :as contacts]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.utils.crypt :refer [encrypt]]
|
||||
[clojure.string :as s]
|
||||
[status-im.protocol.core :as protocol]
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
(defn save-contact
|
||||
[_ [_ contact]]
|
||||
(contacts/save-contacts [contact]))
|
||||
(contacts/save contact))
|
||||
|
||||
(defn watch-contact
|
||||
[{:keys [web3]} [_ {:keys [whisper-identity public-key private-key]}]]
|
||||
|
@ -64,7 +64,7 @@
|
|||
((after save-contact))))
|
||||
|
||||
(defn load-contacts! [db _]
|
||||
(let [contacts (->> (contacts/get-contacts)
|
||||
(let [contacts (->> (contacts/get-all)
|
||||
(map (fn [{:keys [whisper-identity] :as contact}]
|
||||
[whisper-identity contact]))
|
||||
(into {}))]
|
||||
|
@ -136,7 +136,7 @@
|
|||
(u/side-effect! get-identities-by-contacts!))
|
||||
|
||||
(defn save-contacts! [{:keys [new-contacts]} _]
|
||||
(contacts/save-contacts new-contacts))
|
||||
(contacts/save-all new-contacts))
|
||||
|
||||
(defn update-pending-status [old-contacts {:keys [whisper-identity pending] :as contact}]
|
||||
(let [{old-pending :pending
|
||||
|
@ -169,7 +169,7 @@
|
|||
(register-handler :add-new-contact
|
||||
(u/side-effect!
|
||||
(fn [_ [_ {:keys [whisper-identity] :as contact}]]
|
||||
(when-not (contacts/get-contact whisper-identity)
|
||||
(when-not (contacts/get-by-id whisper-identity)
|
||||
(dispatch [::prepare-contact contact])))))
|
||||
|
||||
(register-handler ::prepare-contact
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
(ns status-im.contacts.validations
|
||||
(:require [cljs.spec :as s]
|
||||
[cljsjs.web3]
|
||||
[status-im.persistence.realm.core :as realm]))
|
||||
[status-im.data-store.contacts :as contacts]))
|
||||
|
||||
(defn is-address? [s]
|
||||
(.isAddress js/Web3.prototype s))
|
||||
|
||||
(defn unique-identity? [identity]
|
||||
(not (realm/exists? :account :contact {:whisper-identity identity})))
|
||||
(not (contacts/exists? identity)))
|
||||
|
||||
(defn valid-length? [identity]
|
||||
(let [length (count identity)]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
(ns status-im.data-store.accounts
|
||||
(:require [status-im.data-store.realm.accounts :as data-store]))
|
||||
|
||||
(defn get-all []
|
||||
(data-store/get-all-as-list))
|
||||
|
||||
(defn get-by-address [address]
|
||||
(data-store/get-by-address address))
|
||||
|
||||
(defn save [account update?]
|
||||
(data-store/save account update?))
|
||||
|
||||
(defn save-all [accounts update?]
|
||||
(data-store/save-all accounts update?))
|
|
@ -0,0 +1,73 @@
|
|||
(ns status-im.data-store.chats
|
||||
(:require [status-im.data-store.realm.chats :as data-store]
|
||||
[re-frame.core :refer [dispatch]])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(defn- normalize-contacts
|
||||
[chats]
|
||||
(map #(update % :contacts vals) chats))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(-> (data-store/get-all-active)
|
||||
normalize-contacts))
|
||||
|
||||
(defn get-by-id
|
||||
[id]
|
||||
(data-store/get-by-id id))
|
||||
|
||||
(defn exists?
|
||||
[chat-id]
|
||||
(data-store/exists? chat-id))
|
||||
|
||||
(defn save
|
||||
[{:keys [last-message-id chat-id] :as chat}]
|
||||
(let [chat (assoc chat :last-message-id (or last-message-id ""))]
|
||||
(data-store/save chat (data-store/exists? chat-id))))
|
||||
|
||||
(defn delete
|
||||
[chat-id]
|
||||
(data-store/delete chat-id))
|
||||
|
||||
(defn get-contacts
|
||||
[chat-id]
|
||||
(data-store/get-contacts chat-id))
|
||||
|
||||
(defn has-contact?
|
||||
[chat-id identity]
|
||||
(data-store/has-contact? chat-id identity))
|
||||
|
||||
(defn add-contacts
|
||||
[chat-id identities]
|
||||
(data-store/add-contacts chat-id identities)
|
||||
; TODO: move this somewhere else
|
||||
; TODO: temp. Update chat in db atom
|
||||
(dispatch [:initialize-chats]))
|
||||
|
||||
(defn remove-contacts
|
||||
[chat-id identities]
|
||||
(data-store/remove-contacts chat-id identities))
|
||||
|
||||
(defn save-property
|
||||
[chat-id property-name value]
|
||||
(data-store/save-property chat-id property-name value))
|
||||
|
||||
(defn get-property
|
||||
[chat-id property-name]
|
||||
(data-store/get-property chat-id property-name))
|
||||
|
||||
(defn is-active?
|
||||
[chat-id]
|
||||
(get-property chat-id :is-active))
|
||||
|
||||
(defn removed-at
|
||||
[chat-id]
|
||||
(get-property chat-id :removed-at))
|
||||
|
||||
(defn get-active-group-chats
|
||||
[]
|
||||
(data-store/get-active-group-chats))
|
||||
|
||||
(defn set-active
|
||||
[chat-id active?]
|
||||
(save-property chat-id :is-active active?))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.commands
|
||||
(:require [status-im.data-store.realm.commands :as data-store]))
|
||||
|
||||
(defn get-by-chat-id
|
||||
[chat-id]
|
||||
(data-store/get-by-chat-id chat-id))
|
||||
|
||||
(defn save
|
||||
[command]
|
||||
(data-store/save command))
|
|
@ -0,0 +1,28 @@
|
|||
(ns status-im.data-store.contacts
|
||||
(:require [status-im.data-store.realm.contacts :as data-store])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(data-store/get-all-as-list))
|
||||
|
||||
(defn get-by-id
|
||||
[whisper-identity]
|
||||
(data-store/get-by-id whisper-identity))
|
||||
|
||||
(defn save
|
||||
[{:keys [whisper-identity pending] :as contact}]
|
||||
(let [{pending-db :pending
|
||||
:as contact-db} (data-store/get-by-id whisper-identity)
|
||||
contact (assoc contact :pending (boolean (if contact-db
|
||||
(and pending-db pending)
|
||||
pending)))]
|
||||
(data-store/save contact (if contact-db true false))))
|
||||
|
||||
(defn save-all
|
||||
[contacts]
|
||||
(mapv save contacts))
|
||||
|
||||
(defn exists?
|
||||
[whisper-identity]
|
||||
(data-store/exists? whisper-identity))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.core
|
||||
(:require [taoensso.timbre :as log]
|
||||
[status-im.data-store.realm.core :as data-source]))
|
||||
|
||||
|
||||
(defn init []
|
||||
(data-source/reset-account))
|
||||
|
||||
(defn change-account [address new-account? handler]
|
||||
(data-source/change-account address new-account? handler))
|
|
@ -0,0 +1,23 @@
|
|||
(ns status-im.data-store.discovery
|
||||
(:require [status-im.data-store.realm.discovery :as data-store]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(->> (data-store/get-all-as-list)
|
||||
(mapv #(update % :tags vals))))
|
||||
|
||||
(defn save
|
||||
[discovery]
|
||||
(data-store/save discovery))
|
||||
|
||||
(defn save-all
|
||||
[discoveries]
|
||||
(data-store/save-all discoveries))
|
||||
|
||||
(defn delete
|
||||
[by ordering critical-count to-delete-count]
|
||||
(data-store/delete by ordering critical-count to-delete-count))
|
||||
|
||||
(defn get-all-tags
|
||||
[]
|
||||
(data-store/get-all-tags))
|
|
@ -0,0 +1,92 @@
|
|||
(ns status-im.data-store.messages
|
||||
(:require [status-im.data-store.realm.messages :as data-store]
|
||||
[clojure.string :refer [join split]]
|
||||
[status-im.utils.random :refer [timestamp]]
|
||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||
[status-im.commands.utils :refer [generate-hiccup]]
|
||||
[cljs.reader :refer [read-string]]
|
||||
[status-im.constants :as c])
|
||||
(:refer-clojure :exclude [update]))
|
||||
|
||||
(defn- map-to-str
|
||||
[m]
|
||||
(join ";" (map #(join "=" %) (stringify-keys m))))
|
||||
|
||||
(defn- str-to-map
|
||||
[s]
|
||||
(keywordize-keys (apply hash-map (split s #"[;=]"))))
|
||||
|
||||
(defn- user-statuses-to-map
|
||||
[user-statuses]
|
||||
(->> (vals user-statuses)
|
||||
(mapv (fn [{:keys [whisper-identity] :as status}]
|
||||
[whisper-identity status]))
|
||||
(into {})))
|
||||
|
||||
(defn- command-type?
|
||||
[type]
|
||||
(contains?
|
||||
#{c/content-type-command c/content-type-command-request}
|
||||
type))
|
||||
|
||||
(def default-values
|
||||
{:outgoing false
|
||||
:to nil
|
||||
:same-author false
|
||||
:same-direction false
|
||||
:preview nil})
|
||||
|
||||
(defn get-by-id
|
||||
[message-id]
|
||||
(some-> (data-store/get-by-id message-id)
|
||||
(clojure.core/update :user-statuses user-statuses-to-map)))
|
||||
|
||||
(defn get-by-chat-id
|
||||
([chat-id]
|
||||
(get-by-chat-id chat-id 0))
|
||||
([chat-id from]
|
||||
(->> (data-store/get-by-chat-id chat-id from c/default-number-of-messages)
|
||||
(mapv #(clojure.core/update % :user-statuses user-statuses-to-map))
|
||||
(into '())
|
||||
reverse
|
||||
(keep (fn [{:keys [content-type preview] :as message}]
|
||||
(if (command-type? content-type)
|
||||
(-> message
|
||||
(clojure.core/update :content str-to-map)
|
||||
(assoc :rendered-preview
|
||||
(when preview
|
||||
(generate-hiccup (read-string preview)))))
|
||||
message))))))
|
||||
|
||||
(defn get-last-message
|
||||
[chat-id]
|
||||
(data-store/get-last-message chat-id))
|
||||
|
||||
(defn get-unviewed
|
||||
[]
|
||||
(data-store/get-unviewed))
|
||||
|
||||
(defn save
|
||||
;; todo remove chat-id parameter
|
||||
[chat-id {:keys [message-id content]
|
||||
:as message}]
|
||||
(when-not (data-store/exists? message-id)
|
||||
(let [content' (if (string? content)
|
||||
content
|
||||
(map-to-str content))
|
||||
message' (merge default-values
|
||||
message
|
||||
{:chat-id chat-id
|
||||
:content content'
|
||||
:timestamp (timestamp)})]
|
||||
(data-store/save message'))))
|
||||
|
||||
(defn update
|
||||
[{:keys [message-id] :as message}]
|
||||
(when (data-store/exists? message-id)
|
||||
(let [message (clojure.core/update message :user-statuses vals)]
|
||||
(data-store/save message))))
|
||||
|
||||
(defn delete-by-chat-id [chat-id]
|
||||
(data-store/delete-by-chat-id chat-id))
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
(ns status-im.data-store.pending-messages
|
||||
(:require [status-im.data-store.realm.pending-messages :as data-store]
|
||||
[clojure.string :as str]
|
||||
[status-im.utils.hex :as i]))
|
||||
|
||||
(defn- get-id
|
||||
[message-id to]
|
||||
(let [to' (i/normalize-hex to)
|
||||
to'' (when to' (subs to' 0 7))
|
||||
id' (if to''
|
||||
(str message-id "-" (subs to'' 0 7))
|
||||
message-id)]
|
||||
id'))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(data-store/get-all-as-list))
|
||||
|
||||
(defn get-by-chat-id
|
||||
[chat-id]
|
||||
(data-store/get-by-chat-id chat-id))
|
||||
|
||||
(defn get-by-message-id
|
||||
[message-id]
|
||||
(data-store/get-by-message-id message-id))
|
||||
|
||||
(defn save
|
||||
[{:keys [id to group-id message] :as pending-message}]
|
||||
(let [{:keys [from topics payload]} message
|
||||
id' (get-id id to)
|
||||
chat-id (or group-id to)
|
||||
message' (-> pending-message
|
||||
(assoc :id id'
|
||||
:from from
|
||||
:message-id id
|
||||
:chat-id chat-id
|
||||
:payload payload
|
||||
:topics (prn-str topics))
|
||||
(dissoc :message))]
|
||||
(data-store/save message')))
|
||||
|
||||
(defn delete
|
||||
[pending-message]
|
||||
(data-store/delete pending-message))
|
||||
|
||||
(defn delete-all-by-chat-id
|
||||
[chat-id]
|
||||
(data-store/delete-all-by-chat-id chat-id))
|
|
@ -0,0 +1,21 @@
|
|||
(ns status-im.data-store.realm.accounts
|
||||
(:require [status-im.data-store.realm.core :as realm]))
|
||||
|
||||
(defn get-all []
|
||||
(realm/get-all realm/base-realm :account))
|
||||
|
||||
(defn get-all-as-list []
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-by-address [address]
|
||||
(realm/get-one-by-field-clj realm/base-realm :account :address address))
|
||||
|
||||
(defn save [account update?]
|
||||
(realm/write realm/base-realm
|
||||
#(realm/create realm/base-realm :account account update?)))
|
||||
|
||||
(defn save-all [accounts update?]
|
||||
(realm/write realm/base-realm
|
||||
(fn []
|
||||
(mapv #(realm/create realm/base-realm :account % update?) accounts))))
|
|
@ -0,0 +1,112 @@
|
|||
(ns status-im.data-store.realm.chats
|
||||
(:require [status-im.data-store.realm.core :as realm]
|
||||
[status-im.utils.random :refer [timestamp]])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(-> (realm/get-all @realm/account-realm :chat)
|
||||
(realm/sorted :timestamp :desc)))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-all-active
|
||||
[]
|
||||
(-> (realm/get-by-field @realm/account-realm :chat :is-active true)
|
||||
(realm/sorted :timestamp :desc)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn- groups
|
||||
[active?]
|
||||
(realm/filtered (get-all)
|
||||
(str "group-chat = true && is-active = "
|
||||
(if active? "true" "false"))))
|
||||
|
||||
(defn get-active-group-chats
|
||||
[]
|
||||
(map
|
||||
(fn [{:keys [chat-id public-key private-key]}]
|
||||
{:chat-id chat-id
|
||||
:keypair {:private private-key
|
||||
:public public-key}})
|
||||
(realm/realm-collection->list (groups true))))
|
||||
|
||||
(defn get-by-id
|
||||
[chat-id]
|
||||
(-> (realm/get-one-by-field-clj @realm/account-realm :chat :chat-id chat-id)
|
||||
(realm/list->array :contacts)))
|
||||
|
||||
(defn save
|
||||
[chat update?]
|
||||
(realm/save @realm/account-realm :chat chat update?))
|
||||
|
||||
(defn exists?
|
||||
[chat-id]
|
||||
(realm/exists? @realm/account-realm :chat {:chat-id chat-id}))
|
||||
|
||||
(defn delete
|
||||
[chat-id]
|
||||
(when-let [chat (get-by-id chat-id)]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(doto chat
|
||||
(aset "is-active" false)
|
||||
(aset "removed-at" timestamp))))))
|
||||
|
||||
(defn get-contacts
|
||||
[chat-id]
|
||||
(-> (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)
|
||||
(aget "contacts")))
|
||||
|
||||
(defn has-contact?
|
||||
[chat-id identity]
|
||||
(let [contacts (get-contacts chat-id)
|
||||
contact (.find contacts (fn [object index collection]
|
||||
(= identity (aget object "identity"))))]
|
||||
(if contact true false)))
|
||||
|
||||
(defn- save-contacts
|
||||
[identities contacts added-at]
|
||||
(doseq [contact-identity identities]
|
||||
(if-let [contact (.find contacts (fn [object index collection]
|
||||
(= contact-identity (aget object "identity"))))]
|
||||
(doto contact
|
||||
(aset "is-in-chat" true)
|
||||
(aset "added-at" added-at))
|
||||
(.push contacts (clj->js {:identity contact-identity
|
||||
:added-at added-at})))))
|
||||
|
||||
(defn add-contacts
|
||||
[chat-id identities]
|
||||
(let [contacts (get-contacts chat-id)
|
||||
added-at (timestamp)]
|
||||
(realm/write @realm/account-realm
|
||||
#(save-contacts identities contacts added-at))))
|
||||
|
||||
(defn- delete-contacts
|
||||
[identities contacts]
|
||||
(doseq [contact-identity identities]
|
||||
(when-let [contact (.find contacts (fn [object index collection]
|
||||
(= contact-identity (aget object "identity"))))]
|
||||
(realm/delete @realm/account-realm contact))))
|
||||
|
||||
(defn remove-contacts
|
||||
[chat-id identities]
|
||||
(let [contacts (get-contacts chat-id)]
|
||||
(realm/write @realm/account-realm
|
||||
#(delete-contacts identities contacts))))
|
||||
|
||||
(defn save-property
|
||||
[chat-id property-name value]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(-> (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)
|
||||
(aset (name property-name) value)))))
|
||||
|
||||
(defn get-property
|
||||
[chat-id property]
|
||||
(when-let [chat (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)]
|
||||
(aget chat (name property))))
|
|
@ -0,0 +1,11 @@
|
|||
(ns status-im.data-store.realm.commands
|
||||
(:require [status-im.data-store.realm.core :as realm]))
|
||||
|
||||
(defn get-by-chat-id
|
||||
[chat-id]
|
||||
(realm/get-one-by-field-clj @realm/account-realm :command
|
||||
:chat-id identity))
|
||||
|
||||
(defn save
|
||||
[command]
|
||||
(realm/save @realm/account-realm :command command true))
|
|
@ -0,0 +1,25 @@
|
|||
(ns status-im.data-store.realm.contacts
|
||||
(:require [status-im.data-store.realm.core :as realm])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(-> (realm/get-all @realm/account-realm :contact)
|
||||
(realm/sorted :name :asc)))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-by-id
|
||||
[whisper-identity]
|
||||
(realm/get-one-by-field-clj @realm/account-realm :contact :whisper-identity whisper-identity))
|
||||
|
||||
(defn save
|
||||
[contact update?]
|
||||
(realm/save @realm/account-realm :contact contact update?))
|
||||
|
||||
(defn exists?
|
||||
[whisper-identity]
|
||||
(realm/exists? @realm/account-realm :contact {:whisper-identity whisper-identity}))
|
|
@ -0,0 +1,187 @@
|
|||
(ns status-im.data-store.realm.core
|
||||
(:require [status-im.utils.utils :as u]
|
||||
[status-im.utils.types :refer [to-string]]
|
||||
[status-im.data-store.realm.schemas.account.core :as account]
|
||||
[status-im.data-store.realm.schemas.base.core :as base]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.fs :as fs]
|
||||
[clojure.string :as str])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(def realm-class (u/require "realm"))
|
||||
|
||||
(defn realm-version
|
||||
[file-name]
|
||||
(.schemaVersion realm-class file-name))
|
||||
|
||||
(defn open-realm
|
||||
[options file-name]
|
||||
(let [options (merge options {:path file-name})]
|
||||
(when (cljs.core/exists? js/window)
|
||||
(realm-class. (clj->js options)))))
|
||||
|
||||
(defn close [realm]
|
||||
(.close realm))
|
||||
|
||||
(defn migrate [file-name schemas]
|
||||
(let [current-version (realm-version file-name)]
|
||||
(doseq [schema schemas
|
||||
:when (> (:schemaVersion schema) current-version)
|
||||
:let [migrated-realm (open-realm schema file-name)]]
|
||||
(close migrated-realm))))
|
||||
|
||||
(defn open-migrated-realm
|
||||
[file-name schemas]
|
||||
(migrate file-name schemas)
|
||||
(open-realm (last schemas) file-name))
|
||||
|
||||
(def new-account-filename "new-account")
|
||||
(def new-accout-realm-file (str new-account-filename ".realm"))
|
||||
|
||||
(def base-realm (open-migrated-realm (.-defaultPath realm-class) base/schemas))
|
||||
|
||||
(def account-realm (atom (open-migrated-realm new-account-filename account/schemas)))
|
||||
|
||||
(defn close-account-realm []
|
||||
(close @account-realm)
|
||||
(reset! account-realm nil))
|
||||
|
||||
(defn reset-account []
|
||||
(when @account-realm
|
||||
(close @account-realm))
|
||||
(reset! account-realm (open-migrated-realm new-account-filename account/schemas))
|
||||
(.write @account-realm #(.deleteAll @account-realm)))
|
||||
|
||||
(defn move-file-handler [address err handler]
|
||||
(log/debug "Moved file with error: " err address)
|
||||
(if err
|
||||
(log/error "Error moving account realm: " (.-message err))
|
||||
(reset! account-realm (open-migrated-realm address account/schemas)))
|
||||
(handler err))
|
||||
|
||||
(defn change-account [address new-account? handler]
|
||||
(let [path (.-path @account-realm)]
|
||||
(log/debug "closing account realm: " path)
|
||||
(close-account-realm)
|
||||
(log/debug "is new account? " new-account?)
|
||||
(if new-account?
|
||||
(let [new-path (str/replace path new-accout-realm-file (str address ".realm"))]
|
||||
(log/debug "Moving file to " new-path)
|
||||
(fs/move-file path new-path #(move-file-handler address % handler)))
|
||||
(do
|
||||
(reset! account-realm (open-migrated-realm address account/schemas))
|
||||
(handler nil)))))
|
||||
|
||||
; realm functions
|
||||
|
||||
(defn and-query [queries]
|
||||
(str/join " and " queries))
|
||||
|
||||
(defn or-query [queries]
|
||||
(str/join " or " queries))
|
||||
|
||||
(defn write [realm f]
|
||||
(.write realm f))
|
||||
|
||||
(defn create
|
||||
([realm schema-name obj]
|
||||
(create realm schema-name obj false))
|
||||
([realm schema-name obj update?]
|
||||
(.create realm (to-string schema-name) (clj->js obj) update?)))
|
||||
|
||||
(defn save
|
||||
([realm schema-name obj]
|
||||
(save realm schema-name obj false))
|
||||
([realm schema-name obj update?]
|
||||
(write realm #(create realm schema-name obj update?))))
|
||||
|
||||
(defn save-all
|
||||
([realm schema-name objs]
|
||||
(save-all realm schema-name objs false))
|
||||
([realm schema-name objs update?]
|
||||
(write realm (fn []
|
||||
(mapv #(save realm schema-name % update?) objs)))))
|
||||
|
||||
(defn delete [realm obj]
|
||||
(write realm #(.delete realm obj)))
|
||||
|
||||
(defn get-all [realm schema-name]
|
||||
(.objects realm (to-string schema-name)))
|
||||
|
||||
(defn sorted [results field-name order]
|
||||
(.sorted results (to-string field-name) (if (= order :asc)
|
||||
false
|
||||
true)))
|
||||
|
||||
(defn get-count [objs]
|
||||
(.-length objs))
|
||||
|
||||
(defn page [results from to]
|
||||
(js/Array.prototype.slice.call results from to))
|
||||
|
||||
(defn filtered [results filter-query]
|
||||
(.filtered results filter-query))
|
||||
|
||||
(defn realm-collection->list [collection]
|
||||
(-> (.map collection (fn [object _ _] object))
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn list->array [record list-field]
|
||||
(update-in record [list-field] (comp vec vals)))
|
||||
|
||||
(defn single [result]
|
||||
(-> (aget result 0)))
|
||||
|
||||
(defn single-cljs [result]
|
||||
(some-> (aget result 0)
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn get-by-filter [realm schema-name filter]
|
||||
(-> (.objects realm (name schema-name))
|
||||
(.filtered filter)))
|
||||
|
||||
(defn- get-schema-by-name [opts]
|
||||
(->> opts
|
||||
(mapv (fn [{:keys [name] :as schema}]
|
||||
[(keyword name) schema]))
|
||||
(into {})))
|
||||
|
||||
(defn- field-type [realm schema-name field]
|
||||
(let [schema-by-name (get-schema-by-name (js->clj (.-schema realm) :keywordize-keys true))
|
||||
field-def (get-in schema-by-name [schema-name :properties field])]
|
||||
(if (map? field-def)
|
||||
(:type field-def)
|
||||
field-def)))
|
||||
|
||||
(defmulti to-query (fn [realm schema-name operator field value]
|
||||
operator))
|
||||
|
||||
(defmethod to-query :eq [realm schema-name operator field value]
|
||||
(let [value (to-string value)
|
||||
field-type (field-type realm schema-name field)
|
||||
query (str (name field) "=" (if (= "string" (name field-type))
|
||||
(str "\"" value "\"")
|
||||
value))]
|
||||
query))
|
||||
|
||||
(defn get-by-field [realm schema-name field value]
|
||||
(let [q (to-query realm schema-name :eq field value)]
|
||||
(.filtered (.objects realm (name schema-name)) q)))
|
||||
|
||||
(defn get-one-by-field [realm schema-name field value]
|
||||
(single (get-by-field realm schema-name field value)))
|
||||
|
||||
(defn get-one-by-field-clj [realm schema-name field value]
|
||||
(single-cljs (get-by-field realm schema-name field value)))
|
||||
|
||||
(defn get-by-fields [realm schema-name op fields]
|
||||
(let [queries (map (fn [[k v]]
|
||||
(to-query realm schema-name :eq k v))
|
||||
fields)]
|
||||
(.filtered (.objects realm (name schema-name))
|
||||
(case op
|
||||
:and (and-query queries)
|
||||
:or (or-query queries)))))
|
||||
|
||||
(defn exists? [realm schema-name fields]
|
||||
(pos? (.-length (get-by-fields realm schema-name :and fields))))
|
|
@ -0,0 +1,73 @@
|
|||
(ns status-im.data-store.realm.discovery
|
||||
(:require [status-im.data-store.realm.core :as realm]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(-> (realm/get-all @realm/account-realm :discovery)
|
||||
(realm/sorted :priority :desc)))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-tag-by-name [tag]
|
||||
(log/debug "Getting tag: " tag)
|
||||
(realm/get-one-by-field-clj @realm/account-realm :tag :name tag))
|
||||
|
||||
(defn- update-tag-counter [func tag]
|
||||
(let [tag (:name tag)
|
||||
tag-object (get-tag-by-name tag)]
|
||||
(if tag-object
|
||||
(realm/create @realm/account-realm :tag
|
||||
{:name tag
|
||||
:count (func (:count tag-object))}
|
||||
true))))
|
||||
|
||||
(defn- update-tags-counter [func tags]
|
||||
(doseq [tag (distinct tags)]
|
||||
(update-tag-counter func tag)))
|
||||
|
||||
(defn- get-tags
|
||||
[message-id]
|
||||
(-> (realm/get-one-by-field-clj @realm/account-realm :discovery :message-id message-id)
|
||||
(:tags)
|
||||
(vals)))
|
||||
|
||||
(defn- upsert-discovery [{:keys [message-id tags] :as discovery}]
|
||||
(log/debug "Creating/updating discovery with tags: " tags)
|
||||
(let [prev-tags (get-tags message-id)]
|
||||
(if prev-tags
|
||||
(update-tags-counter dec prev-tags))
|
||||
(realm/create @realm/account-realm :discovery discovery true)
|
||||
(update-tags-counter inc tags)))
|
||||
|
||||
(defn save
|
||||
[discovery]
|
||||
(realm/write @realm/account-realm
|
||||
#(upsert-discovery discovery)))
|
||||
|
||||
(defn save-all
|
||||
[discoveries]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(doseq [discovery discoveries]
|
||||
(upsert-discovery discovery)))))
|
||||
|
||||
(defn delete
|
||||
[by ordering critical-count to-delete-count]
|
||||
(let [discoveries (realm/get-all @realm/account-realm :discovery)
|
||||
count (realm/get-count discoveries)]
|
||||
(if (> count critical-count)
|
||||
(let [to-delete (-> (realm/sorted discoveries by ordering)
|
||||
(realm/page 0 to-delete-count))]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(log/debug (str "Deleting " (realm/get-count to-delete) " discoveries"))
|
||||
(realm/delete @realm/account-realm to-delete)))))))
|
||||
|
||||
(defn get-all-tags []
|
||||
(-> (realm/get-all @realm/account-realm :tag)
|
||||
(realm/sorted :count :desc)
|
||||
realm/realm-collection->list))
|
|
@ -0,0 +1,55 @@
|
|||
(ns status-im.data-store.realm.messages
|
||||
(:require [status-im.data-store.realm.core :as realm])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(realm/get-all @realm/account-realm :message))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-by-id
|
||||
[message-id]
|
||||
(realm/get-one-by-field-clj @realm/account-realm :message :message-id message-id))
|
||||
|
||||
(defn get-by-chat-id
|
||||
([chat-id]
|
||||
(realm/get-by-field @realm/account-realm :message :chat-id chat-id))
|
||||
([chat-id number-of-messages]
|
||||
(get-by-chat-id chat-id 0 number-of-messages))
|
||||
([chat-id from number-of-messages]
|
||||
(-> (realm/get-by-field @realm/account-realm :message :chat-id chat-id)
|
||||
(realm/sorted :timestamp :desc)
|
||||
(realm/page from (+ from number-of-messages))
|
||||
(realm/realm-collection->list))))
|
||||
|
||||
(defn get-last-message
|
||||
[chat-id]
|
||||
(-> (realm/get-by-field @realm/account-realm :message :chat-id chat-id)
|
||||
(realm/sorted :timestamp :desc)
|
||||
(realm/single)
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn get-unviewed
|
||||
[]
|
||||
(-> (realm/get-by-fields @realm/account-realm :message :and {:outgoing false
|
||||
:message-status nil})
|
||||
(realm/realm-collection->list)))
|
||||
|
||||
(defn exists?
|
||||
[message-id]
|
||||
(realm/exists? @realm/account-realm :message {:message-id message-id}))
|
||||
|
||||
(defn save
|
||||
[message]
|
||||
(realm/save @realm/account-realm :message message true))
|
||||
|
||||
(defn delete-by-chat-id
|
||||
[chat-id]
|
||||
(realm/write @realm/account-realm
|
||||
#(realm/delete @realm/account-realm
|
||||
(get-by-chat-id chat-id))))
|
|
@ -0,0 +1,35 @@
|
|||
(ns status-im.data-store.realm.pending-messages
|
||||
(:require [status-im.data-store.realm.core :as realm]
|
||||
[cljs.reader :refer [read-string]]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(realm/get-all @realm/account-realm :pending-message))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(->> (get-all)
|
||||
realm/realm-collection->list
|
||||
(map (fn [message]
|
||||
(update message :topics read-string)))))
|
||||
|
||||
(defn get-by-message-id
|
||||
[message-id]
|
||||
(realm/get-by-field @realm/account-realm :pending-message :message-id message-id))
|
||||
|
||||
(defn get-by-chat-id
|
||||
[chat-id]
|
||||
(realm/get-by-field @realm/account-realm :pending-message :chat-id chat-id))
|
||||
|
||||
(defn save
|
||||
[pending-message]
|
||||
(realm/save @realm/account-realm :pending-message pending-message true))
|
||||
|
||||
(defn delete
|
||||
[{{:keys [message-id ack-of-message]} :payload}]
|
||||
(let [message-id (or ack-of-message message-id)]
|
||||
(realm/delete @realm/account-realm (get-by-message-id message-id))))
|
||||
|
||||
(defn delete-all-by-chat-id
|
||||
[chat-id]
|
||||
(realm/delete @realm/account-realm (get-by-chat-id chat-id)))
|
|
@ -0,0 +1,40 @@
|
|||
(ns status-im.data-store.realm.requests
|
||||
(:require [status-im.data-store.realm.core :as realm]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(realm/get-all @realm/account-realm :request))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(-> (get-all)
|
||||
realm/realm-collection->list))
|
||||
|
||||
(defn get-open-by-chat-id
|
||||
[chat-id]
|
||||
(-> (realm/get-by-fields @realm/account-realm :request :and [[:chat-id chat-id]
|
||||
[:status "open"]])
|
||||
(realm/sorted :added :desc)
|
||||
(realm/realm-collection->list)))
|
||||
|
||||
(defn save
|
||||
[request]
|
||||
(realm/save @realm/account-realm :request request true))
|
||||
|
||||
(defn save-all
|
||||
[requests]
|
||||
(realm/save-all @realm/account-realm :request requests true))
|
||||
|
||||
(defn- get-by-message-id
|
||||
[chat-id message-id]
|
||||
(-> (realm/get-by-fields @realm/account-realm :request :and [[:chat-id chat-id]
|
||||
[:message-id message-id]])
|
||||
(realm/single)))
|
||||
|
||||
(defn mark-as-answered
|
||||
[chat-id message-id]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(-> (get-by-message-id chat-id message-id)
|
||||
(.-status)
|
||||
(set! "answered")))))
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im.data-store.realm.schemas.account.core
|
||||
(:require [status-im.data-store.realm.schemas.account.v1.core :as v1]))
|
||||
|
||||
; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
:schemaVersion 1
|
||||
:migration v1/migration}])
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.chat-contact
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :chat-contact
|
||||
:properties {:identity "string"
|
||||
:is-in-chat {:type "bool"
|
||||
:default true}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating chat-contact schema"))
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.chat
|
||||
(:require [taoensso.timbre :as log]
|
||||
[status-im.components.styles :refer [default-chat-color]]))
|
||||
|
||||
(def schema {:name :chat
|
||||
:primaryKey :chat-id
|
||||
:properties {:chat-id "string"
|
||||
:name "string"
|
||||
:color {:type "string"
|
||||
:default default-chat-color}
|
||||
:group-chat {:type "bool"
|
||||
:indexed true}
|
||||
:is-active "bool"
|
||||
:timestamp "int"
|
||||
:contacts {:type "list"
|
||||
:objectType "chat-contact"}
|
||||
:dapp-url {:type :string
|
||||
:optional true}
|
||||
:dapp-hash {:type :int
|
||||
:optional true}
|
||||
:removed-at {:type :int
|
||||
:optional true}
|
||||
:last-message-id "string"
|
||||
:public-key {:type :string
|
||||
:optional true}
|
||||
:private-key {:type :string
|
||||
:optional true}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating chat schema"))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.command
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :command
|
||||
:primaryKey :chat-id
|
||||
:properties {:chat-id "string"
|
||||
:file "string"}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating command schema"))
|
|
@ -0,0 +1,21 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.contact
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :contact
|
||||
:primaryKey :whisper-identity
|
||||
:properties {:address {:type "string" :optional true}
|
||||
:whisper-identity "string"
|
||||
:name {:type "string" :optional true}
|
||||
:photo-path {:type "string" :optional true}
|
||||
:last-updated {:type "int" :default 0}
|
||||
:last-online {:type "int" :default 0}
|
||||
:pending {:type "bool" :default false}
|
||||
:public-key {:type :string
|
||||
:optional true}
|
||||
:private-key {:type :string
|
||||
:optional true}
|
||||
:dapp? {:type :bool
|
||||
:default false}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating contact schema"))
|
|
@ -0,0 +1,39 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.core
|
||||
(:require [status-im.data-store.realm.schemas.account.v1.chat :as chat]
|
||||
[status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact]
|
||||
[status-im.data-store.realm.schemas.account.v1.command :as command]
|
||||
[status-im.data-store.realm.schemas.account.v1.contact :as contact]
|
||||
[status-im.data-store.realm.schemas.account.v1.discovery :as discovery]
|
||||
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
||||
[status-im.data-store.realm.schemas.account.v1.message :as message]
|
||||
[status-im.data-store.realm.schemas.account.v1.pending-message :as pending-message]
|
||||
[status-im.data-store.realm.schemas.account.v1.request :as request]
|
||||
[status-im.data-store.realm.schemas.account.v1.tag :as tag]
|
||||
[status-im.data-store.realm.schemas.account.v1.user-status :as user-status]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [chat/schema
|
||||
chat-contact/schema
|
||||
command/schema
|
||||
contact/schema
|
||||
discovery/schema
|
||||
kv-store/schema
|
||||
message/schema
|
||||
pending-message/schema
|
||||
request/schema
|
||||
tag/schema
|
||||
user-status/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v1 account database: " old-realm new-realm)
|
||||
(chat/migration old-realm new-realm)
|
||||
(chat-contact/migration old-realm new-realm)
|
||||
(command/migration old-realm new-realm)
|
||||
(contact/migration old-realm new-realm)
|
||||
(discovery/migration old-realm new-realm)
|
||||
(kv-store/migration old-realm new-realm)
|
||||
(message/migration old-realm new-realm)
|
||||
(pending-message/migration old-realm new-realm)
|
||||
(request/migration old-realm new-realm)
|
||||
(tag/migration old-realm new-realm)
|
||||
(user-status/migration old-realm new-realm))
|
|
@ -0,0 +1,17 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.discovery
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :discovery
|
||||
:primaryKey :message-id
|
||||
:properties {:message-id "string"
|
||||
:name {:type "string" :optional true}
|
||||
:status "string"
|
||||
:whisper-id "string"
|
||||
:photo-path {:type "string" :optional true}
|
||||
:tags {:type "list"
|
||||
:objectType "tag"}
|
||||
:priority {:type "int" :default 0}
|
||||
:last-updated "date"}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating discovery schema"))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.kv-store
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :kv-store
|
||||
:primaryKey :key
|
||||
:properties {:key "string"
|
||||
:value "string"}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating kv-store schema"))
|
|
@ -0,0 +1,32 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.message
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :message
|
||||
:primaryKey :message-id
|
||||
:properties {:message-id "string"
|
||||
:from "string"
|
||||
:to {:type "string"
|
||||
:optional true}
|
||||
:group-id {:type "string"
|
||||
:optional true}
|
||||
:content "string" ;; TODO make it ArrayBuffer
|
||||
:content-type "string"
|
||||
:timestamp "int"
|
||||
:chat-id {:type "string"
|
||||
:indexed true}
|
||||
:outgoing "bool"
|
||||
:retry-count {:type :int
|
||||
:default 0}
|
||||
:same-author "bool"
|
||||
:same-direction "bool"
|
||||
:preview {:type :string
|
||||
:optional true}
|
||||
:message-type {:type :string
|
||||
:optional true}
|
||||
:message-status {:type :string
|
||||
:optional true}
|
||||
:user-statuses {:type :list
|
||||
:objectType "user-status"}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating message schema"))
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.pending-message
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :pending-message
|
||||
:primaryKey :id
|
||||
:properties {:id :string
|
||||
:message-id :string
|
||||
:chat-id {:type :string
|
||||
:optional true}
|
||||
:ack? :bool
|
||||
:requires-ack? :bool
|
||||
:from :string
|
||||
:to {:type :string
|
||||
:optional true}
|
||||
:payload :string
|
||||
:type :string
|
||||
:topics :string
|
||||
:attempts :int
|
||||
:was-sent? :bool}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating pending-message schema"))
|
|
@ -0,0 +1,13 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.request
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :request
|
||||
:properties {:message-id :string
|
||||
:chat-id :string
|
||||
:type :string
|
||||
:status {:type :string
|
||||
:default "open"}
|
||||
:added :date}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating request schema"))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.tag
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :tag
|
||||
:primaryKey :name
|
||||
:properties {:name "string"
|
||||
:count {:type "int" :optional true :default 0}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating tag schema"))
|
|
@ -0,0 +1,12 @@
|
|||
(ns status-im.data-store.realm.schemas.account.v1.user-status
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :user-status
|
||||
:primaryKey :id
|
||||
:properties {:id "string"
|
||||
:whisper-identity {:type "string"
|
||||
:default ""}
|
||||
:status "string"}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating user-status schema"))
|
|
@ -0,0 +1,7 @@
|
|||
(ns status-im.data-store.realm.schemas.base.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v1.core :as v1]))
|
||||
|
||||
; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
:schemaVersion 1
|
||||
:migration v1/migration}])
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v1.account
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address "string"
|
||||
:public-key "string"
|
||||
:updates-public-key {:type :string
|
||||
:optional true}
|
||||
:updates-private-key {:type :string
|
||||
:optional true}
|
||||
:name {:type "string" :optional true}
|
||||
:phone {:type "string" :optional true}
|
||||
:email {:type "string" :optional true}
|
||||
:status {:type "string" :optional true}
|
||||
:photo-path "string"
|
||||
:last-updated {:type "int" :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating account schema"))
|
|
@ -0,0 +1,12 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v1.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v1.account :as account]
|
||||
[status-im.data-store.realm.schemas.base.v1.kv-store :as kv-store]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [account/schema
|
||||
kv-store/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v1 base database: " old-realm new-realm)
|
||||
(account/migration old-realm new-realm)
|
||||
(kv-store/migration old-realm new-realm))
|
|
@ -0,0 +1,10 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v1.kv-store
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :kv-store
|
||||
:primaryKey :key
|
||||
:properties {:key "string"
|
||||
:value "string"}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating kv-store schema"))
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.data-store.requests
|
||||
(:require [status-im.data-store.realm.requests :as data-store]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(data-store/get-all-as-list))
|
||||
|
||||
(defn get-open-by-chat-id
|
||||
[chat-id]
|
||||
(data-store/get-open-by-chat-id chat-id))
|
||||
|
||||
(defn save
|
||||
[request]
|
||||
(data-store/save request))
|
||||
|
||||
(defn save-all
|
||||
[requests]
|
||||
(data-store/save-all requests))
|
||||
|
||||
(defn mark-as-answered
|
||||
[chat-id message-id]
|
||||
(data-store/mark-as-answered chat-id message-id))
|
|
@ -4,7 +4,7 @@
|
|||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.navigation.handlers :as nav]
|
||||
[status-im.discovery.model :as discoveries]
|
||||
[status-im.data-store.discovery :as discoveries]
|
||||
[status-im.utils.handlers :as u]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.random :as random]))
|
||||
|
@ -28,11 +28,11 @@
|
|||
(defmethod nav/preload-data! :discovery
|
||||
[{:keys [discoveries] :as db} _]
|
||||
(-> db
|
||||
(assoc :tags (discoveries/all-tags))
|
||||
(assoc :tags (discoveries/get-all-tags))
|
||||
;; todo add limit
|
||||
;; todo hash-map with whisper-id as key and sorted by last-update
|
||||
;; may be more efficient here
|
||||
(assoc :discoveries (discoveries/discovery-list))))
|
||||
(assoc :discoveries (discoveries/get-all))))
|
||||
|
||||
(register-handler :discovery-response-received
|
||||
(u/side-effect!
|
||||
|
@ -85,11 +85,11 @@
|
|||
|
||||
(defn save-discovery!
|
||||
[{:keys [new-discovery]} _]
|
||||
(discoveries/save-discoveries [new-discovery]))
|
||||
(discoveries/save new-discovery))
|
||||
|
||||
(defn reload-tags!
|
||||
[db _]
|
||||
(assoc db :tags (discoveries/all-tags)))
|
||||
(assoc db :tags (discoveries/get-all-tags)))
|
||||
|
||||
(register-handler :add-discovery
|
||||
(-> add-discovery
|
||||
|
@ -100,4 +100,4 @@
|
|||
:remove-old-discoveries!
|
||||
(u/side-effect!
|
||||
(fn [_ _]
|
||||
(discoveries/remove-discoveries! :priority :asc 1000 200))))
|
||||
(discoveries/delete :priority :asc 1000 200))))
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
(ns status-im.discovery.model
|
||||
(:require [taoensso.timbre :as log]
|
||||
[status-im.persistence.realm.core :as r]))
|
||||
|
||||
(defn get-tag [tag]
|
||||
(log/debug "Getting tag: " tag)
|
||||
(-> (r/get-by-field :account :tag :name tag)
|
||||
(r/single-cljs)))
|
||||
|
||||
(defn update-tag-counter [func tag]
|
||||
(let [tag (:name tag)
|
||||
tag-object (get-tag tag)]
|
||||
(if tag-object
|
||||
(r/create :account :tag
|
||||
{:name tag
|
||||
:count (func (:count tag-object))}
|
||||
true))))
|
||||
|
||||
(defn update-tags-counter [func tags]
|
||||
(doseq [tag (distinct tags)]
|
||||
(update-tag-counter func tag)))
|
||||
|
||||
(defn get-tags [message-id]
|
||||
(-> (r/get-by-field :account :discovery :message-id message-id)
|
||||
(r/single-cljs)
|
||||
(:tags)
|
||||
(vals)))
|
||||
|
||||
(defn- upsert-discovery [{:keys [message-id tags] :as discovery}]
|
||||
(log/debug "Creating/updating discovery with tags: " tags)
|
||||
(let [prev-tags (get-tags message-id)]
|
||||
(if prev-tags
|
||||
(update-tags-counter dec prev-tags))
|
||||
(r/create :account :discovery discovery true)
|
||||
(update-tags-counter inc tags)))
|
||||
|
||||
(defn discovery-list []
|
||||
(->> (-> (r/get-all :account :discovery)
|
||||
(r/sorted :priority :desc)
|
||||
(r/realm-collection->list))
|
||||
(mapv #(update % :tags vals))))
|
||||
|
||||
(defn- add-discoveries [discoveries]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(doseq [discovery discoveries]
|
||||
(upsert-discovery discovery)))))
|
||||
|
||||
(defn save-discoveries [discoveries]
|
||||
(add-discoveries discoveries))
|
||||
|
||||
(defn remove-discoveries! [by ordering critical-count to-delete-count]
|
||||
(let [objs (r/get-all :account :discovery)
|
||||
count (r/get-count objs)]
|
||||
(if (> count critical-count)
|
||||
(let [to-delete (-> (r/sorted objs by ordering)
|
||||
(r/page 0 to-delete-count))]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(log/debug (str "Deleting " (r/get-count to-delete) " discoveries"))
|
||||
(r/delete :account to-delete)))))))
|
||||
|
||||
(defn all-tags []
|
||||
(-> (r/get-all :account :tag)
|
||||
(r/sorted :count :desc)
|
||||
r/realm-collection->list))
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
(ns status-im.group-settings.handlers
|
||||
(:require [re-frame.core :refer [debug dispatch after enrich]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.persistence.realm.core :as r]
|
||||
[status-im.chat.handlers :refer [delete-messages!]]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.models.contacts :as contacts]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.constants :refer [text-content-type]]
|
||||
[status-im.utils.handlers :as u]
|
||||
[status-im.navigation.handlers :as nav]))
|
||||
|
@ -18,11 +17,7 @@
|
|||
|
||||
(defn save-property!
|
||||
[current-chat-id property-name value]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(-> (r/get-by-field :account :chat :chat-id current-chat-id)
|
||||
(r/single)
|
||||
(aset (name property-name) value)))))
|
||||
(chats/save-property current-chat-id property-name value))
|
||||
|
||||
(defn save-chat-property!
|
||||
[db-name property-name]
|
||||
|
@ -80,15 +75,9 @@
|
|||
(update-in db [:chats current-chat-id :contacts]
|
||||
remove-identities selected-participants))
|
||||
|
||||
(defn remove-members-from-realm!
|
||||
(defn remove-members-from-chat!
|
||||
[{:keys [current-chat-id selected-participants] :as db} _]
|
||||
(let [chat (get-in db [:chats current-chat-id])]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(r/create :account
|
||||
:chat
|
||||
(update chat :contacts remove-identities selected-participants)
|
||||
true)))))
|
||||
(chats/remove-contacts current-chat-id selected-participants))
|
||||
|
||||
(defn notify-about-removing!
|
||||
[{:keys [current-chat-id selected-participants]} _]
|
||||
|
@ -103,10 +92,10 @@
|
|||
:content-type text-content-type})
|
||||
|
||||
(defn removed-participant-message [chat-id identity]
|
||||
(let [contact-name (:name (contacts/contact-by-identity identity))]
|
||||
(let [contact-name (:name (contacts/get-by-id identity))]
|
||||
(->> (str "You've removed " (or contact-name identity))
|
||||
(system-message (random/id))
|
||||
(messages/save-message chat-id))))
|
||||
(messages/save chat-id))))
|
||||
|
||||
(defn create-removing-messages!
|
||||
[{:keys [current-chat-id selected-participants]} _]
|
||||
|
@ -122,7 +111,7 @@
|
|||
(-> remove-members
|
||||
;; todo shouldn't this be done only after receiving of the "ack message"
|
||||
;; about the api call that removes participants from the group?
|
||||
((after remove-members-from-realm!))
|
||||
((after remove-members-from-chat!))
|
||||
;; todo uncomment
|
||||
;((after notify-about-removing!))
|
||||
((after create-removing-messages!))
|
||||
|
@ -134,9 +123,9 @@
|
|||
(let [new-identities (map #(hash-map :identity %) selected-participants)]
|
||||
(update db [:chats current-chat-id :contacts] concat new-identities)))
|
||||
|
||||
(defn add-members-to-realm!
|
||||
(defn add-members-to-chat!
|
||||
[{:keys [current-chat-id selected-participants]} _]
|
||||
(chats/chat-add-participants current-chat-id selected-participants))
|
||||
(chats/add-contacts current-chat-id selected-participants))
|
||||
|
||||
(defn notify-about-new-members!
|
||||
[{:keys [current-chat-id selected-participants
|
||||
|
@ -166,6 +155,6 @@
|
|||
(register-handler :add-new-participants
|
||||
;; todo order of operations tbd
|
||||
(-> add-memebers
|
||||
((after add-members-to-realm!))
|
||||
((after add-members-to-chat!))
|
||||
((after notify-about-new-members!))
|
||||
((enrich deselect-members))))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[re-frame.core :refer [after dispatch dispatch-sync debug]]
|
||||
[schema.core :as s :include-macros true]
|
||||
[status-im.db :refer [app-db schema]]
|
||||
[status-im.persistence.realm.core :as realm]
|
||||
[status-im.data-store.core :as data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.crypt :refer [gen-random-bytes]]
|
||||
[status-im.components.status :as status]
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
(register-handler :initialize-db
|
||||
(fn [_ _]
|
||||
(realm/reset-account)
|
||||
(data-store/init)
|
||||
(assoc app-db :current-account-id nil)))
|
||||
|
||||
(register-handler :initialize-account-db
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
[status-im.group-settings.screen :refer [group-settings]]
|
||||
[status-im.profile.screen :refer [profile my-profile]]
|
||||
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
|
||||
status-im.persistence.realm.core
|
||||
status-im.data-store.core
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn orientation->keyword [o]
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
(ns status-im.models.accounts
|
||||
(:require [status-im.persistence.realm.core :as r]))
|
||||
|
||||
(defn get-accounts []
|
||||
(-> (r/get-all :base :account)
|
||||
r/realm-collection->list))
|
||||
|
||||
(defn save-account [update?]
|
||||
#(r/create :base :account % update?))
|
||||
|
||||
(defn save-accounts [accounts update?]
|
||||
(r/write :base #(mapv (save-account update?) accounts)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;----------------------------------------------
|
||||
|
||||
(defn accounts-list []
|
||||
(r/get-all :base :account))
|
||||
|
||||
(defn account-by-address [address]
|
||||
(r/single-cljs (r/get-by-field :base :account :address address)))
|
|
@ -1,141 +0,0 @@
|
|||
(ns status-im.models.chats
|
||||
(:require [clojure.set :refer [difference]]
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[status-im.persistence.realm.core :as r]
|
||||
[status-im.utils.random :as random :refer [timestamp]]
|
||||
[clojure.string :refer [join blank?]]
|
||||
[status-im.constants :refer [content-type-status]]
|
||||
[status-im.models.messages :refer [save-message]]
|
||||
[status-im.persistence.realm-queries :refer [include-query]]))
|
||||
|
||||
(defn chat-name-from-contacts [identities]
|
||||
(let [chat-name (->> identities
|
||||
(map (fn [identity]
|
||||
(-> (r/get-by-field :account :contact :whisper-identity identity)
|
||||
(r/single-cljs)
|
||||
:name)))
|
||||
(filter identity)
|
||||
(join ","))]
|
||||
(when-not (blank? chat-name)
|
||||
chat-name)))
|
||||
|
||||
(defn get-chat-name [chat-id identities]
|
||||
(or (chat-name-from-contacts identities)
|
||||
chat-id))
|
||||
|
||||
(defn chat-exists? [chat-id]
|
||||
(r/exists? :account :chat {:chat-id chat-id}))
|
||||
|
||||
(defn chat-contacts [chat-id]
|
||||
(-> (r/get-by-field :account :chat :chat-id chat-id)
|
||||
(r/single)
|
||||
(aget "contacts")))
|
||||
|
||||
(defn re-join-group-chat [db group-id identities group-name]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(let [new-identities (set identities)
|
||||
only-old-contacts (->> (chat-contacts group-id)
|
||||
(r/cljs-list)
|
||||
(remove (fn [{:keys [identity]}]
|
||||
(new-identities identity))))
|
||||
contacts (->> new-identities
|
||||
(mapv (fn [ident]
|
||||
{:identity ident}))
|
||||
(concat only-old-contacts))]
|
||||
(r/create :account :chat
|
||||
{:chat-id group-id
|
||||
:is-active true
|
||||
:name group-name
|
||||
:contacts contacts} true))))
|
||||
db)
|
||||
|
||||
(defn normalize-contacts
|
||||
[chats]
|
||||
(map #(update % :contacts vals) chats))
|
||||
|
||||
(defn chats-list []
|
||||
(-> (r/get-by-field :account :chat :is-active true)
|
||||
(r/sorted :timestamp :desc)
|
||||
r/realm-collection->list
|
||||
normalize-contacts))
|
||||
|
||||
(defn chat-by-id [chat-id]
|
||||
(-> (r/get-by-field :account :chat :chat-id chat-id)
|
||||
(r/single-cljs)
|
||||
(r/list-to-array :contacts)))
|
||||
|
||||
(defn update-chat [{:keys [last-message-id chat-id] :as chat}]
|
||||
(let [{old-chat-id :chat-id
|
||||
:as old-chat} (chat-by-id chat-id)]
|
||||
(when old-chat-id
|
||||
(let [chat (-> (merge old-chat chat)
|
||||
(assoc chat :last-message-id (or last-message-id "")))]
|
||||
(r/write :account #(r/create :account :chat chat true))))))
|
||||
|
||||
(defn create-chat
|
||||
([{:keys [last-message-id] :as chat}]
|
||||
(let [chat (assoc chat :last-message-id (or last-message-id ""))]
|
||||
(r/write :account #(r/create :account :chat chat true)))))
|
||||
|
||||
(defn chat-add-participants [chat-id identities]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(let [contacts (chat-contacts chat-id)
|
||||
added-at (timestamp)]
|
||||
(doseq [contact-identity identities]
|
||||
(if-let [contact (.find contacts (fn [object index collection]
|
||||
(= contact-identity (aget object "identity"))))]
|
||||
(doto contact
|
||||
(aset "is-in-chat" true)
|
||||
(aset "added-at" added-at))
|
||||
(.push contacts (clj->js {:identity contact-identity
|
||||
:added-at added-at})))))))
|
||||
;; TODO temp. Update chat in db atom
|
||||
(dispatch [:initialize-chats]))
|
||||
|
||||
(defn chat-remove-participants [chat-id identities]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(let [query (include-query :identity identities)
|
||||
chat (r/single (r/get-by-field :account :chat :chat-id chat-id))]
|
||||
(-> (aget chat "contacts")
|
||||
(r/filtered query)
|
||||
(.forEach (fn [object _ _]
|
||||
(r/delete :account object))))))))
|
||||
|
||||
(defn- groups [active?]
|
||||
(r/filtered (r/get-all :account :chat)
|
||||
(str "group-chat = true && is-active = "
|
||||
(if active? "true" "false"))))
|
||||
|
||||
(defn active-group-chats []
|
||||
(map
|
||||
(fn [{:keys [chat-id public-key private-key]}]
|
||||
{:chat-id chat-id
|
||||
:keypair {:private private-key
|
||||
:public public-key}})
|
||||
(r/realm-collection->list (groups true))))
|
||||
|
||||
(defn set-chat-active [chat-id active?]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(-> (r/get-by-field :account :chat :chat-id chat-id)
|
||||
(r/single)
|
||||
(aset "is-active" active?)))))
|
||||
|
||||
(defn get-property [chat-id property]
|
||||
(when-let [chat (r/single (r/get-by-field :account :chat :chat-id chat-id))]
|
||||
(aget chat (name property))))
|
||||
|
||||
(defn is-active? [chat-id]
|
||||
(get-property chat-id :is-active))
|
||||
|
||||
(defn removed-at [chat-id]
|
||||
(get-property chat-id :removed-at))
|
||||
|
||||
(defn contact [chat-id id]
|
||||
(let [contacts (r/cljs-list (chat-contacts chat-id))]
|
||||
(some (fn [{:keys [identity]}]
|
||||
(= id identity))
|
||||
contacts)))
|
|
@ -1,50 +0,0 @@
|
|||
(ns status-im.models.contacts
|
||||
(:require [status-im.persistence.realm.core :as r]
|
||||
[status-im.utils.identicon :refer [identicon]]
|
||||
[status-im.persistence.realm-queries :refer [include-query
|
||||
exclude-query]]))
|
||||
|
||||
(defn get-contacts []
|
||||
(-> (r/get-all :account :contact)
|
||||
(r/sorted :name :asc)
|
||||
r/realm-collection->list))
|
||||
|
||||
(defn get-contact [id]
|
||||
(r/get-one-by-field :account :contact :whisper-identity id))
|
||||
|
||||
(defn create-contact [{:keys [whisper-identity pending] :as contact}]
|
||||
(let [{pending-db :pending
|
||||
:as contact-db} (r/get-one-by-field :account :contact
|
||||
:whisper-identity whisper-identity)
|
||||
contact (assoc contact :pending (boolean (if contact-db
|
||||
(and pending-db pending)
|
||||
pending)))]
|
||||
(r/create :account :contact contact (if contact-db true false))))
|
||||
|
||||
(defn save-contacts [contacts]
|
||||
(r/write :account #(mapv create-contact contacts)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;----------------------------------------------
|
||||
|
||||
(defn contacts-list []
|
||||
(r/sorted (r/get-all :account :contact) :name :asc))
|
||||
|
||||
(defn contacts-list-exclude [exclude-idents]
|
||||
(if (empty? exclude-idents)
|
||||
(contacts-list)
|
||||
(let [query (exclude-query :whisper-identity exclude-idents)]
|
||||
(-> (r/get-all :account :contact)
|
||||
(r/filtered query)
|
||||
(r/sorted :name :asc)))))
|
||||
|
||||
(defn contacts-list-include [include-indents]
|
||||
(if (empty? include-indents)
|
||||
()
|
||||
(let [query (include-query :whisper-identity include-indents)]
|
||||
(-> (r/get-all :account :contact)
|
||||
(r/filtered query)
|
||||
(r/sorted :name :asc)))))
|
||||
|
||||
(defn contact-by-identity [identity]
|
||||
(r/single-cljs (r/get-by-field :account :contact :whisper-identity identity)))
|
|
@ -1,89 +0,0 @@
|
|||
(ns status-im.models.messages
|
||||
(:require [status-im.persistence.realm.core :as r]
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[cljs.reader :refer [read-string]]
|
||||
[status-im.utils.random :refer [timestamp]]
|
||||
[clojure.string :refer [join split]]
|
||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||
[status-im.constants :as c]
|
||||
[status-im.commands.utils :refer [generate-hiccup]]))
|
||||
|
||||
(defn- map-to-str
|
||||
[m]
|
||||
(join ";" (map #(join "=" %) (stringify-keys m))))
|
||||
|
||||
(defn- str-to-map
|
||||
[s]
|
||||
(keywordize-keys (apply hash-map (split s #"[;=]"))))
|
||||
|
||||
(defn- user-statuses-to-map
|
||||
[user-statuses]
|
||||
(->> (vals user-statuses)
|
||||
(mapv (fn [{:keys [whisper-identity] :as status}]
|
||||
[whisper-identity status]))
|
||||
(into {})))
|
||||
|
||||
(def default-values
|
||||
{:outgoing false
|
||||
:to nil
|
||||
:same-author false
|
||||
:same-direction false
|
||||
:preview nil})
|
||||
|
||||
(defn save-message
|
||||
;; todo remove chat-id parameter
|
||||
[chat-id {:keys [message-id content]
|
||||
:as message}]
|
||||
(when-not (r/exists? :account :message {:message-id message-id})
|
||||
(r/write :account
|
||||
(fn []
|
||||
(let [content' (if (string? content)
|
||||
content
|
||||
(map-to-str content))
|
||||
message' (merge default-values
|
||||
message
|
||||
{:chat-id chat-id
|
||||
:content content'
|
||||
:timestamp (timestamp)})]
|
||||
(r/create :account :message message' true))))))
|
||||
|
||||
(defn command-type? [type]
|
||||
(contains?
|
||||
#{c/content-type-command c/content-type-command-request}
|
||||
type))
|
||||
|
||||
(defn get-messages
|
||||
([chat-id] (get-messages chat-id 0))
|
||||
([chat-id from]
|
||||
(->> (-> (r/get-by-field :account :message :chat-id chat-id)
|
||||
(r/sorted :timestamp :desc)
|
||||
(r/page from (+ from c/default-number-of-messages))
|
||||
(r/realm-collection->list))
|
||||
(mapv #(update % :user-statuses user-statuses-to-map))
|
||||
(into '())
|
||||
reverse
|
||||
(keep (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)))))
|
||||
message))))))
|
||||
|
||||
(defn update-message! [{:keys [message-id] :as message}]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(when (r/exists? :account :message {:message-id message-id})
|
||||
(let [message (update message :user-statuses vals)]
|
||||
(r/create :account :message message true))))))
|
||||
|
||||
(defn get-message [id]
|
||||
(some-> (r/get-one-by-field :account :message :message-id id)
|
||||
(update :user-statuses user-statuses-to-map)))
|
||||
|
||||
(defn get-last-message [chat-id]
|
||||
(-> (r/get-by-field :account :message :chat-id chat-id)
|
||||
(r/sorted :timestamp :desc)
|
||||
(r/single)
|
||||
(js->clj :keywordize-keys true)))
|
|
@ -1,60 +0,0 @@
|
|||
(ns status-im.models.pending-messages
|
||||
(:require [status-im.persistence.realm.core :as r]
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[cljs.reader :refer [read-string]]
|
||||
[status-im.utils.random :refer [timestamp]]
|
||||
[clojure.string :refer [join split]]
|
||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||
[status-im.constants :as c]
|
||||
[status-im.utils.types :refer [clj->json json->clj]]
|
||||
[status-im.commands.utils :refer [generate-hiccup]]
|
||||
[cljs.reader :as reader]
|
||||
[clojure.string :as str]
|
||||
[status-im.utils.hex :as i]))
|
||||
|
||||
(defn get-pending-messages! []
|
||||
(->> (r/get-all :account :pending-message)
|
||||
r/realm-collection->list
|
||||
(map (fn [message]
|
||||
(update message :topics reader/read-string)))))
|
||||
|
||||
(defn- get-id
|
||||
[message-id to]
|
||||
(let [to' (i/normalize-hex to)
|
||||
to'' (when to' (subs to' 0 7))
|
||||
id' (if to''
|
||||
(str message-id "-" (subs to'' 0 7))
|
||||
message-id)]
|
||||
id'))
|
||||
|
||||
(defn add-pending-message!
|
||||
[{:keys [id to group-id message] :as pending-message}]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(let [{:keys [from topics payload]} message
|
||||
id' (get-id id to)
|
||||
chat-id (or group-id to)
|
||||
message' (-> pending-message
|
||||
(assoc :id id'
|
||||
:from from
|
||||
:message-id id
|
||||
:chat-id chat-id
|
||||
:payload payload
|
||||
:topics (prn-str topics))
|
||||
(dissoc :message))]
|
||||
(r/create :account :pending-message message' true)))))
|
||||
|
||||
(defn remove-pending-message!
|
||||
[{{:keys [message-id ack-of-message]} :payload}]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(r/delete :account
|
||||
(r/get-by-field :account :pending-message
|
||||
:message-id (or ack-of-message message-id))))))
|
||||
|
||||
(defn remove-all-by-chat [chat-id]
|
||||
(r/write
|
||||
:account
|
||||
(fn []
|
||||
(r/delete :account
|
||||
(r/get-by-field :account :pending-message :chat-id chat-id)))))
|
|
@ -1,21 +0,0 @@
|
|||
(ns status-im.models.requests
|
||||
(:require [status-im.persistence.realm.core :as r]))
|
||||
|
||||
(defn get-requests []
|
||||
(-> (r/get-all :account :request)
|
||||
r/realm-collection->list))
|
||||
|
||||
(defn create-request [request]
|
||||
(r/create :account :request request true))
|
||||
|
||||
(defn save-request [request]
|
||||
(r/write :account
|
||||
(fn []
|
||||
(create-request request))))
|
||||
|
||||
(defn save-requests [requests]
|
||||
(r/write :account #(mapv create-request requests)))
|
||||
|
||||
(defn requests-list []
|
||||
(r/get-all :account :request))
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
[re-frame.core :refer [after dispatch debug enrich]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.components.styles :refer [default-chat-color]]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[clojure.string :as s]
|
||||
[status-im.utils.handlers :as u]
|
||||
[status-im.utils.random :as random]
|
||||
|
@ -54,7 +54,7 @@
|
|||
|
||||
(defn create-chat!
|
||||
[{:keys [new-chat]} _]
|
||||
(chats/create-chat new-chat))
|
||||
(chats/save new-chat))
|
||||
|
||||
(defn show-chat!
|
||||
[{:keys [new-chat]} _]
|
||||
|
@ -105,7 +105,7 @@
|
|||
:public-key public
|
||||
:private-key private
|
||||
:contacts contacts'}]
|
||||
(when (or (not (chats/chat-exists? group-id))
|
||||
(when (or (not (chats/exists? group-id))
|
||||
is-active
|
||||
(> timestamp removed-at))
|
||||
(dispatch [:add-chat group-id (assoc chat :is-active true
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
(ns status-im.persistence.realm.core
|
||||
(: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.fs :as fs]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.persistence.realm.schemas :refer [base account]]
|
||||
[clojure.string :as str])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(def new-account-filename "new-account")
|
||||
|
||||
(def realm-class (u/require "realm"))
|
||||
|
||||
(defn create-account-realm [address]
|
||||
(let [opts (merge account {:path (str address ".realm")})]
|
||||
(when (cljs.core/exists? js/window)
|
||||
(realm-class. (clj->js opts)))))
|
||||
|
||||
(def base-realm
|
||||
(when (cljs.core/exists? js/window)
|
||||
(realm-class. (clj->js base))))
|
||||
|
||||
(def account-realm (atom (create-account-realm new-account-filename)))
|
||||
|
||||
(defn is-new-account? []
|
||||
(let [path (.-path @account-realm)
|
||||
realm_file (str new-account-filename ".realm")]
|
||||
(str/ends-with? path realm_file)))
|
||||
|
||||
(defn realm [schema]
|
||||
(case schema
|
||||
:base base-realm
|
||||
:account @account-realm))
|
||||
|
||||
(defn close [schema]
|
||||
(let [realm-db (realm schema)]
|
||||
(when realm-db
|
||||
(.close realm-db))))
|
||||
|
||||
(defn close-account-realm []
|
||||
(close :account)
|
||||
(reset! account-realm nil))
|
||||
|
||||
(defn reset-account []
|
||||
(when @account-realm
|
||||
(close-account-realm))
|
||||
(reset! account-realm (create-account-realm new-account-filename))
|
||||
(.write @account-realm #(.deleteAll @account-realm)))
|
||||
|
||||
(defn move-file-handler [address err handler]
|
||||
(log/debug "Moved file with error: " err address)
|
||||
(if err
|
||||
(log/error "Error moving account realm: " (.-message err))
|
||||
(reset! account-realm (create-account-realm address)))
|
||||
(handler err))
|
||||
|
||||
(defn change-account-realm [address new-account? handler]
|
||||
(let [path (.-path @account-realm)
|
||||
realm-file (str new-account-filename ".realm")]
|
||||
(log/debug "closing account realm: " path)
|
||||
(close-account-realm)
|
||||
(log/debug "is new account? " new-account?)
|
||||
(if new-account?
|
||||
(let [new-path (str/replace path realm-file (str address ".realm"))]
|
||||
(log/debug "Moving file to " new-path)
|
||||
(fs/move-file path new-path #(move-file-handler address % handler)))
|
||||
(do
|
||||
(reset! account-realm (create-account-realm address))
|
||||
(handler nil)))))
|
||||
|
||||
(defn get-schema-by-name [opts]
|
||||
(->> (:schema opts)
|
||||
(mapv (fn [{:keys [name] :as schema}]
|
||||
[name schema]))
|
||||
(into {})))
|
||||
|
||||
(def schema-by-name
|
||||
{:base (get-schema-by-name base)
|
||||
:account (get-schema-by-name account)})
|
||||
|
||||
(defn field-type [schema schema-name field]
|
||||
(let [schema-by-name (get schema-by-name schema)
|
||||
field-def (get-in schema-by-name [schema-name :properties field])]
|
||||
(if (map? field-def)
|
||||
(:type field-def)
|
||||
field-def)))
|
||||
|
||||
(defn write [schema f]
|
||||
(.write (realm schema) f))
|
||||
|
||||
(defn create
|
||||
([schema schema-name obj]
|
||||
(create schema schema-name obj false))
|
||||
([schema schema-name obj update?]
|
||||
(.create (realm schema) (to-string schema-name) (clj->js obj) update?)))
|
||||
|
||||
(defn create-object
|
||||
[schema schema-name obj]
|
||||
(write schema (fn [] (create schema schema-name obj true))))
|
||||
|
||||
(defn and-query [queries]
|
||||
(str/join " and " queries))
|
||||
|
||||
(defn or-query [queries]
|
||||
(str/join " or " queries))
|
||||
|
||||
(defmulti to-query (fn [schema schema-name operator field value]
|
||||
operator))
|
||||
|
||||
(defmethod to-query :eq [schema schema-name operator field value]
|
||||
(let [value (to-string value)
|
||||
field-type (field-type schema schema-name field)
|
||||
query (str (name field) "=" (if (= "string" (name field-type))
|
||||
(str "\"" value "\"")
|
||||
value))]
|
||||
query))
|
||||
|
||||
(defn get-by-filter [schema schema-name filter]
|
||||
(-> (.objects (realm schema) (name schema-name))
|
||||
(.filtered filter)))
|
||||
|
||||
(defn get-by-field [schema schema-name field value]
|
||||
(let [q (to-query schema schema-name :eq field value)]
|
||||
(.filtered (.objects (realm schema) (name schema-name)) q)))
|
||||
|
||||
(defn get-by-fields [schema schema-name op fields]
|
||||
(let [queries (map (fn [[k v]]
|
||||
(to-query schema schema-name :eq k v))
|
||||
fields)]
|
||||
(.filtered (.objects (realm schema) (name schema-name))
|
||||
(case op
|
||||
:and (and-query queries)
|
||||
:or (or-query queries)))))
|
||||
|
||||
(defn get-all [schema schema-name]
|
||||
(.objects (realm schema) (to-string schema-name)))
|
||||
|
||||
(defn sorted [results field-name order]
|
||||
(.sorted results (to-string field-name) (if (= order :asc)
|
||||
false
|
||||
true)))
|
||||
|
||||
(defn filtered [results filter-query]
|
||||
(.filtered results filter-query))
|
||||
|
||||
(defn page [results from to]
|
||||
(js/Array.prototype.slice.call results from to))
|
||||
|
||||
(defn single [result]
|
||||
(-> (aget result 0)))
|
||||
|
||||
(defn single-cljs [result]
|
||||
(some-> (aget result 0)
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn cljs-list [results]
|
||||
(-> (js->clj results :keywordize-keys true)
|
||||
(vals)))
|
||||
|
||||
(defn list-to-array [record list-field]
|
||||
(update-in record [list-field] (comp vec vals)))
|
||||
|
||||
(defn decode-value [{:keys [key value]}]
|
||||
(read-string value))
|
||||
|
||||
(defn delete [schema obj]
|
||||
(.delete (realm schema) obj))
|
||||
|
||||
(defn exists? [schema schema-name fields]
|
||||
(pos? (.-length (get-by-fields schema schema-name :and fields))))
|
||||
|
||||
(defn get-count [objs]
|
||||
(.-length objs))
|
||||
|
||||
(defn get-list [schema schema-name]
|
||||
(vals (js->clj (.objects (realm schema) (to-string schema-name)) :keywordize-keys true)))
|
||||
|
||||
(defn realm-collection->list [collection]
|
||||
(-> (.map collection (fn [object _ _] object))
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
(defn get-one-by-field [schema schema-name field value]
|
||||
(single-cljs (get-by-field schema schema-name field value)))
|
|
@ -1,147 +0,0 @@
|
|||
(ns status-im.persistence.realm.schemas
|
||||
(:require [status-im.components.styles :refer [default-chat-color]]))
|
||||
|
||||
(def base {:schema [{:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address "string"
|
||||
:public-key "string"
|
||||
:updates-public-key {:type :string
|
||||
:optional true}
|
||||
:updates-private-key {:type :string
|
||||
:optional true}
|
||||
:name {:type "string" :optional true}
|
||||
:phone {:type "string" :optional true}
|
||||
:email {:type "string" :optional true}
|
||||
:status {:type "string" :optional true}
|
||||
:photo-path "string"
|
||||
:last-updated {:type "int" :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}}}
|
||||
{:name :kv-store
|
||||
:primaryKey :key
|
||||
:properties {:key "string"
|
||||
:value "string"}}]
|
||||
:schemaVersion 0})
|
||||
|
||||
(def account {:schema [{:name :contact
|
||||
:primaryKey :whisper-identity
|
||||
:properties {:address {:type "string" :optional true}
|
||||
:whisper-identity "string"
|
||||
:name {:type "string" :optional true}
|
||||
:photo-path {:type "string" :optional true}
|
||||
:last-updated {:type "int" :default 0}
|
||||
:last-online {:type "int" :default 0}
|
||||
:pending {:type "bool" :default false}
|
||||
:public-key {:type :string
|
||||
:optional true}
|
||||
:private-key {:type :string
|
||||
:optional true}
|
||||
:dapp? {:type :bool
|
||||
:default false}}}
|
||||
{:name :request
|
||||
:properties {:message-id :string
|
||||
:chat-id :string
|
||||
:type :string
|
||||
:status {:type :string
|
||||
:default "open"}
|
||||
:added :date}}
|
||||
{:name :tag
|
||||
:primaryKey :name
|
||||
:properties {:name "string"
|
||||
:count {:type "int" :optional true :default 0}}}
|
||||
{:name :discovery
|
||||
:primaryKey :message-id
|
||||
:properties {:message-id "string"
|
||||
:name {:type "string" :optional true}
|
||||
:status "string"
|
||||
:whisper-id "string"
|
||||
:photo-path {:type "string" :optional true}
|
||||
:tags {:type "list"
|
||||
:objectType "tag"}
|
||||
:priority {:type "int" :default 0}
|
||||
:last-updated "date"}}
|
||||
{:name :kv-store
|
||||
:primaryKey :key
|
||||
:properties {:key "string"
|
||||
:value "string"}}
|
||||
{:name :user-status
|
||||
:primaryKey :id
|
||||
:properties {:id "string"
|
||||
:whisper-identity {:type "string"
|
||||
:default ""}
|
||||
:status "string"}}
|
||||
{:name :message
|
||||
:primaryKey :message-id
|
||||
:properties {:message-id "string"
|
||||
:from "string"
|
||||
:to {:type "string"
|
||||
:optional true}
|
||||
:group-id {:type "string"
|
||||
:optional true}
|
||||
:content "string" ;; TODO make it ArrayBuffer
|
||||
:content-type "string"
|
||||
:timestamp "int"
|
||||
:chat-id {:type "string"
|
||||
:indexed true}
|
||||
:outgoing "bool"
|
||||
:retry-count {:type :int
|
||||
:default 0}
|
||||
:same-author "bool"
|
||||
:same-direction "bool"
|
||||
:preview {:type :string
|
||||
:optional true}
|
||||
:message-type {:type :string
|
||||
:optional true}
|
||||
:message-status {:type :string
|
||||
:optional true}
|
||||
:user-statuses {:type :list
|
||||
:objectType "user-status"}}}
|
||||
{:name :pending-message
|
||||
:primaryKey :id
|
||||
:properties {:id :string
|
||||
:message-id :string
|
||||
:chat-id {:type :string
|
||||
:optional true}
|
||||
:ack? :bool
|
||||
:requires-ack? :bool
|
||||
:from :string
|
||||
:to {:type :string
|
||||
:optional true}
|
||||
:payload :string
|
||||
:type :string
|
||||
:topics :string
|
||||
:attempts :int
|
||||
:was-sent? :bool}}
|
||||
{:name :chat-contact
|
||||
:properties {:identity "string"
|
||||
:is-in-chat {:type "bool"
|
||||
:default true}}}
|
||||
{:name :chat
|
||||
:primaryKey :chat-id
|
||||
:properties {:chat-id "string"
|
||||
:name "string"
|
||||
:color {:type "string"
|
||||
:default default-chat-color}
|
||||
:group-chat {:type "bool"
|
||||
:indexed true}
|
||||
:is-active "bool"
|
||||
:timestamp "int"
|
||||
:contacts {:type "list"
|
||||
:objectType "chat-contact"}
|
||||
:dapp-url {:type :string
|
||||
:optional true}
|
||||
:dapp-hash {:type :int
|
||||
:optional true}
|
||||
:removed-at {:type :int
|
||||
:optional true}
|
||||
:last-message-id "string"
|
||||
:public-key {:type :string
|
||||
:optional true}
|
||||
:private-key {:type :string
|
||||
:optional true}}}
|
||||
{:name :command
|
||||
:primaryKey :chat-id
|
||||
:properties {:chat-id "string"
|
||||
:file "string"}}]
|
||||
:schemaVersion 0})
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
(ns status-im.persistence.realm-queries
|
||||
(:require [clojure.string :as s]
|
||||
[status-im.utils.types :refer [to-string]]))
|
||||
|
||||
(defn include-query [field-name values]
|
||||
(->> values
|
||||
(map (fn [val]
|
||||
(str (to-string field-name) " == " (if (string? val)
|
||||
(str "'" val "'")
|
||||
val))))
|
||||
(s/join " || ")))
|
||||
|
||||
(defn exclude-query [field-name values]
|
||||
(->> values
|
||||
(map (fn [val]
|
||||
(str (to-string field-name) " != " (if (string? val)
|
||||
(str "'" val "'")
|
||||
val))))
|
||||
(s/join " && ")))
|
|
@ -2,10 +2,10 @@
|
|||
(:require [status-im.utils.handlers :as u]
|
||||
[re-frame.core :refer [dispatch after]]
|
||||
[status-im.utils.handlers :refer [register-handler]]
|
||||
[status-im.models.contacts :as contacts]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.models.pending-messages :as pending-messages]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.pending-messages :as pending-messages]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.constants :refer [text-content-type]]
|
||||
[status-im.i18n :refer [label]]
|
||||
|
@ -17,7 +17,7 @@
|
|||
(let [{:keys [public-key status updates-public-key
|
||||
updates-private-key]}
|
||||
(get-in db [:accounts current-account-id])]
|
||||
(let [groups (chats/active-group-chats)
|
||||
(let [groups (chats/get-active-group-chats)
|
||||
w3 (protocol/init-whisper!
|
||||
{:rpc-url "http://localhost:8545"
|
||||
:identity public-key
|
||||
|
@ -32,7 +32,7 @@
|
|||
:profile-keypair {:public updates-public-key
|
||||
:private updates-private-key}
|
||||
:hashtags (u/get-hashtags status)
|
||||
:pending-messages (pending-messages/get-pending-messages!)
|
||||
:pending-messages (pending-messages/get-all)
|
||||
:contacts (keep (fn [{:keys [whisper-identity
|
||||
public-key
|
||||
private-key]}]
|
||||
|
@ -40,8 +40,7 @@
|
|||
{:identity whisper-identity
|
||||
:keypair {:public public-key
|
||||
:private private-key}}))
|
||||
|
||||
(contacts/get-contacts))})]
|
||||
(contacts/get-all))})]
|
||||
(assoc db :web3 w3)))))
|
||||
|
||||
(register-handler :incoming-message
|
||||
|
@ -77,40 +76,40 @@
|
|||
:content-type text-content-type})
|
||||
|
||||
(defn joined-chat-message [chat-id from message-id]
|
||||
(let [contact-name (:name (contacts/contact-by-identity from))]
|
||||
(messages/save-message chat-id {:from "system"
|
||||
:message-id (str message-id "_" from)
|
||||
:content (str (or contact-name from) " " (label :t/received-invitation))
|
||||
:content-type text-content-type})))
|
||||
(let [contact-name (:name (contacts/get-by-id from))]
|
||||
(messages/save chat-id {:from "system"
|
||||
:message-id (str message-id "_" from)
|
||||
:content (str (or contact-name from) " " (label :t/received-invitation))
|
||||
:content-type text-content-type})))
|
||||
|
||||
(defn participant-invited-to-group-message [chat-id current-identity identity from message-id]
|
||||
(let [inviter-name (:name (contacts/contact-by-identity from))
|
||||
(let [inviter-name (:name (contacts/get-by-id from))
|
||||
invitee-name (if (= identity current-identity)
|
||||
(label :t/You)
|
||||
(:name (contacts/contact-by-identity identity)))]
|
||||
(messages/save-message chat-id {:from "system"
|
||||
:message-id message-id
|
||||
:content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity))
|
||||
:content-type text-content-type})))
|
||||
(:name (contacts/get-by-id identity)))]
|
||||
(messages/save chat-id {:from "system"
|
||||
:message-id message-id
|
||||
:content (str (or inviter-name from) " " (label :t/invited) " " (or invitee-name identity))
|
||||
:content-type text-content-type})))
|
||||
|
||||
(defn participant-removed-from-group-message [chat-id identity from message-id]
|
||||
(let [remover-name (:name (contacts/contact-by-identity from))
|
||||
removed-name (:name (contacts/contact-by-identity identity))]
|
||||
(let [remover-name (:name (contacts/get-by-id from))
|
||||
removed-name (:name (contacts/get-by-id identity))]
|
||||
(->> (str (or remover-name from) " " (label :t/removed) " " (or removed-name identity))
|
||||
(system-message message-id)
|
||||
(messages/save-message chat-id))))
|
||||
(messages/save chat-id))))
|
||||
|
||||
(defn you-removed-from-group-message [chat-id from message-id]
|
||||
(let [remover-name (:name (contacts/contact-by-identity from))]
|
||||
(let [remover-name (:name (contacts/get-by-id from))]
|
||||
(->> (str (or remover-name from) " " (label :t/removed-from-chat))
|
||||
(system-message message-id)
|
||||
(messages/save-message chat-id))))
|
||||
(messages/save chat-id))))
|
||||
|
||||
(defn participant-left-group-message [chat-id from message-id]
|
||||
(let [left-name (:name (contacts/contact-by-identity from))]
|
||||
(let [left-name (:name (contacts/get-by-id from))]
|
||||
(->> (str (or left-name from) " " (label :t/left))
|
||||
(system-message message-id)
|
||||
(messages/save-message chat-id))))
|
||||
(messages/save chat-id))))
|
||||
|
||||
(register-handler :group-chat-invite-acked
|
||||
(u/side-effect!
|
||||
|
@ -122,7 +121,7 @@
|
|||
(u/side-effect!
|
||||
(fn [_ [action from group-id identity message-id]]
|
||||
(log/debug action message-id from group-id identity)
|
||||
(chats/chat-remove-participants group-id [identity])
|
||||
(chats/remove-contacts group-id [identity])
|
||||
(participant-removed-from-group-message group-id identity from message-id))))
|
||||
|
||||
(register-handler :you-removed-from-group
|
||||
|
@ -130,7 +129,7 @@
|
|||
(fn [_ [action from group-id message-id]]
|
||||
(log/debug action message-id from group-id)
|
||||
(you-removed-from-group-message group-id from message-id)
|
||||
(chats/set-chat-active group-id false))))
|
||||
(chats/set-active group-id false))))
|
||||
|
||||
(register-handler :participant-left-group
|
||||
(u/side-effect!
|
||||
|
@ -153,7 +152,7 @@
|
|||
(register-handler ::remove-identity-from-chat!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ group-id identity]]
|
||||
(chats/chat-remove-participants group-id [identity]))))
|
||||
(chats/remove-contacts group-id [identity]))))
|
||||
|
||||
(register-handler :participant-invited-to-group
|
||||
(u/side-effect!
|
||||
|
@ -167,7 +166,7 @@
|
|||
(register-handler :add-contact-to-group!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ group-id identity]]
|
||||
(when-not (chats/contact group-id identity)
|
||||
(when-not (chats/has-contact? group-id identity)
|
||||
(dispatch [::add-contact group-id identity])
|
||||
(dispatch [::store-contact! group-id identity])))))
|
||||
|
||||
|
@ -178,14 +177,14 @@
|
|||
(register-handler ::store-contact!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ group-id identity]]
|
||||
(chats/chat-add-participants group-id [identity]))))
|
||||
(chats/add-contacts group-id [identity]))))
|
||||
|
||||
(defn save-message-status! [status]
|
||||
(fn [_ [_
|
||||
{:keys [from]
|
||||
{:keys [message-id ack-of-message group-id]} :payload}]]
|
||||
(let [message-id' (or ack-of-message message-id)]
|
||||
(when-let [{:keys [message-status] :as message} (messages/get-message message-id')]
|
||||
(when-let [{:keys [message-status] :as message} (messages/get-by-id message-id')]
|
||||
(when-not (= (keyword message-status) :seen)
|
||||
(let [group? (boolean group-id)
|
||||
message (if (and group? (not= status :sent))
|
||||
|
@ -198,7 +197,7 @@
|
|||
old-status
|
||||
status)}))
|
||||
(assoc message :message-status status))]
|
||||
(messages/update-message! message)))))))
|
||||
(messages/update message)))))))
|
||||
|
||||
|
||||
(defn update-message-status [status]
|
||||
|
@ -242,10 +241,10 @@
|
|||
(register-handler :pending-message-upsert
|
||||
(after
|
||||
(fn [_ [_ {:keys [type id] :as pending-message}]]
|
||||
(pending-messages/add-pending-message! pending-message)
|
||||
(pending-messages/save pending-message)
|
||||
(when (#{:message :group-message} type)
|
||||
(messages/update-message! {:message-id id
|
||||
:delivery-status :pending}))))
|
||||
(messages/update {:message-id id
|
||||
:delivery-status :pending}))))
|
||||
(fn [db [_ {:keys [type id to group-id]}]]
|
||||
(if (#{:message :group-message} type)
|
||||
(let [chat-id (or group-id to)
|
||||
|
@ -258,7 +257,7 @@
|
|||
(register-handler :pending-message-remove
|
||||
(u/side-effect!
|
||||
(fn [_ [_ message]]
|
||||
(pending-messages/remove-pending-message! message))))
|
||||
(pending-messages/delete message))))
|
||||
|
||||
(register-handler :contact-request-received
|
||||
(u/side-effect!
|
||||
|
|
Loading…
Reference in New Issue