Fix topic issue, remove ttt, add db export/import
There were a few issues with topic management: - Topics/ranges were saved one-by-one, which cause an out of memory error on some devices - Topics that were not listened to were saved, and therefore requested from the mailserver, which caused long syncing time It also removes tribute to talk and add export/import methods Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
9bf4da1edd
commit
eba6b63258
1
.env
1
.env
|
@ -28,3 +28,4 @@ MAX_IMAGES_BATCH=5
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||||
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
|
|
1
.env.e2e
1
.env.e2e
|
@ -28,3 +28,4 @@ APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=3
|
VERIFY_TRANSACTION_CHAIN_ID=3
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
COMMUNITIES_MANAGEMENT_ENABLED=0
|
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||||
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
|
|
|
@ -28,3 +28,4 @@ MAX_IMAGES_BATCH=5
|
||||||
GOOGLE_FREE=0
|
GOOGLE_FREE=0
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
COMMUNITIES_MANAGEMENT_ENABLED=0
|
COMMUNITIES_MANAGEMENT_ENABLED=0
|
||||||
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
|
|
|
@ -21,3 +21,4 @@ ENABLE_REFERRAL_INVITE=0
|
||||||
MAX_IMAGES_BATCH=5
|
MAX_IMAGES_BATCH=5
|
||||||
BLANK_PREVIEW=0
|
BLANK_PREVIEW=0
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
|
|
|
@ -75,6 +75,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
private static final String TAG = "StatusModule";
|
private static final String TAG = "StatusModule";
|
||||||
private static final String logsZipFileName = "Status-debug-logs.zip";
|
private static final String logsZipFileName = "Status-debug-logs.zip";
|
||||||
private static final String gethLogFileName = "geth.log";
|
private static final String gethLogFileName = "geth.log";
|
||||||
|
private static final String exportDBFileName = "export.db";
|
||||||
private static final String statusLogFileName = "Status.log";
|
private static final String statusLogFileName = "Status.log";
|
||||||
private static StatusModule module;
|
private static StatusModule module;
|
||||||
private ReactApplicationContext reactContext;
|
private ReactApplicationContext reactContext;
|
||||||
|
@ -193,6 +194,16 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
return logFile;
|
return logFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File getExportDBFile() {
|
||||||
|
final Context context = this.getReactApplicationContext();
|
||||||
|
// Environment.getExternalStoragePublicDirectory doesn't work as expected on Android Q
|
||||||
|
// https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String)
|
||||||
|
final File pubDirectory = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
final File filename = new File(pubDirectory, exportDBFileName);
|
||||||
|
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
private File prepareLogsFile(final Context context) {
|
private File prepareLogsFile(final Context context) {
|
||||||
final File logFile = getLogsFile();
|
final File logFile = getLogsFile();
|
||||||
|
|
||||||
|
@ -398,6 +409,36 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void exportUnencryptedDatabase(final String accountData, final String password) {
|
||||||
|
Log.d(TAG, "login");
|
||||||
|
|
||||||
|
final File newFile = getExportDBFile();
|
||||||
|
|
||||||
|
this.migrateKeyStoreDir(accountData, password);
|
||||||
|
String result = Statusgo.exportUnencryptedDatabase(accountData, password, newFile.getAbsolutePath());
|
||||||
|
if (result.startsWith("{\"error\":\"\"")) {
|
||||||
|
Log.d(TAG, "Login result: " + result);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Login failed: " + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void importUnencryptedDatabase(final String accountData, final String password) {
|
||||||
|
Log.d(TAG, "importUnencryptedDatabase");
|
||||||
|
|
||||||
|
final File newFile = getExportDBFile();
|
||||||
|
|
||||||
|
this.migrateKeyStoreDir(accountData, password);
|
||||||
|
String result = Statusgo.importUnencryptedDatabase(accountData, password, newFile.getAbsolutePath());
|
||||||
|
if (result.startsWith("{\"error\":\"\"")) {
|
||||||
|
Log.d(TAG, "import result: " + result);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "import failed: " + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void logout() {
|
public void logout() {
|
||||||
Log.d(TAG, "logout");
|
Log.d(TAG, "logout");
|
||||||
|
|
|
@ -768,7 +768,21 @@ RCT_EXPORT_METHOD(startLocalNotifications) {
|
||||||
StatusgoStartLocalNotifications();
|
StatusgoStartLocalNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(exportUnencryptedDatabase:(NSString *)accountData
|
||||||
|
password:(NSString *)password) {
|
||||||
|
#if DEBUG
|
||||||
|
NSLog(@"exportUnencryptedDatabase() method called");
|
||||||
|
#endif
|
||||||
|
"";
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(importUnencryptedDatabase:(NSString *)accountData
|
||||||
|
password:(NSString *)password) {
|
||||||
|
#if DEBUG
|
||||||
|
NSLog(@"importUnencryptedDatabase() method called");
|
||||||
|
#endif
|
||||||
|
"";
|
||||||
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
|
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
[status-im.ui.screens.chat.state :as chat.state]
|
[status-im.ui.screens.chat.state :as chat.state]
|
||||||
[status-im.data-store.chats :as data-store.chats]
|
[status-im.data-store.chats :as data-store.chats]
|
||||||
[status-im.data-store.messages :as data-store.messages]
|
[status-im.data-store.messages :as data-store.messages]
|
||||||
[status-im.transport.filters.core :as filters]
|
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.chat.models.reactions :as reactions]
|
[status-im.chat.models.reactions :as reactions]
|
||||||
|
@ -29,10 +28,8 @@
|
||||||
{}
|
{}
|
||||||
new-chats)
|
new-chats)
|
||||||
chats (merge old-chats chats)]
|
chats (merge old-chats chats)]
|
||||||
(fx/merge cofx
|
{:db (assoc db :chats chats
|
||||||
{:db (assoc db :chats chats
|
:chats/loading? false)}))
|
||||||
:chats/loading? false)}
|
|
||||||
(filters/load-filters))))
|
|
||||||
|
|
||||||
(fx/defn handle-chat-visibility-changed
|
(fx/defn handle-chat-visibility-changed
|
||||||
{:events [:chat.ui/message-visibility-changed]}
|
{:events [:chat.ui/message-visibility-changed]}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
[status-im.transport.filters.core :as transport.filters]
|
[status-im.transport.filters.core :as transport.filters]
|
||||||
[status-im.tribute-to-talk.db :as tribute-to-talk]
|
|
||||||
[status-im.tribute-to-talk.whitelist :as whitelist]
|
|
||||||
[status-im.navigation :as navigation]
|
[status-im.navigation :as navigation]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
|
@ -19,19 +17,10 @@
|
||||||
(dissoc % :address)
|
(dissoc % :address)
|
||||||
%))
|
%))
|
||||||
all-contacts)
|
all-contacts)
|
||||||
contacts (into {} contacts-list)
|
contacts (into {} contacts-list)]
|
||||||
tr-to-talk-enabled? (-> db tribute-to-talk/get-settings tribute-to-talk/enabled?)]
|
{:db (cond-> (-> db
|
||||||
(fx/merge cofx
|
(update :contacts/contacts #(merge contacts %))
|
||||||
{:db (cond-> (-> db
|
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts))))}))
|
||||||
(update :contacts/contacts #(merge contacts %))
|
|
||||||
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts)))
|
|
||||||
tr-to-talk-enabled?
|
|
||||||
(assoc :contacts/whitelist (whitelist/get-contact-whitelist all-contacts)))}
|
|
||||||
;; TODO: This is currently called twice, once we load chats & when we load filters.
|
|
||||||
;; For now leaving as it is as the next step is not to have this being called from status-react
|
|
||||||
;; as both contacts & chats are in status-go, but we still need to signals the filters to
|
|
||||||
;; status-react for mailsevers/gaps, so will address separately
|
|
||||||
(transport.filters/load-filters))))
|
|
||||||
|
|
||||||
(defn build-contact
|
(defn build-contact
|
||||||
[{{:keys [multiaccount]
|
[{{:keys [multiaccount]
|
||||||
|
@ -92,7 +81,6 @@
|
||||||
{:db (dissoc db :contacts/new-identity)
|
{:db (dissoc db :contacts/new-identity)
|
||||||
:dispatch [:start-profile-chat public-key]}
|
:dispatch [:start-profile-chat public-key]}
|
||||||
(upsert-contact contact)
|
(upsert-contact contact)
|
||||||
(whitelist/add-to-whitelist public-key)
|
|
||||||
(send-contact-request contact)
|
(send-contact-request contact)
|
||||||
(mailserver/process-next-messages-request)))))
|
(mailserver/process-next-messages-request)))))
|
||||||
|
|
||||||
|
@ -129,17 +117,6 @@
|
||||||
:new-chat-name "")}
|
:new-chat-name "")}
|
||||||
(navigation/navigate-to-cofx :create-group-chat nil)))
|
(navigation/navigate-to-cofx :create-group-chat nil)))
|
||||||
|
|
||||||
(fx/defn set-tribute
|
|
||||||
[{:keys [db] :as cofx} public-key tribute-to-talk]
|
|
||||||
(let [contact (-> (or (build-contact cofx public-key)
|
|
||||||
(get-in db [:contacts/contacts public-key]))
|
|
||||||
(assoc :tribute-to-talk (or tribute-to-talk
|
|
||||||
{:disabled? true})))]
|
|
||||||
{:db (assoc-in db [:contacts/contacts public-key] contact)
|
|
||||||
:insert-identicons [[public-key [:contacts/contacts public-key :identicon]]]
|
|
||||||
:insert-gfycats [[public-key [:contacts/contacts public-key :name]]
|
|
||||||
[public-key [:contacts/contacts public-key :alias]]]}))
|
|
||||||
|
|
||||||
(fx/defn name-verified
|
(fx/defn name-verified
|
||||||
{:events [:contacts/ens-name-verified]}
|
{:events [:contacts/ens-name-verified]}
|
||||||
[{:keys [db now] :as cofx} public-key ens-name]
|
[{:keys [db now] :as cofx} public-key ens-name]
|
||||||
|
|
|
@ -116,20 +116,6 @@
|
||||||
([db public-key]
|
([db public-key]
|
||||||
(active? (get-in db [:contacts/contacts public-key]))))
|
(active? (get-in db [:contacts/contacts public-key]))))
|
||||||
|
|
||||||
;;TODO TTT
|
|
||||||
#_(defn enrich-ttt-contact
|
|
||||||
[{:keys [system-tags tribute-to-talk] :as contact}]
|
|
||||||
(let [tribute (:snt-amount tribute-to-talk)
|
|
||||||
tribute-status (tribute-to-talk.db/tribute-status contact)
|
|
||||||
tribute-label (tribute-to-talk.db/status-label tribute-status tribute)]
|
|
||||||
(-> contact
|
|
||||||
(assoc-in [:tribute-to-talk :tribute-status] tribute-status)
|
|
||||||
(assoc-in [:tribute-to-talk :tribute-label] tribute-label)
|
|
||||||
(assoc :pending? (pending? contact)
|
|
||||||
:blocked? (blocked? contact)
|
|
||||||
:active? (active? contact)
|
|
||||||
:added? (contains? system-tags :contact/added)))))
|
|
||||||
|
|
||||||
(defn enrich-contact
|
(defn enrich-contact
|
||||||
([contact] (enrich-contact contact nil nil))
|
([contact] (enrich-contact contact nil nil))
|
||||||
([{:keys [system-tags public-key] :as contact} setting own-public-key]
|
([{:keys [system-tags public-key] :as contact} setting own-public-key]
|
||||||
|
|
|
@ -2,24 +2,16 @@
|
||||||
(:require [clojure.set :as clojure.set]
|
(:require [clojure.set :as clojure.set]
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.utils.types :as types]
|
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn deserialize-tribute-to-talk [t]
|
|
||||||
(if (seq t)
|
|
||||||
(types/deserialize t)
|
|
||||||
{}))
|
|
||||||
|
|
||||||
(defn <-rpc [contact]
|
(defn <-rpc [contact]
|
||||||
(-> contact
|
(-> contact
|
||||||
(update :tributeToTalk deserialize-tribute-to-talk)
|
|
||||||
(update :systemTags
|
(update :systemTags
|
||||||
#(reduce (fn [acc s]
|
#(reduce (fn [acc s]
|
||||||
(conj acc (keyword (subs s 1))))
|
(conj acc (keyword (subs s 1))))
|
||||||
#{}
|
#{}
|
||||||
%))
|
%))
|
||||||
(clojure.set/rename-keys {:id :public-key
|
(clojure.set/rename-keys {:id :public-key
|
||||||
:tributeToTalk :tribute-to-talk
|
|
||||||
:ensVerifiedAt :ens-verified-at
|
:ensVerifiedAt :ens-verified-at
|
||||||
:ensVerified :ens-verified
|
:ensVerified :ens-verified
|
||||||
:ensVerificationRetries :ens-verification-retries
|
:ensVerificationRetries :ens-verification-retries
|
||||||
|
@ -30,14 +22,12 @@
|
||||||
|
|
||||||
(defn ->rpc [contact]
|
(defn ->rpc [contact]
|
||||||
(-> contact
|
(-> contact
|
||||||
(update :tribute-to-talk types/serialize)
|
|
||||||
(update :system-tags #(mapv str %))
|
(update :system-tags #(mapv str %))
|
||||||
(clojure.set/rename-keys {:public-key :id
|
(clojure.set/rename-keys {:public-key :id
|
||||||
:ens-verified :ensVerified
|
:ens-verified :ensVerified
|
||||||
:ens-verified-at :ensVerifiedAt
|
:ens-verified-at :ensVerifiedAt
|
||||||
:last-ens-clock-value :lastENSClockValue
|
:last-ens-clock-value :lastENSClockValue
|
||||||
:ens-verification-retries :ensVerificationRetries
|
:ens-verification-retries :ensVerificationRetries
|
||||||
:tribute-to-talk :tributeToTalk
|
|
||||||
:system-tags :systemTags
|
:system-tags :systemTags
|
||||||
:last-updated :lastUpdated
|
:last-updated :lastUpdated
|
||||||
:nickname :localNickname})))
|
:nickname :localNickname})))
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
:address "address"
|
:address "address"
|
||||||
:name "name"
|
:name "name"
|
||||||
:identicon "identicon"
|
:identicon "identicon"
|
||||||
:tribute-to-talk "tribute-to-talk"
|
|
||||||
:last-updated 1
|
:last-updated 1
|
||||||
:system-tags #{:a :b}}
|
:system-tags #{:a :b}}
|
||||||
expected-contact {:id "pk"
|
expected-contact {:id "pk"
|
||||||
:address "address"
|
:address "address"
|
||||||
:name "name"
|
:name "name"
|
||||||
:identicon "identicon"
|
:identicon "identicon"
|
||||||
:tributeToTalk "\"tribute-to-talk\""
|
|
||||||
|
|
||||||
:lastUpdated 1
|
:lastUpdated 1
|
||||||
:systemTags #{":a" ":b"}}]
|
:systemTags #{":a" ":b"}}]
|
||||||
|
@ -29,15 +27,12 @@
|
||||||
:address "address"
|
:address "address"
|
||||||
:name "name"
|
:name "name"
|
||||||
:identicon "identicon"
|
:identicon "identicon"
|
||||||
:tributeToTalk "\"tribute-to-talk\""
|
|
||||||
:lastUpdated 1
|
:lastUpdated 1
|
||||||
:systemTags [":a" ":b"]}
|
:systemTags [":a" ":b"]}
|
||||||
expected-contact {:public-key "pk"
|
expected-contact {:public-key "pk"
|
||||||
:address "address"
|
:address "address"
|
||||||
:name "name"
|
:name "name"
|
||||||
:identicon "identicon"
|
:identicon "identicon"
|
||||||
:tribute-to-talk "tribute-to-talk"
|
|
||||||
|
|
||||||
:last-updated 1
|
:last-updated 1
|
||||||
:system-tags #{:a :b}}]
|
:system-tags #{:a :b}}]
|
||||||
(testing "<-rpc"
|
(testing "<-rpc"
|
||||||
|
|
|
@ -160,9 +160,11 @@
|
||||||
"mailservers_getMailservers" {}
|
"mailservers_getMailservers" {}
|
||||||
"mailservers_deleteMailserver" {}
|
"mailservers_deleteMailserver" {}
|
||||||
"mailservers_addMailserverTopic" {}
|
"mailservers_addMailserverTopic" {}
|
||||||
|
"mailservers_addMailserverTopics" {}
|
||||||
"mailservers_getMailserverTopics" {}
|
"mailservers_getMailserverTopics" {}
|
||||||
"mailservers_deleteMailserverTopic" {}
|
"mailservers_deleteMailserverTopic" {}
|
||||||
"mailservers_addChatRequestRange" {}
|
"mailservers_addChatRequestRange" {}
|
||||||
|
"mailservers_addChatRequestRanges" {}
|
||||||
"mailservers_getChatRequestRanges" {}
|
"mailservers_getChatRequestRanges" {}
|
||||||
"mailservers_deleteChatRequestRange" {}})
|
"mailservers_deleteChatRequestRange" {}})
|
||||||
|
|
||||||
|
|
|
@ -152,9 +152,12 @@
|
||||||
(select-keys multiaccount [:key-uid :name :public-key :identicon :images]))))))
|
(select-keys multiaccount [:key-uid :name :public-key :identicon :images]))))))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:login/filters-initialized
|
::transport/messenger-started
|
||||||
(fn [cofx]
|
(fn [cofx [_ response]]
|
||||||
(universal-links/process-stored-event cofx)))
|
(fx/merge
|
||||||
|
cofx
|
||||||
|
(transport/messenger-started response)
|
||||||
|
(universal-links/process-stored-event))))
|
||||||
|
|
||||||
;; multiaccounts update module
|
;; multiaccounts update module
|
||||||
|
|
||||||
|
|
|
@ -328,7 +328,7 @@
|
||||||
- mailserver disconnected: we try to reconnect
|
- mailserver disconnected: we try to reconnect
|
||||||
- mailserver connected: we mark the mailserver as trusted peer"
|
- mailserver connected: we mark the mailserver as trusted peer"
|
||||||
[{:keys [db] :as cofx} previous-summary]
|
[{:keys [db] :as cofx} previous-summary]
|
||||||
(when (and (not config/nimbus-enabled?) (:multiaccount db))
|
(when (:multiaccount db)
|
||||||
(if (:mailserver/current-id db)
|
(if (:mailserver/current-id db)
|
||||||
(let [{:keys [peers-summary peers-count]} db
|
(let [{:keys [peers-summary peers-count]} db
|
||||||
{:keys [address sym-key-id] :as mailserver} (fetch-current db)
|
{:keys [address sym-key-id] :as mailserver} (fetch-current db)
|
||||||
|
@ -498,7 +498,7 @@
|
||||||
(fx/defn process-next-messages-request
|
(fx/defn process-next-messages-request
|
||||||
[{:keys [db now] :as cofx}]
|
[{:keys [db now] :as cofx}]
|
||||||
(when (and
|
(when (and
|
||||||
(:filters/initialized db)
|
(:messenger/started? db)
|
||||||
(mobile-network-utils/syncing-allowed? cofx)
|
(mobile-network-utils/syncing-allowed? cofx)
|
||||||
(fetch-use-mailservers? cofx)
|
(fetch-use-mailservers? cofx)
|
||||||
(not (:mailserver/current-request db)))
|
(not (:mailserver/current-request db)))
|
||||||
|
@ -756,13 +756,11 @@
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (update db :mailserver/ranges merge updated-ranges)
|
{:db (update db :mailserver/ranges merge updated-ranges)
|
||||||
::json-rpc/call
|
::json-rpc/call
|
||||||
(mapv (fn [chat-requests-range]
|
[{:method "mailservers_addChatRequestRanges"
|
||||||
{:method "mailservers_addChatRequestRange"
|
:params [(vals updated-ranges)]
|
||||||
:params [chat-requests-range]
|
:on-success #()
|
||||||
:on-success #()
|
:on-failure
|
||||||
:on-failure
|
#(log/error "failed to save chat request range" %)}]})))
|
||||||
#(log/error "failed to save chat request range" %)})
|
|
||||||
(vals updated-ranges))})))
|
|
||||||
|
|
||||||
(defn prepare-new-gaps [new-gaps ranges {:keys [from to]} chat-ids]
|
(defn prepare-new-gaps [new-gaps ranges {:keys [from to]} chat-ids]
|
||||||
(into
|
(into
|
||||||
|
@ -886,14 +884,13 @@
|
||||||
(update :mailserver/planned-gap-requests
|
(update :mailserver/planned-gap-requests
|
||||||
dissoc gap))
|
dissoc gap))
|
||||||
::json-rpc/call
|
::json-rpc/call
|
||||||
(mapv (fn [[topic mailserver-topic]]
|
[{:method "mailservers_addMailserverTopics"
|
||||||
{:method "mailservers_addMailserverTopic"
|
:params [(mapv (fn [[topic mailserver-topic]]
|
||||||
:params [(assoc mailserver-topic :topic topic)]
|
(assoc mailserver-topic :topic topic)) mailserver-topics)]
|
||||||
:on-success
|
:on-success
|
||||||
#(log/debug "added mailserver-topic successfully")
|
#(log/debug "added mailserver-topic successfully")
|
||||||
:on-failure
|
:on-failure
|
||||||
#(log/error "failed to add mailserver topic" %)})
|
#(log/error "failed to add mailserver topic" %)}]}
|
||||||
mailserver-topics)}
|
|
||||||
(process-next-messages-request))))))))
|
(process-next-messages-request))))))))
|
||||||
|
|
||||||
(fx/defn retry-next-messages-request
|
(fx/defn retry-next-messages-request
|
||||||
|
@ -1043,7 +1040,9 @@
|
||||||
[cofx]
|
[cofx]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:mailserver/set-limit constants/default-limit}
|
{:mailserver/set-limit constants/default-limit}
|
||||||
(set-current-mailserver)))
|
(set-current-mailserver)
|
||||||
|
(reset-request-to)
|
||||||
|
(process-next-messages-request)))
|
||||||
|
|
||||||
(def enode-address-regex
|
(def enode-address-regex
|
||||||
#"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
#"enode://[a-zA-Z0-9]+\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
|
||||||
|
|
|
@ -86,8 +86,7 @@
|
||||||
new-mailserver-topic
|
new-mailserver-topic
|
||||||
{:now-s (quot now 1000)})]
|
{:now-s (quot now 1000)})]
|
||||||
(update-topic cofx
|
(update-topic cofx
|
||||||
(new-chat-ids? old-mailserver-topic
|
true
|
||||||
new-mailserver-topic)
|
|
||||||
updated-topic))))
|
updated-topic))))
|
||||||
|
|
||||||
(fx/defn upsert-many [cofx mailserver-topics]
|
(fx/defn upsert-many [cofx mailserver-topics]
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[status-im.notifications.core :as notifications]
|
[status-im.notifications.core :as notifications]
|
||||||
[status-im.popover.core :as popover]
|
[status-im.popover.core :as popover]
|
||||||
[status-im.communities.core :as communities]
|
[status-im.communities.core :as communities]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.transport.core :as transport]
|
||||||
[status-im.stickers.core :as stickers]
|
[status-im.stickers.core :as stickers]
|
||||||
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
|
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
|
||||||
[status-im.navigation :as navigation]
|
[status-im.navigation :as navigation]
|
||||||
|
@ -37,6 +37,16 @@
|
||||||
(fn [[key-uid account-data hashed-password]]
|
(fn [[key-uid account-data hashed-password]]
|
||||||
(status/login key-uid account-data hashed-password)))
|
(status/login key-uid account-data hashed-password)))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
::export-db
|
||||||
|
(fn [[key-uid account-data hashed-password]]
|
||||||
|
(status/export-db key-uid account-data hashed-password)))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
::import-db
|
||||||
|
(fn [[key-uid account-data hashed-password]]
|
||||||
|
(status/import-db key-uid account-data hashed-password)))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
::enable-local-notifications
|
::enable-local-notifications
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -87,6 +97,26 @@
|
||||||
:identicon identicon})
|
:identicon identicon})
|
||||||
(ethereum/sha3 (security/safe-unmask-data password))]}))
|
(ethereum/sha3 (security/safe-unmask-data password))]}))
|
||||||
|
|
||||||
|
(fx/defn export-db-submitted
|
||||||
|
{:events [:multiaccounts.login.ui/export-db-submitted]}
|
||||||
|
[{:keys [db]}]
|
||||||
|
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
|
||||||
|
{::export-db [key-uid
|
||||||
|
(types/clj->json {:name name
|
||||||
|
:key-uid key-uid
|
||||||
|
:identicon identicon})
|
||||||
|
(ethereum/sha3 (security/safe-unmask-data password))]}))
|
||||||
|
|
||||||
|
(fx/defn import-db-submitted
|
||||||
|
{:events [:multiaccounts.login.ui/import-db-submitted]}
|
||||||
|
[{:keys [db]}]
|
||||||
|
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
|
||||||
|
{::import-db [key-uid
|
||||||
|
(types/clj->json {:name name
|
||||||
|
:key-uid key-uid
|
||||||
|
:identicon identicon})
|
||||||
|
(ethereum/sha3 (security/safe-unmask-data password))]}))
|
||||||
|
|
||||||
(fx/defn finish-keycard-setup
|
(fx/defn finish-keycard-setup
|
||||||
[{:keys [db] :as cofx}]
|
[{:keys [db] :as cofx}]
|
||||||
(let [flow (get-in db [:keycard :flow])]
|
(let [flow (get-in db [:keycard :flow])]
|
||||||
|
@ -217,9 +247,7 @@
|
||||||
(assoc ::notifications/enable nil))
|
(assoc ::notifications/enable nil))
|
||||||
(acquisition/login)
|
(acquisition/login)
|
||||||
(initialize-appearance)
|
(initialize-appearance)
|
||||||
;; NOTE: initializing mailserver depends on user mailserver
|
(transport/start-messenger)
|
||||||
;; preference which is why we wait for config callback
|
|
||||||
(protocol/initialize-protocol {:default-mailserver true})
|
|
||||||
(check-network-version network-id)
|
(check-network-version network-id)
|
||||||
(chat.loading/initialize-chats)
|
(chat.loading/initialize-chats)
|
||||||
(communities/fetch)
|
(communities/fetch)
|
||||||
|
@ -250,18 +278,12 @@
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (assoc db :chats/loading? true)
|
{:db (assoc db :chats/loading? true)
|
||||||
::json-rpc/call
|
::json-rpc/call
|
||||||
[{:method "mailservers_getMailserverTopics"
|
[{:method "browsers_getBrowsers"
|
||||||
:on-success #(re-frame/dispatch [::protocol/initialize-protocol {:mailserver-topics (or % {})}])}
|
|
||||||
{:method "mailservers_getChatRequestRanges"
|
|
||||||
:on-success #(re-frame/dispatch [::protocol/initialize-protocol {:mailserver-ranges (or % {})}])}
|
|
||||||
{:method "browsers_getBrowsers"
|
|
||||||
:on-success #(re-frame/dispatch [::initialize-browsers %])}
|
:on-success #(re-frame/dispatch [::initialize-browsers %])}
|
||||||
{:method "browsers_getBookmarks"
|
{:method "browsers_getBookmarks"
|
||||||
:on-success #(re-frame/dispatch [::initialize-bookmarks %])}
|
:on-success #(re-frame/dispatch [::initialize-bookmarks %])}
|
||||||
{:method "permissions_getDappPermissions"
|
{:method "permissions_getDappPermissions"
|
||||||
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}
|
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}
|
||||||
{:method "mailservers_getMailservers"
|
|
||||||
:on-success #(re-frame/dispatch [::protocol/initialize-protocol {:mailservers (or % [])}])}
|
|
||||||
{:method "settings_getSettings"
|
{:method "settings_getSettings"
|
||||||
:on-success #(re-frame/dispatch [::get-settings-callback %])}]}
|
:on-success #(re-frame/dispatch [::get-settings-callback %])}]}
|
||||||
(notifications/load-notification-preferences)
|
(notifications/load-notification-preferences)
|
||||||
|
@ -278,24 +300,10 @@
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (-> db
|
{:db (-> db
|
||||||
(dissoc :multiaccounts/login)
|
(dissoc :multiaccounts/login)
|
||||||
(assoc
|
|
||||||
;;NOTE when login the filters are initialized twice
|
|
||||||
;;once for contacts and once for chats
|
|
||||||
;;when creating an account we do it only once by calling
|
|
||||||
;;load-filters directly because we don't have chats and contacts
|
|
||||||
;;later on there is a check that filters have been initialized twice
|
|
||||||
;;so here we set it at 1 already so that it passes the check once it has
|
|
||||||
;;been initialized
|
|
||||||
:filters/initialized 1)
|
|
||||||
(assoc-in [:multiaccount :multiaccounts/first-account] first-account?))
|
(assoc-in [:multiaccount :multiaccounts/first-account] first-account?))
|
||||||
:dispatch-later [{:ms 2000 :dispatch [::initialize-wallet accounts nil nil (:recovered multiaccount)]}]
|
:dispatch-later [{:ms 2000 :dispatch [::initialize-wallet accounts nil nil (:recovered multiaccount)]}]}
|
||||||
:filters/load-filters [[]]}
|
|
||||||
(finish-keycard-setup)
|
(finish-keycard-setup)
|
||||||
(protocol/initialize-protocol {:mailservers []
|
(transport/start-messenger)
|
||||||
:mailserver-ranges {}
|
|
||||||
:mailserver-topics {}
|
|
||||||
:default-mailserver true})
|
|
||||||
|
|
||||||
(communities/fetch)
|
(communities/fetch)
|
||||||
(multiaccounts/switch-preview-privacy-mode-flag)
|
(multiaccounts/switch-preview-privacy-mode-flag)
|
||||||
(link-preview/request-link-preview-whitelist)
|
(link-preview/request-link-preview-whitelist)
|
||||||
|
|
|
@ -72,6 +72,24 @@
|
||||||
key-uid
|
key-uid
|
||||||
#(.login ^js (status) account-data hashed-password)))
|
#(.login ^js (status) account-data hashed-password)))
|
||||||
|
|
||||||
|
(defn export-db
|
||||||
|
"NOTE: beware, the password has to be sha3 hashed"
|
||||||
|
[key-uid account-data hashed-password]
|
||||||
|
(log/debug "[native-module] export-db")
|
||||||
|
(clear-web-data)
|
||||||
|
(init-keystore
|
||||||
|
key-uid
|
||||||
|
#(.exportUnencryptedDatabase ^js (status) account-data hashed-password)))
|
||||||
|
|
||||||
|
(defn import-db
|
||||||
|
"NOTE: beware, the password has to be sha3 hashed"
|
||||||
|
[key-uid account-data hashed-password]
|
||||||
|
(log/debug "[native-module] import-db")
|
||||||
|
(clear-web-data)
|
||||||
|
(init-keystore
|
||||||
|
key-uid
|
||||||
|
#(.importUnencryptedDatabase ^js (status) account-data hashed-password)))
|
||||||
|
|
||||||
(defn logout []
|
(defn logout []
|
||||||
(log/debug "[native-module] logout")
|
(log/debug "[native-module] logout")
|
||||||
(clear-web-data)
|
(clear-web-data)
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
(ns status-im.protocol.core
|
|
||||||
(:require [status-im.constants :as constants]
|
|
||||||
[status-im.transport.core :as transport]
|
|
||||||
[status-im.utils.fx :as fx]))
|
|
||||||
|
|
||||||
(defn add-custom-mailservers
|
|
||||||
[db custom-mailservers]
|
|
||||||
(reduce (fn [db {:keys [fleet] :as mailserver}]
|
|
||||||
(let [{:keys [id] :as mailserver}
|
|
||||||
(-> mailserver
|
|
||||||
(update :id keyword)
|
|
||||||
(dissoc :fleet)
|
|
||||||
(assoc :user-defined true))]
|
|
||||||
(assoc-in db
|
|
||||||
[:mailserver/mailservers (keyword fleet) id]
|
|
||||||
mailserver)))
|
|
||||||
db
|
|
||||||
custom-mailservers))
|
|
||||||
|
|
||||||
(defn add-mailserver-topics
|
|
||||||
[db mailserver-topics]
|
|
||||||
(assoc db
|
|
||||||
:mailserver/topics
|
|
||||||
(reduce (fn [acc {:keys [topic]
|
|
||||||
:as mailserver-topic}]
|
|
||||||
(assoc acc topic
|
|
||||||
(update mailserver-topic :chat-ids
|
|
||||||
#(into #{} %))))
|
|
||||||
{}
|
|
||||||
mailserver-topics)))
|
|
||||||
|
|
||||||
(defn add-mailserver-ranges
|
|
||||||
[db mailserver-ranges]
|
|
||||||
(assoc db
|
|
||||||
:mailserver/ranges
|
|
||||||
(reduce (fn [acc {:keys [chat-id] :as range}]
|
|
||||||
(assoc acc chat-id range))
|
|
||||||
{}
|
|
||||||
mailserver-ranges)))
|
|
||||||
|
|
||||||
(fx/defn initialize-protocol
|
|
||||||
{:events [::initialize-protocol]}
|
|
||||||
[{:keys [db] :as cofx}
|
|
||||||
{:keys [mailserver-ranges mailserver-topics mailservers] :as data}]
|
|
||||||
;; NOTE: we need to wait for `:mailservers` `:mailserver-ranges` and
|
|
||||||
;; `:mailserver-topics` before we can proceed to init whisper
|
|
||||||
;; since those are populated by separate events, we check here
|
|
||||||
;; that everything has been initialized before moving forward
|
|
||||||
(let [initialization-protocol (apply conj (get db :initialization-protocol #{})
|
|
||||||
(keys data))
|
|
||||||
initialization-complete? (= initialization-protocol
|
|
||||||
#{:mailservers
|
|
||||||
:mailserver-ranges
|
|
||||||
:mailserver-topics
|
|
||||||
:default-mailserver})]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (cond-> db
|
|
||||||
mailserver-ranges
|
|
||||||
(add-mailserver-ranges mailserver-ranges)
|
|
||||||
mailserver-topics
|
|
||||||
(add-mailserver-topics mailserver-topics)
|
|
||||||
mailservers
|
|
||||||
(add-custom-mailservers mailservers)
|
|
||||||
initialization-complete?
|
|
||||||
(assoc :rpc-url constants/ethereum-rpc-url)
|
|
||||||
initialization-complete?
|
|
||||||
(dissoc :initialization-protocol)
|
|
||||||
(not initialization-complete?)
|
|
||||||
(assoc :initialization-protocol initialization-protocol))}
|
|
||||||
(when initialization-complete?
|
|
||||||
(transport/init-messenger)))))
|
|
|
@ -24,9 +24,6 @@
|
||||||
[status-im.chat.models.reactions :as models.reactions]
|
[status-im.chat.models.reactions :as models.reactions]
|
||||||
[status-im.pairing.core :as pairing]
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.signing.gas :as signing.gas]
|
[status-im.signing.gas :as signing.gas]
|
||||||
#_[status-im.tribute-to-talk.core :as tribute-to-talk]
|
|
||||||
[status-im.tribute-to-talk.db :as tribute-to-talk.db]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[status-im.ui.screens.add-new.new-public-chat.db :as db]
|
[status-im.ui.screens.add-new.new-public-chat.db :as db]
|
||||||
[status-im.ui.screens.mobile-network-settings.utils
|
[status-im.ui.screens.mobile-network-settings.utils
|
||||||
:as
|
:as
|
||||||
|
@ -403,7 +400,7 @@
|
||||||
:disconnected?
|
:disconnected?
|
||||||
:<- [:peers-count]
|
:<- [:peers-count]
|
||||||
(fn [peers-count]
|
(fn [peers-count]
|
||||||
(and (not config/nimbus-enabled?) (zero? peers-count))))
|
(zero? peers-count)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:offline?
|
:offline?
|
||||||
|
@ -2152,102 +2149,6 @@
|
||||||
:tokens {true (apply-filter search-token-filter custom-tokens extract-token-attributes false)
|
:tokens {true (apply-filter search-token-filter custom-tokens extract-token-attributes false)
|
||||||
nil (apply-filter search-token-filter default-tokens extract-token-attributes false)}}))
|
nil (apply-filter search-token-filter default-tokens extract-token-attributes false)}}))
|
||||||
|
|
||||||
;; TRIBUTE TO TALK
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:tribute-to-talk/settings
|
|
||||||
:<- [:multiaccount]
|
|
||||||
:<- [:ethereum/chain-keyword]
|
|
||||||
(fn [[multiaccount chain-keyword]]
|
|
||||||
(get-in multiaccount [:tribute-to-talk]) chain-keyword))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:tribute-to-talk/screen-params
|
|
||||||
:<- [:screen-params]
|
|
||||||
(fn [screen-params]
|
|
||||||
(get screen-params :tribute-to-talk)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:tribute-to-talk/profile
|
|
||||||
:<- [:tribute-to-talk/settings]
|
|
||||||
:<- [:tribute-to-talk/screen-params]
|
|
||||||
(fn [[{:keys [seen? snt-amount]}
|
|
||||||
{:keys [state unavailable?]}]]
|
|
||||||
(let [state (or state (if snt-amount :completed :disabled))
|
|
||||||
snt-amount (tribute-to-talk.db/from-wei snt-amount)]
|
|
||||||
(when config/tr-to-talk-enabled?
|
|
||||||
(if unavailable?
|
|
||||||
{:subtext "Change network to enable Tribute to Talk"
|
|
||||||
:active? false
|
|
||||||
:icon :main-icons/tribute-to-talk
|
|
||||||
:icon-color colors/gray}
|
|
||||||
(cond-> {:new? (not seen?)}
|
|
||||||
(and (not (and seen?
|
|
||||||
snt-amount
|
|
||||||
(#{:signing :pending :transaction-failed :completed} state))))
|
|
||||||
(assoc :subtext (i18n/label :t/tribute-to-talk-desc))
|
|
||||||
|
|
||||||
(#{:signing :pending} state)
|
|
||||||
(assoc :activity-indicator {:animating true
|
|
||||||
:color colors/blue}
|
|
||||||
:subtext (case state
|
|
||||||
:pending (i18n/label :t/pending-confirmation)
|
|
||||||
:signing (i18n/label :t/waiting-to-sign)))
|
|
||||||
|
|
||||||
(= state :transaction-failed)
|
|
||||||
(assoc :icon :main-icons/warning
|
|
||||||
:icon-color colors/red
|
|
||||||
:subtext (i18n/label :t/transaction-failed))
|
|
||||||
|
|
||||||
(not (#{:signing :pending :transaction-failed} state))
|
|
||||||
(assoc :icon :main-icons/tribute-to-talk)
|
|
||||||
|
|
||||||
(and (= state :completed)
|
|
||||||
(not-empty snt-amount))
|
|
||||||
(assoc :accessory-value (str snt-amount " SNT"))))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:tribute-to-talk/enabled?
|
|
||||||
:<- [:tribute-to-talk/settings]
|
|
||||||
(fn [settings]
|
|
||||||
(tribute-to-talk.db/enabled? settings)))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
|
||||||
:tribute-to-talk/settings-ui
|
|
||||||
:<- [:tribute-to-talk/settings]
|
|
||||||
:<- [:tribute-to-talk/screen-params]
|
|
||||||
:<- [:prices]
|
|
||||||
:<- [:wallet/currency]
|
|
||||||
(fn [[{:keys [seen? snt-amount message]
|
|
||||||
:as settings}
|
|
||||||
{:keys [step editing? state error]
|
|
||||||
:or {step :intro}
|
|
||||||
screen-snt-amount :snt-amount}
|
|
||||||
prices currency]]
|
|
||||||
(let [fiat-value (if snt-amount
|
|
||||||
(money/fiat-amount-value
|
|
||||||
snt-amount
|
|
||||||
:SNT
|
|
||||||
(-> currency :code keyword)
|
|
||||||
prices)
|
|
||||||
"0")]
|
|
||||||
(cond-> {:seen? seen?
|
|
||||||
:snt-amount (tribute-to-talk.db/from-wei snt-amount)
|
|
||||||
:message message
|
|
||||||
:enabled? (tribute-to-talk.db/enabled? settings)
|
|
||||||
:error error
|
|
||||||
:step step
|
|
||||||
:state (or state (if snt-amount :completed :disabled))
|
|
||||||
:editing? editing?
|
|
||||||
:fiat-value (str fiat-value " " (:code currency))}
|
|
||||||
|
|
||||||
(= step :set-snt-amount)
|
|
||||||
(assoc :snt-amount (str screen-snt-amount)
|
|
||||||
:disable-button?
|
|
||||||
(boolean (and (= step :set-snt-amount)
|
|
||||||
(or (string/blank? screen-snt-amount)
|
|
||||||
(#{"0" "0.0" "0.00"} screen-snt-amount)
|
|
||||||
(string/ends-with? screen-snt-amount ".")))))))))
|
|
||||||
|
|
||||||
;;ENS ==================================================================================================================
|
;;ENS ==================================================================================================================
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:multiaccount/usernames
|
:multiaccount/usernames
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
[status-im.ethereum.json-rpc :as json-rpc]
|
||||||
[status-im.mailserver.core :as mailserver]
|
[status-im.mailserver.core :as mailserver]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.native-module.core :as status]
|
[status-im.native-module.core :as status]
|
||||||
[status-im.pairing.core :as pairing]
|
[status-im.pairing.core :as pairing]
|
||||||
[status-im.utils.config :as config]
|
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.utils.publisher :as publisher]
|
[status-im.utils.publisher :as publisher]
|
||||||
|
[status-im.transport.filters.core :as transport.filters]
|
||||||
status-im.transport.shh
|
status-im.transport.shh
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
@ -32,28 +33,68 @@
|
||||||
(fx/defn fetch-node-info-fx [cofx]
|
(fx/defn fetch-node-info-fx [cofx]
|
||||||
{::fetch-node-info []})
|
{::fetch-node-info []})
|
||||||
|
|
||||||
(fx/defn init-messenger
|
(defn add-custom-mailservers
|
||||||
|
[db custom-mailservers]
|
||||||
|
(reduce (fn [db {:keys [fleet] :as mailserver}]
|
||||||
|
(let [{:keys [id] :as mailserver}
|
||||||
|
(-> mailserver
|
||||||
|
(update :id keyword)
|
||||||
|
(dissoc :fleet)
|
||||||
|
(assoc :user-defined true))]
|
||||||
|
(assoc-in db
|
||||||
|
[:mailserver/mailservers (keyword fleet) id]
|
||||||
|
mailserver)))
|
||||||
|
db
|
||||||
|
custom-mailservers))
|
||||||
|
|
||||||
|
(defn add-mailserver-topics
|
||||||
|
[db mailserver-topics]
|
||||||
|
(assoc db
|
||||||
|
:mailserver/topics
|
||||||
|
(reduce (fn [acc {:keys [topic]
|
||||||
|
:as mailserver-topic}]
|
||||||
|
(assoc acc topic
|
||||||
|
(update mailserver-topic :chat-ids
|
||||||
|
#(into #{} %))))
|
||||||
|
{}
|
||||||
|
mailserver-topics)))
|
||||||
|
|
||||||
|
(defn add-mailserver-ranges
|
||||||
|
[db mailserver-ranges]
|
||||||
|
(assoc db
|
||||||
|
:mailserver/ranges
|
||||||
|
(reduce (fn [acc {:keys [chat-id] :as range}]
|
||||||
|
(assoc acc chat-id range))
|
||||||
|
{}
|
||||||
|
mailserver-ranges)))
|
||||||
|
|
||||||
|
(fx/defn start-messenger
|
||||||
"We should only start receiving messages/processing topics once all the
|
"We should only start receiving messages/processing topics once all the
|
||||||
initializiation is completed, otherwise we might receive messages/topics
|
initializiation is completed, otherwise we might receive messages/topics
|
||||||
when the state has not been properly initialized."
|
when the state has not been properly initialized."
|
||||||
[cofx]
|
[{:keys [db] :as cofx}]
|
||||||
{::json-rpc/call [{:method (json-rpc/call-ext-method "startMessenger")
|
{:db (assoc db :rpc-url constants/ethereum-rpc-url)
|
||||||
:on-success #(do
|
::json-rpc/call [{:method (json-rpc/call-ext-method "startMessenger")
|
||||||
(log/debug "messenger initialized")
|
:on-success #(re-frame/dispatch [::messenger-started %])
|
||||||
(re-frame/dispatch [::init-whisper]))
|
:on-failure #(log/error "failed to start messenger")}]})
|
||||||
:on-failure #(log/error "failed to init messenger")}]})
|
|
||||||
|
|
||||||
(fx/defn init-whisper
|
(fx/defn messenger-started
|
||||||
"Initialises whisper protocol by:
|
[{:keys [db] :as cofx} {:keys [filters
|
||||||
- (optionally) initializing mailserver"
|
mailserverTopics
|
||||||
{:events [::init-whisper]}
|
mailservers
|
||||||
[cofx]
|
mailserverRanges] :as response}]
|
||||||
(log/debug "Initializing whisper")
|
(log/info "Messenger started", response, mailserverTopics, mailservers, mailserverRanges)
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
|
{:db (-> db
|
||||||
|
(assoc :messenger/started? true)
|
||||||
|
(add-mailserver-ranges mailserverRanges)
|
||||||
|
(add-mailserver-topics mailserverTopics)
|
||||||
|
(add-custom-mailservers mailservers))}
|
||||||
|
(transport.filters/handle-loaded-filters filters)
|
||||||
(fetch-node-info-fx)
|
(fetch-node-info-fx)
|
||||||
(pairing/init)
|
(pairing/init)
|
||||||
(publisher/start-fx)
|
(publisher/start-fx)
|
||||||
(when-not config/nimbus-enabled? (mailserver/initialize-mailserver))))
|
(mailserver/initialize-mailserver)))
|
||||||
|
|
||||||
(fx/defn stop-whisper
|
(fx/defn stop-whisper
|
||||||
"Stops whisper protocol"
|
"Stops whisper protocol"
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
(ns status-im.transport.core-test
|
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
|
||||||
[status-im.protocol.core :as protocol]
|
|
||||||
[status-im.transport.message.core :as message]
|
|
||||||
[status-im.utils.fx :as fx]))
|
|
||||||
|
|
||||||
(deftest init-whisper
|
|
||||||
(let [cofx {:db {:multiaccount {:public-key "1"}}}]
|
|
||||||
(testing "custom mailservers"
|
|
||||||
(let [ms-1 {:id :a
|
|
||||||
:fleet :eth.staging
|
|
||||||
:name "name-1"
|
|
||||||
:address "address-1"
|
|
||||||
:password "password-1"}
|
|
||||||
ms-2 {:id :b
|
|
||||||
:fleet :eth.staging
|
|
||||||
:name "name-2"
|
|
||||||
:address "address-2"
|
|
||||||
:password "password-2"}
|
|
||||||
ms-3 {:id :c
|
|
||||||
:fleet :eth.test
|
|
||||||
:name "name-3"
|
|
||||||
:address "address-3"
|
|
||||||
:password "password-3"}
|
|
||||||
expected-mailservers {:eth.staging {:a (-> ms-1
|
|
||||||
(dissoc :fleet)
|
|
||||||
(assoc :user-defined true))
|
|
||||||
:b (-> ms-2
|
|
||||||
(dissoc ms-2 :fleet)
|
|
||||||
(assoc :user-defined true))}
|
|
||||||
:eth.test {:c (-> ms-3
|
|
||||||
(dissoc :fleet)
|
|
||||||
(assoc :user-defined true))}}]
|
|
||||||
(is (= expected-mailservers
|
|
||||||
(-> (get-in
|
|
||||||
(protocol/initialize-protocol cofx {:mailservers [ms-1 ms-2 ms-3]
|
|
||||||
:mailserver-ranges {}
|
|
||||||
:mailserver-topics {}
|
|
||||||
:default-mailserver true})
|
|
||||||
[:db :mailserver/mailservers])
|
|
||||||
(update-in [:eth.staging :a] dissoc :generating-sym-key?)
|
|
||||||
(update-in [:eth.staging :b] dissoc :generating-sym-key?)
|
|
||||||
(update-in [:eth.test :c] dissoc :generating-sym-key?))))))))
|
|
||||||
|
|
||||||
(def sig "0x04325367620ae20dd878dbb39f69f02c567d789dd21af8a88623dc5b529827c2812571c380a2cd8236a2851b8843d6486481166c39debf60a5d30b9099c66213e4")
|
|
||||||
|
|
||||||
(def messages [(clj->js {:id "someid"
|
|
||||||
:metadata {:author {:publicKey sig}}
|
|
||||||
:payload "[\"~#c4\",[\"F\",\"text/plain\",\"~:public-group-user-message\",152769201438101,1527692014377]]"
|
|
||||||
:message {:sig sig
|
|
||||||
:ttl 10
|
|
||||||
:timestamp 1527692015
|
|
||||||
:topic "0x9c22ff5f"
|
|
||||||
:payload "0x5b227e236334222c5b2246222c22746578742f706c61696e222c227e3a7075626c69632d67726f75702d757365722d6d657373616765222c3135323736393230313433383130312c313532373639323031343337375d5d"
|
|
||||||
:padding "0xbf06347cc7f9aa18b4a846032264a88f559d9b14079975d14b10648847c0543a77a80624e101c082d19b502ae3b4f97958d18abf59eb0a82afc1301aa22470495fac739a30c2f563599fa8d8e09363a43d39311596b7f119dee7b046989c08224f1ef5cdc385"
|
|
||||||
:pow 0.002631578947368421
|
|
||||||
:hash "0x220ef9994a4fae64c112b27ed07ef910918159cbe6fcf8ac515ee2bf9a6711a0"}})])
|
|
||||||
|
|
||||||
(deftest message-envelopes
|
|
||||||
(let [chat-id "chat-id"
|
|
||||||
from "from"
|
|
||||||
message-id "message-id"
|
|
||||||
initial-cofx {:db {:messages {chat-id {message-id {:from from}}}
|
|
||||||
:chats {chat-id {}}}}]
|
|
||||||
|
|
||||||
(testing "a single envelope message"
|
|
||||||
(let [cofx (message/set-message-envelope-hash initial-cofx chat-id message-id :message-type 1)]
|
|
||||||
(testing "it sets the message-infos"
|
|
||||||
(is (= {:chat-id chat-id
|
|
||||||
:message-type :message-type}
|
|
||||||
(get-in cofx [:db :transport/message-envelopes message-id]))))
|
|
||||||
(testing "the message is sent"
|
|
||||||
(is (= :sent
|
|
||||||
(get-in
|
|
||||||
(message/update-envelope-status cofx message-id :sent)
|
|
||||||
[:db :messages chat-id message-id :outgoing-status]))))
|
|
||||||
(testing "the message is not sent"
|
|
||||||
(is (= :not-sent
|
|
||||||
(get-in
|
|
||||||
(message/update-envelope-status cofx message-id :not-sent)
|
|
||||||
[:db :messages chat-id message-id :outgoing-status]))))))
|
|
||||||
(testing "multi envelope message"
|
|
||||||
(testing "only inserts"
|
|
||||||
(let [cofx (fx/merge
|
|
||||||
initial-cofx
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3))]
|
|
||||||
(testing "it sets the message count"
|
|
||||||
(is (= {:pending-confirmations 3}
|
|
||||||
(get-in cofx [:db :transport/message-ids->confirmations message-id]))))))
|
|
||||||
(testing "message sent correctly"
|
|
||||||
(let [cofx (fx/merge
|
|
||||||
initial-cofx
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/update-envelope-status message-id :sent))]
|
|
||||||
(testing "it removes the confirmations"
|
|
||||||
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
|
|
||||||
(testing "the message is sent"
|
|
||||||
(is (= :sent
|
|
||||||
(get-in
|
|
||||||
cofx
|
|
||||||
[:db :messages chat-id message-id :outgoing-status]))))))
|
|
||||||
(testing "order of events is reversed"
|
|
||||||
(let [cofx (fx/merge
|
|
||||||
initial-cofx
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3))]
|
|
||||||
(testing "it removes the confirmations"
|
|
||||||
(is (not (get-in cofx [:db :transport/message-confirmations message-id])))
|
|
||||||
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
|
|
||||||
|
|
||||||
(testing "the message is sent"
|
|
||||||
(is (= :sent
|
|
||||||
(get-in
|
|
||||||
cofx
|
|
||||||
[:db :messages chat-id message-id :outgoing-status]))))))
|
|
||||||
(testing "message not sent"
|
|
||||||
(let [cofx (fx/merge
|
|
||||||
initial-cofx
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/update-envelope-status message-id :sent)
|
|
||||||
(message/set-message-envelope-hash chat-id message-id :message-type 3)
|
|
||||||
(message/update-envelope-status message-id :not-sent)
|
|
||||||
(message/update-envelope-status message-id :sent))]
|
|
||||||
(testing "it removes the confirmations"
|
|
||||||
(is (not (get-in cofx [:db :transport/message-ids->confirmations message-id]))))
|
|
||||||
(testing "the message is sent"
|
|
||||||
(is (= :not-sent
|
|
||||||
(get-in
|
|
||||||
cofx
|
|
||||||
[:db :messages chat-id message-id :outgoing-status])))))))))
|
|
|
@ -119,7 +119,9 @@
|
||||||
(fx/defn add-filter-to-db
|
(fx/defn add-filter-to-db
|
||||||
"Set the filter in the db and upsert a mailserver topic"
|
"Set the filter in the db and upsert a mailserver topic"
|
||||||
[{:keys [db] :as cofx} filter]
|
[{:keys [db] :as cofx} filter]
|
||||||
(when-not (loaded? db filter)
|
(when (and (not (loaded? db filter))
|
||||||
|
(not (:ephemeral? filter))
|
||||||
|
(:listen? filter))
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(set-raw-filter filter)
|
(set-raw-filter filter)
|
||||||
(upsert-mailserver-topic filter))))
|
(upsert-mailserver-topic filter))))
|
||||||
|
@ -198,25 +200,21 @@
|
||||||
discovery
|
discovery
|
||||||
filterId
|
filterId
|
||||||
chatId
|
chatId
|
||||||
|
listen
|
||||||
|
ephemeral
|
||||||
topic
|
topic
|
||||||
identity]}]
|
identity]}]
|
||||||
{:chat-id (if (not= identity "") (str "0x" identity) chatId)
|
{:chat-id (if (not= identity "") (str "0x" identity) chatId)
|
||||||
:id chatId
|
:id chatId
|
||||||
:filter-id filterId
|
:filter-id filterId
|
||||||
:negotiated? negotiated
|
:negotiated? negotiated
|
||||||
|
:ephemeral? ephemeral
|
||||||
|
:listen? listen
|
||||||
:discovery? discovery
|
:discovery? discovery
|
||||||
:topic topic})
|
:topic topic})
|
||||||
|
|
||||||
;; We check that both chats & contacts have been initialized
|
(defn messenger-started? [db]
|
||||||
(defn filters-initialized? [db]
|
(:messenger/started? db))
|
||||||
(>= (:filters/initialized db) 2))
|
|
||||||
|
|
||||||
(fx/defn set-filters-initialized [{:keys [db] :as cofx}]
|
|
||||||
(fx/merge
|
|
||||||
cofx
|
|
||||||
{:db (update db :filters/initialized inc)}
|
|
||||||
#(when (filters-initialized? (:db %))
|
|
||||||
{:dispatch [:login/filters-initialized]})))
|
|
||||||
|
|
||||||
(fx/defn handle-filters-added
|
(fx/defn handle-filters-added
|
||||||
"Called every time we load a filter from statusgo, either from explicit call
|
"Called every time we load a filter from statusgo, either from explicit call
|
||||||
|
@ -228,12 +226,20 @@
|
||||||
(add-filters-to-db filters)
|
(add-filters-to-db filters)
|
||||||
(upsert-group-chat-topics)
|
(upsert-group-chat-topics)
|
||||||
(when (new-filters? db filters)
|
(when (new-filters? db filters)
|
||||||
(mailserver/process-next-messages-request))
|
(mailserver/process-next-messages-request))))
|
||||||
(set-filters-initialized)))
|
|
||||||
|
|
||||||
(fx/defn handle-filters [cofx filters]
|
(fx/defn handle-filters [cofx filters]
|
||||||
(handle-filters-added cofx (map responses->filters filters)))
|
(handle-filters-added cofx (map responses->filters filters)))
|
||||||
|
|
||||||
|
(fx/defn handle-loaded-filter [cofx filter]
|
||||||
|
(when (and (not (:ephemeral? filter))
|
||||||
|
(:listen? filter))
|
||||||
|
(set-raw-filter cofx filter)))
|
||||||
|
|
||||||
|
(fx/defn handle-loaded-filters [cofx filters]
|
||||||
|
(let [processed-filters (map responses->filters filters)]
|
||||||
|
(apply fx/merge cofx (map handle-loaded-filter processed-filters))))
|
||||||
|
|
||||||
(fx/defn handle-filters-removed
|
(fx/defn handle-filters-removed
|
||||||
"Called when we remove a filter from status-go, it will update the mailserver
|
"Called when we remove a filter from status-go, it will update the mailserver
|
||||||
topics"
|
topics"
|
||||||
|
@ -256,23 +262,12 @@
|
||||||
{:filters/add-raw-filters
|
{:filters/add-raw-filters
|
||||||
{:filters new-filters}})))
|
{:filters new-filters}})))
|
||||||
|
|
||||||
(fx/defn load-filters
|
|
||||||
"Load all contacts and chats as filters"
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(log/debug "loading filters")
|
|
||||||
(let [chats (vals (:chats db))
|
|
||||||
contacts (vals (:contacts/contacts db))
|
|
||||||
filters (concat
|
|
||||||
(chats->filter-requests chats)
|
|
||||||
(contacts->filter-requests contacts))]
|
|
||||||
(load-filter-fx filters)))
|
|
||||||
|
|
||||||
;; Load functions: utility function to load filters
|
;; Load functions: utility function to load filters
|
||||||
|
|
||||||
(fx/defn load-chat
|
(fx/defn load-chat
|
||||||
"Check if a filter already exists for that chat, otherw load the filter"
|
"Check if a filter already exists for that chat, otherw load the filter"
|
||||||
[{:keys [db] :as cofx} chat-id]
|
[{:keys [db] :as cofx} chat-id]
|
||||||
(when (and (filters-initialized? db)
|
(when (and (messenger-started? db)
|
||||||
(not (chat-loaded? db chat-id)))
|
(not (chat-loaded? db chat-id)))
|
||||||
(let [chat (get-in db [:chats chat-id])]
|
(let [chat (get-in db [:chats chat-id])]
|
||||||
(load-filter-fx (->filter-request chat)))))
|
(load-filter-fx (->filter-request chat)))))
|
||||||
|
@ -281,7 +276,7 @@
|
||||||
"Check if a filter already exists for that chat, otherw load the filter"
|
"Check if a filter already exists for that chat, otherw load the filter"
|
||||||
[{:keys [db] :as cofx} chats]
|
[{:keys [db] :as cofx} chats]
|
||||||
(let [chats (filter #(chat-loaded? db (:chat-id %)) chats)]
|
(let [chats (filter #(chat-loaded? db (:chat-id %)) chats)]
|
||||||
(when (and (filters-initialized? db) (seq chats))
|
(when (and (messenger-started? db) (seq chats))
|
||||||
(load-filter-fx (chats->filter-requests chats)))))
|
(load-filter-fx (chats->filter-requests chats)))))
|
||||||
|
|
||||||
(fx/defn load-contact
|
(fx/defn load-contact
|
||||||
|
|
|
@ -119,6 +119,7 @@
|
||||||
(let [expected {:db {:filter/chat-ids #{"chat-id"}
|
(let [expected {:db {:filter/chat-ids #{"chat-id"}
|
||||||
:filter/filters {"filter-id" {:filter-id "filter-id"
|
:filter/filters {"filter-id" {:filter-id "filter-id"
|
||||||
:discovery? false
|
:discovery? false
|
||||||
|
:listen? true
|
||||||
:chat-id "chat-id"
|
:chat-id "chat-id"
|
||||||
:negotiated? false
|
:negotiated? false
|
||||||
:topic "topic"}}
|
:topic "topic"}}
|
||||||
|
@ -132,8 +133,17 @@
|
||||||
:discovery? false
|
:discovery? false
|
||||||
:chat-id "chat-id"
|
:chat-id "chat-id"
|
||||||
:negotiated? false
|
:negotiated? false
|
||||||
|
:listen? true
|
||||||
:topic "topic"}))))))
|
:topic "topic"}))))))
|
||||||
|
|
||||||
|
(deftest add-filter-to-db-not-listen
|
||||||
|
(with-redefs [mailserver.topics/upsert (fn [{:keys [db]} r] {:db (assoc db :upsert r)})]
|
||||||
|
(is (not (transport.filters/add-filter-to-db {:db {}} {:filter-id "filter-id"
|
||||||
|
:discovery? false
|
||||||
|
:chat-id "chat-id"
|
||||||
|
:negotiated? false
|
||||||
|
:topic "topic"})))))
|
||||||
|
|
||||||
(deftest new-filters?
|
(deftest new-filters?
|
||||||
(testing "new-filters?"
|
(testing "new-filters?"
|
||||||
(let [db {:filter/filters {"a" {}
|
(let [db {:filter/filters {"a" {}
|
||||||
|
|
|
@ -1,374 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.core
|
|
||||||
(:refer-clojure :exclude [remove])
|
|
||||||
(:require [clojure.string :as string]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.contact.core :as contact]
|
|
||||||
[status-im.ethereum.contracts :as contracts]
|
|
||||||
[status-im.ethereum.core :as ethereum]
|
|
||||||
[status-im.ethereum.json-rpc :as json-rpc]
|
|
||||||
[status-im.ethereum.transactions.core :as transactions]
|
|
||||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
|
||||||
[status-im.signing.core :as signing]
|
|
||||||
[status-im.tribute-to-talk.db :as tribute-to-talk.db]
|
|
||||||
[status-im.tribute-to-talk.whitelist :as whitelist]
|
|
||||||
[status-im.navigation :as navigation]
|
|
||||||
[status-im.utils.fx :as fx]
|
|
||||||
[taoensso.timbre :as log]))
|
|
||||||
|
|
||||||
(defn add-transaction-hash
|
|
||||||
[message db]
|
|
||||||
(let [to (get-in message [:content :chat-id])
|
|
||||||
tribute-transaction-hash
|
|
||||||
(get-in db [:contacts/contacts to :tribute-to-talk :transaction-hash])]
|
|
||||||
(if tribute-transaction-hash
|
|
||||||
(assoc-in message
|
|
||||||
[:content :tribute-transaction]
|
|
||||||
tribute-transaction-hash)
|
|
||||||
message)))
|
|
||||||
|
|
||||||
(fx/defn update-settings
|
|
||||||
[{:keys [db] :as cofx} {:keys [snt-amount message update] :as new-settings}]
|
|
||||||
(let [tribute-to-talk-settings (get-in db [:multiaccount :tribute-to-talk])
|
|
||||||
chain-keyword (ethereum/chain-keyword db)
|
|
||||||
tribute-to-talk-chain-settings
|
|
||||||
(cond-> (merge (tribute-to-talk.db/get-settings db)
|
|
||||||
new-settings)
|
|
||||||
new-settings
|
|
||||||
(assoc :seen? true)
|
|
||||||
|
|
||||||
(not new-settings)
|
|
||||||
(dissoc :snt-amount :manifest)
|
|
||||||
|
|
||||||
(and (contains? new-settings :update)
|
|
||||||
(nil? update))
|
|
||||||
(dissoc :update))]
|
|
||||||
(fx/merge cofx
|
|
||||||
(multiaccounts.update/multiaccount-update
|
|
||||||
:tribute-to-talk (assoc tribute-to-talk-settings
|
|
||||||
chain-keyword
|
|
||||||
tribute-to-talk-chain-settings)
|
|
||||||
{})
|
|
||||||
(whitelist/enable-whitelist))))
|
|
||||||
|
|
||||||
(fx/defn mark-ttt-as-seen
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(when-not (:seen (tribute-to-talk.db/get-settings db))
|
|
||||||
(update-settings cofx {:seen? true})))
|
|
||||||
|
|
||||||
(fx/defn open-settings
|
|
||||||
{:events [:tribute-to-talk.ui/menu-item-pressed]}
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(let [settings (tribute-to-talk.db/get-settings db)
|
|
||||||
updated-settings (:update settings)]
|
|
||||||
(fx/merge cofx
|
|
||||||
mark-ttt-as-seen
|
|
||||||
(navigation/navigate-to-cofx
|
|
||||||
:tribute-to-talk
|
|
||||||
(cond
|
|
||||||
updated-settings
|
|
||||||
(merge {:step :finish}
|
|
||||||
updated-settings
|
|
||||||
(when updated-settings
|
|
||||||
{:state :pending}))
|
|
||||||
(:snt-amount settings)
|
|
||||||
(merge {:step :edit
|
|
||||||
:editing? true}
|
|
||||||
(update settings :snt-amount tribute-to-talk.db/from-wei))
|
|
||||||
:else
|
|
||||||
{:step :intro
|
|
||||||
:snt-amount "0"})))))
|
|
||||||
|
|
||||||
(fx/defn set-step
|
|
||||||
[{:keys [db]} step]
|
|
||||||
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :step] step)})
|
|
||||||
|
|
||||||
(fx/defn set-tribute-signing-flow
|
|
||||||
[{:keys [db] :as cofx} tribute]
|
|
||||||
(if-let [contract (contracts/get-address db :status/tribute-to-talk)]
|
|
||||||
(signing/eth-transaction-call
|
|
||||||
cofx
|
|
||||||
{:contract contract
|
|
||||||
:method "setTribute(uint256)"
|
|
||||||
:params [tribute]
|
|
||||||
:on-result [:tribute-to-talk.callback/set-tribute-transaction-sent]
|
|
||||||
:on-error [:tribute-to-talk.callback/set-tribute-transaction-failed]})
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:navigation/screen-params :tribute-to-talk :state]
|
|
||||||
:transaction-failed)}))
|
|
||||||
|
|
||||||
(fx/defn remove
|
|
||||||
{:events [:tribute-to-talk.ui/remove-pressed]}
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk]
|
|
||||||
{:step :finish
|
|
||||||
:state :disabled})}
|
|
||||||
(set-tribute-signing-flow 0)))
|
|
||||||
|
|
||||||
(fx/defn set-step-finish
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(let [tribute (get-in db [:navigation/screen-params :tribute-to-talk :snt-amount])]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:navigation/screen-params :tribute-to-talk :state] :signing)}
|
|
||||||
(set-tribute-signing-flow (tribute-to-talk.db/to-wei tribute))
|
|
||||||
(set-step :finish))))
|
|
||||||
|
|
||||||
(fx/defn open-learn-more
|
|
||||||
{:events [:tribute-to-talk.ui/learn-more-pressed]}
|
|
||||||
[cofx]
|
|
||||||
(set-step cofx :learn-more))
|
|
||||||
|
|
||||||
(fx/defn step-back
|
|
||||||
{:events [:tribute-to-talk.ui/step-back-pressed]}
|
|
||||||
[cofx]
|
|
||||||
(let [{:keys [step editing?]}
|
|
||||||
(get-in cofx [:db :navigation/screen-params :tribute-to-talk])]
|
|
||||||
(case step
|
|
||||||
(:intro :edit)
|
|
||||||
(navigation/navigate-back cofx)
|
|
||||||
|
|
||||||
(:learn-more :set-snt-amount)
|
|
||||||
(set-step cofx (if editing?
|
|
||||||
:edit
|
|
||||||
:intro))
|
|
||||||
|
|
||||||
:finish
|
|
||||||
(set-step cofx :set-snt-amount))))
|
|
||||||
|
|
||||||
(fx/defn step-forward
|
|
||||||
{:events [:tribute-to-talk.ui/step-forward-pressed]}
|
|
||||||
[cofx]
|
|
||||||
(let [{:keys [step editing?]}
|
|
||||||
(get-in cofx [:db :navigation/screen-params :tribute-to-talk])]
|
|
||||||
(case step
|
|
||||||
:intro
|
|
||||||
(set-step cofx :set-snt-amount)
|
|
||||||
|
|
||||||
:set-snt-amount
|
|
||||||
(set-step-finish cofx)
|
|
||||||
|
|
||||||
:finish
|
|
||||||
(navigation/navigate-back cofx))))
|
|
||||||
|
|
||||||
(defn get-new-snt-amount
|
|
||||||
[snt-amount numpad-symbol]
|
|
||||||
;; TODO: Put some logic in place so that incorrect numbers can not
|
|
||||||
;; be entered
|
|
||||||
(let [snt-amount (or (str snt-amount) "0")]
|
|
||||||
(if (= numpad-symbol :remove)
|
|
||||||
(let [len (count snt-amount)
|
|
||||||
s (subs snt-amount 0 (dec len))]
|
|
||||||
(cond-> s
|
|
||||||
;; Remove both the digit after the dot and the dot itself
|
|
||||||
(string/ends-with? s ".") (subs 0 (- len 2))
|
|
||||||
;; Set default value if last digit is removed
|
|
||||||
(string/blank? s) (do "0")))
|
|
||||||
(cond
|
|
||||||
;; Disallow two consecutive dots
|
|
||||||
(and (string/includes? snt-amount ".") (= numpad-symbol "."))
|
|
||||||
snt-amount
|
|
||||||
;; Disallow more than 2 digits after the dot
|
|
||||||
(and (string/includes? snt-amount ".")
|
|
||||||
(> (count (second (string/split snt-amount #"\."))) 1))
|
|
||||||
snt-amount
|
|
||||||
;; Disallow values larger or equal to 1 million
|
|
||||||
(>= (js/parseFloat (str snt-amount numpad-symbol))
|
|
||||||
tribute-to-talk.db/max-snt-amount)
|
|
||||||
snt-amount
|
|
||||||
;; Replace initial "0" by the first digit
|
|
||||||
(and (= snt-amount "0") (not= numpad-symbol "."))
|
|
||||||
(str numpad-symbol)
|
|
||||||
:else (str snt-amount numpad-symbol)))))
|
|
||||||
|
|
||||||
(fx/defn update-snt-amount
|
|
||||||
{:events [:tribute-to-talk.ui/numpad-key-pressed]}
|
|
||||||
[{:keys [db]} numpad-symbol]
|
|
||||||
{:db (update-in db
|
|
||||||
[:navigation/screen-params :tribute-to-talk :snt-amount]
|
|
||||||
#(get-new-snt-amount % numpad-symbol))})
|
|
||||||
|
|
||||||
(fx/defn start-editing
|
|
||||||
{:events [:tribute-to-talk.ui/edit-pressed]}
|
|
||||||
[{:keys [db]}]
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:navigation/screen-params :tribute-to-talk :step]
|
|
||||||
:set-snt-amount)})
|
|
||||||
|
|
||||||
(fx/defn on-check-tribute-success
|
|
||||||
{:events [:tribute-to-talk.callback/check-tribute-success]}
|
|
||||||
[cofx public-key tribute-to-talk]
|
|
||||||
(let [tribute-to-talk (when (tribute-to-talk.db/valid? tribute-to-talk)
|
|
||||||
tribute-to-talk)]
|
|
||||||
(if-let [me? (= public-key
|
|
||||||
(get-in cofx [:db :multiaccount :public-key]))]
|
|
||||||
(update-settings cofx tribute-to-talk)
|
|
||||||
(contact/set-tribute cofx public-key tribute-to-talk))))
|
|
||||||
|
|
||||||
(fx/defn on-no-tribute-found
|
|
||||||
{:events [:tribute-to-talk.callback/no-tribute-found]}
|
|
||||||
[cofx public-key]
|
|
||||||
(if-let [me? (= public-key
|
|
||||||
(get-in cofx [:db :multiaccount :public-key]))]
|
|
||||||
(update-settings cofx nil)
|
|
||||||
(contact/set-tribute cofx public-key nil)))
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
|
||||||
:tribute-to-talk/get-tribute
|
|
||||||
(fn [{:keys [contract address on-success]}]
|
|
||||||
(json-rpc/eth-call
|
|
||||||
{:contract contract
|
|
||||||
:method "getTribute(address)"
|
|
||||||
:params [address]
|
|
||||||
:outputs ["uint256"]
|
|
||||||
:on-success on-success})))
|
|
||||||
|
|
||||||
(fx/defn check-tribute
|
|
||||||
[{:keys [db] :as cofx} public-key]
|
|
||||||
(when (and (not (get-in db [:chats public-key :group-chat]))
|
|
||||||
(not (get-in db [:contacts/contacts public-key :tribute-to-talk
|
|
||||||
:transaction-hash]))
|
|
||||||
(not (whitelist/whitelisted-by?
|
|
||||||
(get-in db [:contacts/contacts public-key]))))
|
|
||||||
(if-let [contract (contracts/get-address db :status/tribute-to-talk)]
|
|
||||||
(let [address (ethereum/public-key->address public-key)]
|
|
||||||
{:tribute-to-talk/get-tribute
|
|
||||||
{:contract contract
|
|
||||||
:address address
|
|
||||||
:on-success
|
|
||||||
(fn [[tribute]]
|
|
||||||
(re-frame/dispatch
|
|
||||||
(if (pos? tribute)
|
|
||||||
[:tribute-to-talk.callback/check-tribute-success
|
|
||||||
public-key
|
|
||||||
{:snt-amount (str tribute)}]
|
|
||||||
[:tribute-to-talk.callback/no-tribute-found public-key])))}})
|
|
||||||
;; update settings if checking own manifest or do nothing otherwise
|
|
||||||
(if-let [me? (= public-key
|
|
||||||
(get-in cofx [:db :multiaccount :public-key]))]
|
|
||||||
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:navigation/screen-params :tribute-to-talk :unavailable?]
|
|
||||||
true)}
|
|
||||||
(update-settings nil))
|
|
||||||
(contact/set-tribute cofx public-key nil)))))
|
|
||||||
|
|
||||||
(fx/defn check-own-tribute
|
|
||||||
[cofx]
|
|
||||||
(check-tribute cofx (get-in cofx [:db :multiaccount :public-key])))
|
|
||||||
|
|
||||||
(fx/defn pay-tribute
|
|
||||||
{:events [:tribute-to-talk.ui/on-pay-to-chat-pressed]}
|
|
||||||
[{:keys [db] :as cofx} public-key]
|
|
||||||
(let [{:keys [address public-key tribute-to-talk]}
|
|
||||||
(get-in db [:contacts/contacts public-key])
|
|
||||||
{:keys [snt-amount]} tribute-to-talk]
|
|
||||||
(signing/eth-transaction-call
|
|
||||||
cofx
|
|
||||||
{:contract (contracts/get-address db :status/snt)
|
|
||||||
:method "transfer(address,uint256)"
|
|
||||||
:params [address snt-amount]
|
|
||||||
:on-result [:tribute-to-talk.callback/pay-tribute-transaction-sent public-key]})))
|
|
||||||
|
|
||||||
(defn tribute-transaction-trigger
|
|
||||||
[db {:keys [block error?]}]
|
|
||||||
(let [current-block (get db :ethereum/current-block)
|
|
||||||
transaction-block (or block
|
|
||||||
current-block)]
|
|
||||||
(or error?
|
|
||||||
(pos? (- current-block
|
|
||||||
(js/parseInt transaction-block))))))
|
|
||||||
|
|
||||||
(fx/defn on-pay-tribute-transaction-triggered
|
|
||||||
[{:keys [db] :as cofx}
|
|
||||||
public-key
|
|
||||||
{:keys [error? transfer symbol] :as transaction}]
|
|
||||||
(when (and transfer
|
|
||||||
(= symbol (ethereum/snt-symbol db))
|
|
||||||
(not error?))
|
|
||||||
(whitelist/mark-tribute-paid cofx public-key)))
|
|
||||||
|
|
||||||
(fx/defn on-pay-tribute-transaction-sent
|
|
||||||
{:events [:tribute-to-talk.callback/pay-tribute-transaction-sent]}
|
|
||||||
[{:keys [db] :as cofx} public-key transaction-hash]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:contacts/contacts public-key
|
|
||||||
:tribute-to-talk :transaction-hash]
|
|
||||||
transaction-hash)}
|
|
||||||
(transactions/watch-transaction
|
|
||||||
transaction-hash
|
|
||||||
{:trigger-fn
|
|
||||||
tribute-transaction-trigger
|
|
||||||
:on-trigger
|
|
||||||
#(on-pay-tribute-transaction-triggered public-key %)})))
|
|
||||||
|
|
||||||
(fx/defn on-set-tribute-transaction-triggered
|
|
||||||
[{:keys [db] :as cofx}
|
|
||||||
tribute
|
|
||||||
{:keys [error?] :as transaction}]
|
|
||||||
(if error?
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:navigation/screen-params
|
|
||||||
:tribute-to-talk :state]
|
|
||||||
:transaction-failed)}
|
|
||||||
(update-settings {:update nil}))
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:navigation/screen-params
|
|
||||||
:tribute-to-talk :state]
|
|
||||||
(if tribute
|
|
||||||
:completed
|
|
||||||
:disabled))}
|
|
||||||
(check-own-tribute)
|
|
||||||
(update-settings {:update nil}))))
|
|
||||||
|
|
||||||
(fx/defn on-set-tribute-transaction-sent
|
|
||||||
{:events [:tribute-to-talk.callback/set-tribute-transaction-sent]}
|
|
||||||
[{:keys [db] :as cofx} transaction-hash]
|
|
||||||
(let [{:keys [snt-amount message]} (get-in db [:navigation/screen-params
|
|
||||||
:tribute-to-talk])]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (assoc-in db [:navigation/screen-params
|
|
||||||
:tribute-to-talk :state]
|
|
||||||
:pending)}
|
|
||||||
(update-settings {:update {:transaction transaction-hash
|
|
||||||
:snt-amount snt-amount
|
|
||||||
:message message}})
|
|
||||||
(transactions/watch-transaction
|
|
||||||
transaction-hash
|
|
||||||
{:trigger-fn
|
|
||||||
tribute-transaction-trigger
|
|
||||||
:on-trigger
|
|
||||||
#(on-set-tribute-transaction-triggered snt-amount %)}))))
|
|
||||||
|
|
||||||
(fx/defn on-set-tribute-transaction-failed
|
|
||||||
{:events [:tribute-to-talk.callback/set-tribute-transaction-failed]}
|
|
||||||
[{:keys [db] :as cofx} error]
|
|
||||||
(log/error :set-tribute-transaction-failed error)
|
|
||||||
{:db (assoc-in db
|
|
||||||
[:navigation/screen-params :tribute-to-talk :state]
|
|
||||||
:transaction-failed)})
|
|
||||||
|
|
||||||
(fx/defn watch-set-tribute-transaction
|
|
||||||
"check if there is a pending transaction to set the tribute and
|
|
||||||
add a watch on that transaction
|
|
||||||
if there is a transaction check if the trigger is valid already"
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(when-let [tribute-update (get (tribute-to-talk.db/get-settings db)
|
|
||||||
:update)]
|
|
||||||
(let [{:keys [transaction snt-amount]} tribute-update]
|
|
||||||
(fx/merge cofx
|
|
||||||
(transactions/watch-transaction
|
|
||||||
transaction
|
|
||||||
{:trigger-fn
|
|
||||||
tribute-transaction-trigger
|
|
||||||
:on-trigger
|
|
||||||
#(on-set-tribute-transaction-triggered snt-amount %)})
|
|
||||||
(when-let [transaction (get-in db [:wallet :transactions
|
|
||||||
transaction])]
|
|
||||||
(transactions/check-transaction transaction))))))
|
|
||||||
|
|
||||||
(fx/defn init
|
|
||||||
[cofx]
|
|
||||||
(fx/merge cofx
|
|
||||||
(check-own-tribute)
|
|
||||||
(watch-set-tribute-transaction)))
|
|
|
@ -1,139 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.core-test
|
|
||||||
(:require [cljs.test :refer-macros [deftest testing is]]
|
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
|
||||||
[status-im.utils.identicon :as identicon]
|
|
||||||
[status-im.tribute-to-talk.core :as tribute-to-talk]
|
|
||||||
[status-im.utils.money :as money]))
|
|
||||||
|
|
||||||
(deftest get-new-snt-amount
|
|
||||||
(testing "staying under the limit"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"999999.9" "9")
|
|
||||||
"999999.99")))
|
|
||||||
(testing "getting over the limit"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"100000" "0")
|
|
||||||
"100000")))
|
|
||||||
(testing "replace initial 0 by the first digit"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0" "1")
|
|
||||||
"1")))
|
|
||||||
(testing "disallow more than two dots"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0." ".")
|
|
||||||
"0."))
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0.0" ".")
|
|
||||||
"0.0")))
|
|
||||||
(testing "disallow more than two digits after dot"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0.0" "0")
|
|
||||||
"0.00"))
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0.00" "1")
|
|
||||||
"0.00")))
|
|
||||||
(testing "0 remains if removed is pressed on last digit"
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"0" :remove)
|
|
||||||
"0"))
|
|
||||||
(is (= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"1" :remove)
|
|
||||||
"0")))
|
|
||||||
(testing "dot is removed when last digit after dot is removed"
|
|
||||||
(= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"1." :remove)
|
|
||||||
"1")
|
|
||||||
(= (tribute-to-talk/get-new-snt-amount
|
|
||||||
"1.1" :remove)
|
|
||||||
"1")))
|
|
||||||
|
|
||||||
(def recipient-pk "0x04263d74e55775280e75b4a4e9a45ba59fc372793a869c5d9c4fa2100556d9963e3f4fbfa1724ec94a46e6da057540ab248ed1f5eb956e36e3129ecd50fade2c97")
|
|
||||||
(def recipient-address "0xdff1a5e4e57d9723b3294e0f4413372e3ea9a8ff")
|
|
||||||
|
|
||||||
(def user-cofx
|
|
||||||
{:db {:networks/current-network "testnet_rpc"
|
|
||||||
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
|
|
||||||
:multiaccount
|
|
||||||
{:address "954d4393515747ea75808a0301fb73317ae1e460"}
|
|
||||||
:tribute-to-talk {:testnet {:snt-amount "1000000000000000000"}}
|
|
||||||
:contacts/contacts
|
|
||||||
{recipient-pk {:name "bob"
|
|
||||||
:address recipient-address
|
|
||||||
:public-key recipient-pk
|
|
||||||
:tribute-to-talk {:snt-amount "1000000000000000000"}}}
|
|
||||||
:wallet {:balance {:STT (money/bignumber "1000000000000000000")}}}})
|
|
||||||
|
|
||||||
(deftest tribute-transaction-trigger
|
|
||||||
(testing "transaction error"
|
|
||||||
(is (tribute-to-talk/tribute-transaction-trigger
|
|
||||||
{:ethereum/current-block 10}
|
|
||||||
{:block "5"
|
|
||||||
:error? true})))
|
|
||||||
(testing "transaction confirmed"
|
|
||||||
(is (tribute-to-talk/tribute-transaction-trigger
|
|
||||||
{:ethereum/current-block 10}
|
|
||||||
{:block "5"})))
|
|
||||||
(testing "transaction not confirmed yet"
|
|
||||||
(is (not (tribute-to-talk/tribute-transaction-trigger
|
|
||||||
{:ethereum/current-block 5}
|
|
||||||
{:block "5"})))))
|
|
||||||
|
|
||||||
(def public-key "0xabcdef")
|
|
||||||
(def my-public-key "0x000001")
|
|
||||||
(def test-db
|
|
||||||
{:chats
|
|
||||||
{public-key {:group-chat false}}
|
|
||||||
:contacts/contacts
|
|
||||||
{public-key {:tribute-to-talk {}
|
|
||||||
:system-tags #{}}}
|
|
||||||
:multiaccount
|
|
||||||
{:public-key my-public-key}
|
|
||||||
:networks/current-network "mainnet_rpc"
|
|
||||||
:networks/networks {"mainnet_rpc" {:id "mainnet_rpc"
|
|
||||||
:config {:NetworkId 1}}
|
|
||||||
"testnet_rpc" {:id "testnet_rpc"
|
|
||||||
:config {:NetworkId 3}}}})
|
|
||||||
|
|
||||||
(deftest check-tribute
|
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
|
||||||
identicon/identicon (constantly "generated")]
|
|
||||||
(testing "No contract in network, own public key"
|
|
||||||
(let [result (tribute-to-talk/check-tribute {:db test-db} my-public-key)]
|
|
||||||
(is (= (-> test-db
|
|
||||||
(assoc :navigation/screen-params {:tribute-to-talk {:unavailable? true}})
|
|
||||||
(assoc-in [:multiaccount :tribute-to-talk] {:mainnet nil}))
|
|
||||||
(:db result)))))
|
|
||||||
|
|
||||||
(testing "No contract in network, another public key"
|
|
||||||
(let [result (tribute-to-talk/check-tribute {:db test-db} public-key)]
|
|
||||||
(is (= {:disabled? true}
|
|
||||||
(get-in result [:db :contacts/contacts public-key :tribute-to-talk])))))
|
|
||||||
|
|
||||||
(testing "Contract in network, another public key"
|
|
||||||
(let [result (tribute-to-talk/check-tribute {:db (assoc test-db :networks/current-network "testnet_rpc")}
|
|
||||||
public-key)]
|
|
||||||
(is (= "0xC61aa0287247a0398589a66fCD6146EC0F295432"
|
|
||||||
(get-in result [:tribute-to-talk/get-tribute :contract])))))
|
|
||||||
|
|
||||||
(testing "Added by other user"
|
|
||||||
(let [result (tribute-to-talk/check-tribute
|
|
||||||
{:db (update-in test-db
|
|
||||||
[:contacts/contacts public-key :system-tags]
|
|
||||||
conj :contact/request-received)}
|
|
||||||
public-key)]
|
|
||||||
(is (= result nil))))
|
|
||||||
|
|
||||||
(testing "Group chat"
|
|
||||||
(let [result (tribute-to-talk/check-tribute
|
|
||||||
{:db (assoc-in test-db [:chats public-key :group-chat] true)}
|
|
||||||
public-key)]
|
|
||||||
(is (= result nil))))
|
|
||||||
|
|
||||||
(testing "Added by this user"
|
|
||||||
(let [result (tribute-to-talk/check-tribute
|
|
||||||
{:db (update-in test-db
|
|
||||||
[:contacts/contacts public-key :system-tags]
|
|
||||||
conj :contact/added)}
|
|
||||||
public-key)]
|
|
||||||
(is (= {:disabled? true}
|
|
||||||
(get-in result [:db :contacts/contacts public-key :tribute-to-talk])))))))
|
|
|
@ -1,71 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.db
|
|
||||||
(:require [status-im.ethereum.core :as ethereum]
|
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.utils.money :as money]
|
|
||||||
["web3-utils" :as utils]))
|
|
||||||
|
|
||||||
(defn tribute-received?
|
|
||||||
[contact]
|
|
||||||
(contains? (:system-tags contact) :tribute-to-talk/received))
|
|
||||||
|
|
||||||
(def max-snt-amount 1000000)
|
|
||||||
|
|
||||||
(defn to-wei
|
|
||||||
[s]
|
|
||||||
(when s
|
|
||||||
(.toWei utils s)))
|
|
||||||
|
|
||||||
(defn from-wei
|
|
||||||
[s]
|
|
||||||
(when s
|
|
||||||
(.fromWei utils s)))
|
|
||||||
|
|
||||||
(defn tribute-status
|
|
||||||
[{:keys [system-tags tribute-to-talk]}]
|
|
||||||
(let [{:keys [snt-amount transaction-hash]} tribute-to-talk]
|
|
||||||
(cond (contains? system-tags :tribute-to-talk/paid) :paid
|
|
||||||
(not (nil? transaction-hash)) :pending
|
|
||||||
(pos? snt-amount) :required
|
|
||||||
:else :none)))
|
|
||||||
|
|
||||||
(defn status-label
|
|
||||||
[tribute-status tribute]
|
|
||||||
(case tribute-status
|
|
||||||
:paid (i18n/label :t/tribute-state-paid)
|
|
||||||
:pending (i18n/label :t/tribute-state-pending)
|
|
||||||
:required (i18n/label :t/tribute-state-required
|
|
||||||
{:snt-amount (from-wei tribute)})
|
|
||||||
nil))
|
|
||||||
|
|
||||||
(defn valid?
|
|
||||||
[{:keys [snt-amount]}]
|
|
||||||
(when (string? snt-amount)
|
|
||||||
(try (let [converted-snt-amount (from-wei snt-amount)]
|
|
||||||
(and (= (to-wei converted-snt-amount)
|
|
||||||
snt-amount)
|
|
||||||
(< 0 (js/parseFloat converted-snt-amount) max-snt-amount)))
|
|
||||||
(catch :default _ nil))))
|
|
||||||
|
|
||||||
(defn get-settings
|
|
||||||
[db]
|
|
||||||
(let [chain-keyword (ethereum/chain-keyword db)]
|
|
||||||
(get-in db [:multiaccount :tribute-to-talk chain-keyword])))
|
|
||||||
|
|
||||||
(defn enabled?
|
|
||||||
[settings]
|
|
||||||
(:snt-amount settings))
|
|
||||||
|
|
||||||
(defn valid-tribute-transaction?
|
|
||||||
[db tribute-required tribute-transaction from-public-key]
|
|
||||||
(let [{:keys [value block from] :as transaction}
|
|
||||||
(get-in db [:wallet :transactions tribute-transaction])
|
|
||||||
current-block (get db :ethereum/current-block)
|
|
||||||
transaction-block (or block
|
|
||||||
current-block)]
|
|
||||||
(and transaction
|
|
||||||
(pos? (- current-block
|
|
||||||
(js/parseInt transaction-block)))
|
|
||||||
(.lessThanOrEqualTo ^js (money/bignumber tribute-required)
|
|
||||||
(money/bignumber value))
|
|
||||||
(ethereum/address= (ethereum/public-key->address from-public-key)
|
|
||||||
from))))
|
|
|
@ -1,81 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.db-test
|
|
||||||
(:require [cljs.test :refer-macros [deftest testing is]]
|
|
||||||
[status-im.tribute-to-talk.db :as db]))
|
|
||||||
|
|
||||||
(deftest tribute-status
|
|
||||||
(is (= (db/tribute-status {:system-tags #{:tribute-to-talk/paid}
|
|
||||||
:tribute-to-talk {:snt-amount 1000
|
|
||||||
:transaction-hash "0x"}})
|
|
||||||
:paid))
|
|
||||||
(is (= (db/tribute-status {:tribute-to-talk {:snt-amount 1000
|
|
||||||
:transaction-hash "0x"}})
|
|
||||||
:pending))
|
|
||||||
(is (= (db/tribute-status {:tribute-to-talk {:snt-amount 1000}})
|
|
||||||
:required))
|
|
||||||
(is (= (db/tribute-status {:tribute-to-talk {:snt-amount 0}})
|
|
||||||
:none))
|
|
||||||
(is (= (db/tribute-status {})
|
|
||||||
:none)))
|
|
||||||
|
|
||||||
(deftest valid?
|
|
||||||
(is (db/valid? {:snt-amount "1000"}))
|
|
||||||
(is (not (db/valid? {:snt-amount "-1000"})))
|
|
||||||
(is (not (db/valid? {:snt-amount "1000001000000000000000000"})))
|
|
||||||
(is (not (db/valid? {:snt-amount 5})))
|
|
||||||
(is (not (db/valid? {:snt-amount "abcdef"}))))
|
|
||||||
|
|
||||||
(def sender-pk "0x04263d74e55775280e75b4a4e9a45ba59fc372793a869c5d9c4fa2100556d9963e3f4fbfa1724ec94a46e6da057540ab248ed1f5eb956e36e3129ecd50fade2c97")
|
|
||||||
(def sender-address "0xdff1a5e4e57d9723b3294e0f4413372e3ea9a8ff")
|
|
||||||
|
|
||||||
(deftest valid-tribute-transaction?
|
|
||||||
(testing "a valid transaction"
|
|
||||||
(is (db/valid-tribute-transaction?
|
|
||||||
{:wallet {:transactions
|
|
||||||
{"transaction-hash-1"
|
|
||||||
{:value "1000000000000000000"
|
|
||||||
:block "5"
|
|
||||||
:from sender-address}}}
|
|
||||||
:ethereum/current-block 8}
|
|
||||||
"1000000000000000000"
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk)))
|
|
||||||
(testing "a transaction"
|
|
||||||
(testing "with insufficient value transfered"
|
|
||||||
(is (not (db/valid-tribute-transaction?
|
|
||||||
{:wallet {:transactions
|
|
||||||
{"transaction-hash-1"
|
|
||||||
{:value "1"
|
|
||||||
:block "5"
|
|
||||||
:from sender-address}}}
|
|
||||||
:ethereum/current-block 8}
|
|
||||||
"1000000000000000000"
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk)))
|
|
||||||
(testing "that was not confirmed yet"
|
|
||||||
(is (not (db/valid-tribute-transaction?
|
|
||||||
{:wallet {:transactions
|
|
||||||
{"transaction-hash-1"
|
|
||||||
{:value "1000000000000000000"
|
|
||||||
:block "8"
|
|
||||||
:from sender-address}}}
|
|
||||||
:ethereum/current-block 8}
|
|
||||||
"1000000000000000000"
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk))))
|
|
||||||
(testing "from someone else"
|
|
||||||
(is (not (db/valid-tribute-transaction?
|
|
||||||
{:wallet {:transactions
|
|
||||||
{"transaction-hash-1"
|
|
||||||
{:value "1000000000000000000"
|
|
||||||
:block "5"
|
|
||||||
:from "another address"}}}
|
|
||||||
:ethereum/current-block 8}
|
|
||||||
"1000000000000000000"
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk))))))
|
|
||||||
(testing "a transaction that does not exist"
|
|
||||||
(is (not (db/valid-tribute-transaction?
|
|
||||||
{:ethereum/current-block 8}
|
|
||||||
"1000000000000000000"
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk)))))
|
|
|
@ -1,79 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.whitelist
|
|
||||||
(:require [status-im.contact.db :as contact.db]
|
|
||||||
[status-im.data-store.contacts :as contacts-store]
|
|
||||||
[status-im.constants :as constants]
|
|
||||||
[status-im.tribute-to-talk.db :as tribute-to-talk.db]
|
|
||||||
[status-im.utils.fx :as fx]))
|
|
||||||
|
|
||||||
(defn whitelisted-by? [{:keys [system-tags]}]
|
|
||||||
(or (contains? system-tags :contact/request-received)
|
|
||||||
(contains? system-tags :tribute-to-talk/paid)
|
|
||||||
(contains? system-tags :tribute-to-talk/received)))
|
|
||||||
|
|
||||||
(defn whitelisted? [{:keys [system-tags]}]
|
|
||||||
(or (contains? system-tags :contact/added)
|
|
||||||
(contains? system-tags :tribute-to-talk/paid)
|
|
||||||
(contains? system-tags :tribute-to-talk/received)))
|
|
||||||
|
|
||||||
(defn get-contact-whitelist
|
|
||||||
[contacts]
|
|
||||||
(reduce (fn [acc {:keys [public-key] :as contact}]
|
|
||||||
(if (whitelisted? contact)
|
|
||||||
(conj acc public-key) acc))
|
|
||||||
(hash-set) contacts))
|
|
||||||
|
|
||||||
(fx/defn add-to-whitelist
|
|
||||||
"Add contact to whitelist"
|
|
||||||
[{:keys [db]} public-key]
|
|
||||||
{:db (update db :contacts/whitelist (fnil conj #{}) public-key)})
|
|
||||||
|
|
||||||
(defn- mark-tribute
|
|
||||||
[{:keys [db now] :as cofx} public-key tag]
|
|
||||||
(let [contact (-> (contact.db/public-key->contact
|
|
||||||
(:contacts/contacts db)
|
|
||||||
public-key)
|
|
||||||
(assoc :last-updated now)
|
|
||||||
(update :system-tags conj tag))]
|
|
||||||
(fx/merge cofx
|
|
||||||
{:db (-> db
|
|
||||||
(assoc-in [:contacts/contacts public-key] contact))}
|
|
||||||
(contacts-store/save-contact contact)
|
|
||||||
(add-to-whitelist public-key))))
|
|
||||||
|
|
||||||
(fx/defn mark-tribute-paid
|
|
||||||
[cofx public-key]
|
|
||||||
(mark-tribute cofx public-key :tribute-to-talk/paid))
|
|
||||||
|
|
||||||
(fx/defn mark-tribute-received
|
|
||||||
[cofx public-key]
|
|
||||||
(mark-tribute cofx public-key :tribute-to-talk/received))
|
|
||||||
|
|
||||||
(fx/defn enable-whitelist
|
|
||||||
[{:keys [db] :as cofx}]
|
|
||||||
(if (tribute-to-talk.db/enabled? (tribute-to-talk.db/get-settings db))
|
|
||||||
{:db (assoc db :contacts/whitelist
|
|
||||||
(get-contact-whitelist (vals (:contacts/contacts db))))}
|
|
||||||
{:db (dissoc db :contacts/whitelist)}))
|
|
||||||
|
|
||||||
(fx/defn filter-message
|
|
||||||
"clojure semantics of filter, if true the message is allowed
|
|
||||||
if it is a user message and tribute to talk is enabled, the user must be
|
|
||||||
in the whitelist or there must be a valid tribute transaction id passed
|
|
||||||
along the message"
|
|
||||||
[{:keys [db] :as cofx} received-message-fx message-type tribute-transaction from]
|
|
||||||
;; if it is not a user-message or the user is whitelisted it passes
|
|
||||||
(if (or (not= constants/message-type-one-to-one message-type)
|
|
||||||
(contains? (:contacts/whitelist db) from))
|
|
||||||
received-message-fx
|
|
||||||
;; if ttt is disabled it passes
|
|
||||||
(if-let [snt-amount (:snt-amount (tribute-to-talk.db/get-settings db))]
|
|
||||||
(let [contact (get-in db [:contacts/contacts from])]
|
|
||||||
;; if the tribute is not paid the message is dropped
|
|
||||||
;; otherwise it passes and the user is added to the whitelist
|
|
||||||
;; through system tags
|
|
||||||
(when (tribute-to-talk.db/valid-tribute-transaction?
|
|
||||||
db snt-amount tribute-transaction from)
|
|
||||||
(fx/merge cofx
|
|
||||||
received-message-fx
|
|
||||||
(mark-tribute-received from))))
|
|
||||||
received-message-fx)))
|
|
|
@ -1,136 +0,0 @@
|
||||||
(ns status-im.tribute-to-talk.whitelist-test
|
|
||||||
(:require [cljs.test :refer-macros [deftest testing is]]
|
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
|
||||||
[status-im.constants :as constants]
|
|
||||||
[status-im.utils.identicon :as identicon]
|
|
||||||
[status-im.tribute-to-talk.whitelist :as whitelist]))
|
|
||||||
|
|
||||||
(def user-contacts
|
|
||||||
{"not whitelisted"
|
|
||||||
{:public-key "not whitelisted"
|
|
||||||
:system-tags #{}}
|
|
||||||
"not whitelisted2"
|
|
||||||
{:public-key "not whitelisted2"
|
|
||||||
:system-tags #{:contact/request-received}}
|
|
||||||
"whitelisted because tribute paid"
|
|
||||||
{:public-key "whitelisted because tribute paid"
|
|
||||||
:system-tags #{:tribute-to-talk/paid}}
|
|
||||||
"whitelisted because tribute received"
|
|
||||||
{:public-key "whitelisted because tribute received"
|
|
||||||
:system-tags #{:tribute-to-talk/received}}
|
|
||||||
"whitelisted because added"
|
|
||||||
{:public-key "whitelisted because added"
|
|
||||||
:system-tags #{:contact/added}}})
|
|
||||||
|
|
||||||
(deftest get-contact-whitelist
|
|
||||||
(is (= 3
|
|
||||||
(count (whitelist/get-contact-whitelist
|
|
||||||
(vals user-contacts))))))
|
|
||||||
|
|
||||||
(deftest add-to-whitelist
|
|
||||||
(testing "adding contact to whitelist"
|
|
||||||
(is (= #{"bob" "bob2"}
|
|
||||||
(get-in (whitelist/add-to-whitelist
|
|
||||||
{:db {:contacts/whitelist #{"bob2"}}} "bob")
|
|
||||||
[:db :contacts/whitelist])))
|
|
||||||
(testing "when there is no whitelist yet"
|
|
||||||
(is (= #{"bob"}
|
|
||||||
(get-in (whitelist/add-to-whitelist
|
|
||||||
{:db {}} "bob")
|
|
||||||
[:db :contacts/whitelist]))
|
|
||||||
(whitelist/add-to-whitelist {:db {}} "bob")))
|
|
||||||
(testing "when already added"
|
|
||||||
(is (= #{"bob"}
|
|
||||||
(get-in (whitelist/add-to-whitelist
|
|
||||||
{:db {:contacts/whitelist #{"bob"}}} "bob")
|
|
||||||
[:db :contacts/whitelist]))))))
|
|
||||||
|
|
||||||
(deftest mark-tribute-paid
|
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
|
||||||
identicon/identicon (constantly "generated")]
|
|
||||||
(let [result (whitelist/mark-tribute-paid {:db {}} "bob")]
|
|
||||||
(testing "contact was added to whitelist"
|
|
||||||
(is (= (get-in result
|
|
||||||
[:db :contacts/whitelist])
|
|
||||||
#{"bob"})))
|
|
||||||
(testing "contact was tagged as tribute paid"
|
|
||||||
(is (= (get-in result
|
|
||||||
[:db :contacts/contacts "bob" :system-tags])
|
|
||||||
#{:tribute-to-talk/paid}))))))
|
|
||||||
|
|
||||||
(deftest mark-tribute-received
|
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
|
||||||
identicon/identicon (constantly "generated")]
|
|
||||||
(let [result (whitelist/mark-tribute-received {:db {}} "bob")]
|
|
||||||
(testing "contact was added to whitelist"
|
|
||||||
(is (= (get-in result
|
|
||||||
[:db :contacts/whitelist])
|
|
||||||
#{"bob"})))
|
|
||||||
(testing "contact was tagged as tribute paid"
|
|
||||||
(is (= (get-in result
|
|
||||||
[:db :contacts/contacts "bob" :system-tags])
|
|
||||||
#{:tribute-to-talk/received}))))))
|
|
||||||
|
|
||||||
(def sender-pk "0x04263d74e55775280e75b4a4e9a45ba59fc372793a869c5d9c4fa2100556d9963e3f4fbfa1724ec94a46e6da057540ab248ed1f5eb956e36e3129ecd50fade2c97")
|
|
||||||
(def sender-address "0xdff1a5e4e57d9723b3294e0f4413372e3ea9a8ff")
|
|
||||||
|
|
||||||
(def ttt-enabled-multiaccount
|
|
||||||
{:db {:multiaccount {:tribute-to-talk {:testnet {:snt-amount "1000000000000000000"}}}
|
|
||||||
:networks/current-network "testnet_rpc"
|
|
||||||
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
|
|
||||||
:contacts/contacts user-contacts
|
|
||||||
:wallet {:transactions
|
|
||||||
{"transaction-hash-1"
|
|
||||||
{:value "1000000000000000000"
|
|
||||||
:block "5"
|
|
||||||
:from sender-address}}}
|
|
||||||
:ethereum/current-block 8}})
|
|
||||||
|
|
||||||
(def ttt-disabled-multiaccount
|
|
||||||
{:db {:multiaccount {:tribute-to-talk {}}
|
|
||||||
:networks/current-network "testnet_rpc"
|
|
||||||
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
|
|
||||||
:contacts/contacts user-contacts}})
|
|
||||||
|
|
||||||
(deftest enable-whitelist
|
|
||||||
(testing "ttt enabled multiaccount"
|
|
||||||
(is (= (get-in (whitelist/enable-whitelist ttt-enabled-multiaccount)
|
|
||||||
[:db :contacts/whitelist]))))
|
|
||||||
(testing "ttt disabled multiaccount"
|
|
||||||
(is (not (get-in (whitelist/enable-whitelist ttt-disabled-multiaccount)
|
|
||||||
[:db :contacts/whitelist])))))
|
|
||||||
|
|
||||||
(deftest filter-message
|
|
||||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
|
||||||
identicon/identicon (constantly "generated")]
|
|
||||||
(testing "not a user message"
|
|
||||||
(whitelist/filter-message
|
|
||||||
ttt-enabled-multiaccount
|
|
||||||
:unfiltered-fx
|
|
||||||
:not-user-message
|
|
||||||
nil
|
|
||||||
"public-key"))
|
|
||||||
(testing "user is whitelisted"
|
|
||||||
(whitelist/filter-message
|
|
||||||
(whitelist/enable-whitelist ttt-enabled-multiaccount)
|
|
||||||
:unfiltered-fx
|
|
||||||
constants/message-type-one-to-one
|
|
||||||
nil
|
|
||||||
"whitelisted because added"))
|
|
||||||
(testing "tribute to talk is disabled"
|
|
||||||
(whitelist/filter-message
|
|
||||||
ttt-disabled-multiaccount
|
|
||||||
:unfiltered-fx
|
|
||||||
constants/message-type-one-to-one
|
|
||||||
nil
|
|
||||||
"public-key"))
|
|
||||||
(testing "user is not whitelisted but transaction is valid"
|
|
||||||
(let [result (whitelist/filter-message
|
|
||||||
ttt-enabled-multiaccount
|
|
||||||
#(assoc % :message-received true)
|
|
||||||
constants/message-type-one-to-one
|
|
||||||
"transaction-hash-1"
|
|
||||||
sender-pk)]
|
|
||||||
(is (contains? (get-in result [:db :contacts/whitelist])
|
|
||||||
sender-pk))
|
|
||||||
(is (:message-received result))))))
|
|
|
@ -1,95 +0,0 @@
|
||||||
|
|
||||||
(ns status-im.ui.screens.chat.ttt
|
|
||||||
(:require [re-frame.core :as re-frame]
|
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[status-im.ui.components.react :as react]
|
|
||||||
[status-im.ui.screens.chat.styles.main :as style]
|
|
||||||
[status-im.ui.screens.profile.tribute-to-talk.views
|
|
||||||
:as
|
|
||||||
tribute-to-talk.views]))
|
|
||||||
|
|
||||||
(defn tribute-to-talk-header
|
|
||||||
[name]
|
|
||||||
[react/nested-text {:style (assoc style/intro-header-description
|
|
||||||
:margin-bottom 32)}
|
|
||||||
(i18n/label :t/tribute-required-by-multiaccount {:multiaccount-name name})
|
|
||||||
[{:style {:color colors/blue}
|
|
||||||
:on-press #(re-frame/dispatch [:navigate-to :tribute-learn-more])}
|
|
||||||
(str " " (i18n/label :learn-more))]])
|
|
||||||
|
|
||||||
(defn pay-to-chat-messages
|
|
||||||
[snt-amount chat-id tribute-status tribute-label
|
|
||||||
fiat-amount fiat-currency token]
|
|
||||||
[tribute-to-talk.views/pay-to-chat-message
|
|
||||||
{:snt-amount snt-amount
|
|
||||||
:public-key chat-id
|
|
||||||
:tribute-status tribute-status
|
|
||||||
:tribute-label tribute-label
|
|
||||||
:fiat-amount fiat-amount
|
|
||||||
:fiat-currency fiat-currency
|
|
||||||
:token token
|
|
||||||
:style {:margin-horizontal 8
|
|
||||||
:align-items :flex-start
|
|
||||||
:align-self (if snt-amount :flex-start :flex-end)}}])
|
|
||||||
|
|
||||||
(defn one-to-one-chat-description-container
|
|
||||||
[{:keys [chat-id name]
|
|
||||||
:tribute-to-talk/keys [received? tribute-status
|
|
||||||
tribute-label snt-amount on-share-my-profile
|
|
||||||
fiat-amount fiat-currency token]}]
|
|
||||||
(case tribute-status
|
|
||||||
:loading
|
|
||||||
[react/view (assoc (dissoc style/empty-chat-container :flex)
|
|
||||||
:justify-content :flex-end)
|
|
||||||
[react/view {:style {:align-items :center :justify-content :flex-end}}
|
|
||||||
[react/view {:style {:flex-direction :row :justify-content :center}}
|
|
||||||
[react/text {:style style/loading-text}
|
|
||||||
(i18n/label :t/loading)]
|
|
||||||
[react/activity-indicator {:color colors/gray
|
|
||||||
:animating true}]]]]
|
|
||||||
|
|
||||||
:required
|
|
||||||
[react/view
|
|
||||||
[tribute-to-talk-header name]
|
|
||||||
[pay-to-chat-messages snt-amount chat-id tribute-status tribute-label
|
|
||||||
fiat-amount fiat-currency token]
|
|
||||||
[react/view {:style style/are-you-friends-bubble}
|
|
||||||
[react/text {:style (assoc style/are-you-friends-text
|
|
||||||
:font-weight "500")}
|
|
||||||
(i18n/label :t/tribute-to-talk-are-you-friends)]
|
|
||||||
[react/text {:style style/are-you-friends-text}
|
|
||||||
(i18n/label :t/tribute-to-talk-ask-to-be-added)]
|
|
||||||
[react/text {:style style/share-my-profile
|
|
||||||
:on-press on-share-my-profile}
|
|
||||||
(i18n/label :t/share-my-profile)]]]
|
|
||||||
|
|
||||||
:pending
|
|
||||||
[react/view
|
|
||||||
[tribute-to-talk-header name]
|
|
||||||
[pay-to-chat-messages snt-amount chat-id tribute-status tribute-label
|
|
||||||
fiat-amount fiat-currency token]]
|
|
||||||
|
|
||||||
(:paid :none)
|
|
||||||
[react/view
|
|
||||||
;[intro-header contact]
|
|
||||||
(when (= tribute-status :paid)
|
|
||||||
[pay-to-chat-messages snt-amount chat-id tribute-status tribute-label
|
|
||||||
fiat-amount fiat-currency token])
|
|
||||||
(when received?
|
|
||||||
[pay-to-chat-messages nil nil nil nil nil nil nil])
|
|
||||||
|
|
||||||
(when (or (= tribute-status :paid) received?)
|
|
||||||
[react/view {:style {:margin-top 16 :margin-horizontal 8}}
|
|
||||||
[react/nested-text {:style style/tribute-received-note}
|
|
||||||
(when received?
|
|
||||||
[{:style (assoc style/tribute-received-note :color colors/gray)}
|
|
||||||
(i18n/label :tribute-to-talk-tribute-received1)])
|
|
||||||
[{:style (assoc style/tribute-received-note :font-weight "500")}
|
|
||||||
name]
|
|
||||||
[{:style (assoc style/tribute-received-note :color colors/gray)}
|
|
||||||
(i18n/label (if received?
|
|
||||||
:tribute-to-talk-tribute-received2
|
|
||||||
:tribute-to-talk-contact-received-your-tribute))]]])]))
|
|
||||||
|
|
||||||
;[intro-header contact]))
|
|
|
@ -83,7 +83,17 @@
|
||||||
:height 40}
|
:height 40}
|
||||||
[react/image {:source (resources/get-image :keycard-logo-blue)
|
[react/image {:source (resources/get-image :keycard-logo-blue)
|
||||||
:style {:width 24 :height 24}}]]
|
:style {:width 24 :height 24}}]]
|
||||||
:on-press #(hide-sheet-and-dispatch [::keycard/recover-with-keycard-pressed])}])]]))
|
:on-press #(hide-sheet-and-dispatch [::keycard/recover-with-keycard-pressed])}])
|
||||||
|
(when config/database-management-enabled?
|
||||||
|
[quo/list-item {:theme :accent
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:multiaccounts.login.ui/import-db-submitted])
|
||||||
|
:icon :main-icons/receive
|
||||||
|
:title "Import unencrypted"}])
|
||||||
|
(when config/database-management-enabled?
|
||||||
|
[quo/list-item {:theme :accent
|
||||||
|
:on-press #(hide-sheet-and-dispatch [:multiaccounts.login.ui/export-db-submitted])
|
||||||
|
:icon :main-icons/send
|
||||||
|
:title "Export unencrypted"}])]]))
|
||||||
|
|
||||||
(def bottom-sheet
|
(def bottom-sheet
|
||||||
{:content bottom-sheet-view})
|
{:content bottom-sheet-view})
|
||||||
|
|
|
@ -1,254 +0,0 @@
|
||||||
(ns status-im.ui.screens.profile.tribute-to-talk.styles
|
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
|
||||||
|
|
||||||
(def intro-container
|
|
||||||
{:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:margin-horizontal 32})
|
|
||||||
|
|
||||||
(def intro-image
|
|
||||||
{:width 246
|
|
||||||
:height 219
|
|
||||||
:margin-vertical 32})
|
|
||||||
|
|
||||||
(def intro-text
|
|
||||||
{:typography :header
|
|
||||||
:text-align :center})
|
|
||||||
|
|
||||||
(def description-label
|
|
||||||
{:text-align :center
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def step-n
|
|
||||||
{:margin-top 5
|
|
||||||
:font-size 14
|
|
||||||
:text-align :center
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def tribute-to-talk
|
|
||||||
{:typography :main-medium
|
|
||||||
:text-align :center})
|
|
||||||
|
|
||||||
(def container
|
|
||||||
{:flex 1
|
|
||||||
:background-color colors/white})
|
|
||||||
|
|
||||||
(def set-snt-amount-container
|
|
||||||
{:flex-grow 1
|
|
||||||
:flex-direction :column
|
|
||||||
:background-color colors/white})
|
|
||||||
|
|
||||||
(defn horizontal-separator
|
|
||||||
[min-height max-height]
|
|
||||||
{:flex 1
|
|
||||||
:min-height min-height
|
|
||||||
:max-height max-height})
|
|
||||||
|
|
||||||
(def number-row
|
|
||||||
{:flex-direction :row})
|
|
||||||
|
|
||||||
(def number-pad
|
|
||||||
{:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:margin-bottom 24
|
|
||||||
:min-height 292
|
|
||||||
:max-height 328})
|
|
||||||
|
|
||||||
(def number-container
|
|
||||||
{:width 64
|
|
||||||
:height 64
|
|
||||||
:border-radius 32
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:background-color colors/blue-light})
|
|
||||||
|
|
||||||
(def vertical-number-separator
|
|
||||||
{:flex 1
|
|
||||||
:min-width 16
|
|
||||||
:max-width 32})
|
|
||||||
|
|
||||||
(def number
|
|
||||||
{:font-size 22
|
|
||||||
:color colors/blue})
|
|
||||||
|
|
||||||
(def snt-amount-container
|
|
||||||
{:margin-horizontal 16
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(def snt-amount
|
|
||||||
{:font-size 32})
|
|
||||||
|
|
||||||
(def snt-amount-label
|
|
||||||
(assoc snt-amount :color colors/gray))
|
|
||||||
|
|
||||||
(def snt-asset-value
|
|
||||||
{:typography :main-medium
|
|
||||||
:color colors/gray})
|
|
||||||
|
|
||||||
(def finish-label
|
|
||||||
{:typography :header
|
|
||||||
:text-align :center})
|
|
||||||
|
|
||||||
(defn finish-circle [color radius]
|
|
||||||
{:background-color color
|
|
||||||
:width (* 2 radius)
|
|
||||||
:height (* 2 radius)
|
|
||||||
:border-radius radius
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(def finish-circle-with-shadow
|
|
||||||
(assoc (finish-circle colors/white 40)
|
|
||||||
:elevation 5
|
|
||||||
:shadow-offset {:width 0 :height 2}
|
|
||||||
:shadow-radius 4
|
|
||||||
:shadow-color (colors/alpha "#435971" 0.124066)))
|
|
||||||
|
|
||||||
(defn icon-view [color]
|
|
||||||
{:background-color color
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:border-radius 20
|
|
||||||
:width 40
|
|
||||||
:height 40})
|
|
||||||
|
|
||||||
(def current-snt-amount
|
|
||||||
{:font-size 28
|
|
||||||
:font-weight "500"})
|
|
||||||
|
|
||||||
(def edit-label
|
|
||||||
{:color colors/blue})
|
|
||||||
|
|
||||||
(def edit-note
|
|
||||||
{:color colors/gray
|
|
||||||
:margin-top 16
|
|
||||||
:margin-horizontal 16
|
|
||||||
:text-align :center})
|
|
||||||
|
|
||||||
(def enabled-note
|
|
||||||
{:border-radius 8
|
|
||||||
:border-width 1
|
|
||||||
:padding 12
|
|
||||||
:border-color colors/gray-lighter
|
|
||||||
:margin-horizontal 16
|
|
||||||
:margin-bottom 16})
|
|
||||||
|
|
||||||
(def learn-more-container
|
|
||||||
{:flex-grow 1
|
|
||||||
:justify-content :flex-start})
|
|
||||||
|
|
||||||
(def learn-more-link
|
|
||||||
{:height 52
|
|
||||||
:padding-horizontal 32
|
|
||||||
:margin-bottom 16
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center})
|
|
||||||
|
|
||||||
(def learn-more-link-text
|
|
||||||
{:color colors/blue})
|
|
||||||
|
|
||||||
(def learn-more-image
|
|
||||||
{:width 120
|
|
||||||
:height 110
|
|
||||||
:margin-top 32
|
|
||||||
:margin-left 32
|
|
||||||
:margin-bottom 16
|
|
||||||
:align-items :flex-start
|
|
||||||
:justify-content :center})
|
|
||||||
|
|
||||||
(def learn-more-title-text
|
|
||||||
(assoc intro-text
|
|
||||||
:text-align :left
|
|
||||||
:margin-left 32))
|
|
||||||
|
|
||||||
(def learn-more-text-container-1
|
|
||||||
{:margin-horizontal 32
|
|
||||||
:margin-top 12
|
|
||||||
:margin-bottom 24})
|
|
||||||
|
|
||||||
(def learn-more-text-container-2
|
|
||||||
{:margin-horizontal 32
|
|
||||||
:margin-top 16
|
|
||||||
:margin-bottom 32})
|
|
||||||
|
|
||||||
(def learn-more-text
|
|
||||||
{:typography :title})
|
|
||||||
|
|
||||||
(def learn-more-section
|
|
||||||
{:border-radius 12
|
|
||||||
:border-width 1
|
|
||||||
:margin-horizontal 32
|
|
||||||
:padding 8
|
|
||||||
:width 238
|
|
||||||
:border-color colors/gray-lighter})
|
|
||||||
|
|
||||||
(def pay-to-chat-bubble
|
|
||||||
{:background-color colors/blue-light
|
|
||||||
:padding-horizontal 12
|
|
||||||
:padding-vertical 8
|
|
||||||
:margin-top 4
|
|
||||||
:border-radius 8})
|
|
||||||
|
|
||||||
(def pay-to-chat-container
|
|
||||||
{:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:flex-direction :row
|
|
||||||
:padding-top 12
|
|
||||||
:padding-bottom 4})
|
|
||||||
|
|
||||||
(def pay-to-chat-text
|
|
||||||
{:color colors/blue})
|
|
||||||
|
|
||||||
(defn payment-status-icon [pending?]
|
|
||||||
{:width 24
|
|
||||||
:height 24
|
|
||||||
:border-radius 12
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:background-color (if pending?
|
|
||||||
colors/black-transparent
|
|
||||||
colors/green)})
|
|
||||||
|
|
||||||
(def payment-status-text
|
|
||||||
{:font-size 15
|
|
||||||
:color colors/gray
|
|
||||||
:margin-left 6
|
|
||||||
:line-height 22})
|
|
||||||
|
|
||||||
(def edit-container
|
|
||||||
{:justify-content :space-between
|
|
||||||
:flex-grow 1})
|
|
||||||
|
|
||||||
(def edit-screen-top-row
|
|
||||||
{:flex-direction :row
|
|
||||||
:margin-vertical 16
|
|
||||||
:margin-horizontal 16
|
|
||||||
:align-items :flex-start
|
|
||||||
:justify-content :space-between})
|
|
||||||
|
|
||||||
(def remove-view
|
|
||||||
{:flex-direction :row
|
|
||||||
:justify-content :flex-start
|
|
||||||
:align-self :flex-start
|
|
||||||
:margin-horizontal 16
|
|
||||||
:margin-top 52})
|
|
||||||
|
|
||||||
(def remove-text
|
|
||||||
{:typography :title
|
|
||||||
:color colors/red
|
|
||||||
:margin-left 16})
|
|
||||||
|
|
||||||
(def remove-note
|
|
||||||
{:margin-horizontal 16
|
|
||||||
:color colors/gray
|
|
||||||
:text-align :center
|
|
||||||
:margin-top 12})
|
|
||||||
|
|
||||||
(def enabled-note-text
|
|
||||||
{:typography :main-medium})
|
|
||||||
|
|
||||||
(def separator-style
|
|
||||||
{:height 1
|
|
||||||
:background-color colors/gray-lighter
|
|
||||||
:align-self :stretch})
|
|
|
@ -1,365 +0,0 @@
|
||||||
(ns status-im.ui.screens.profile.tribute-to-talk.views
|
|
||||||
(:require [re-frame.core :as re-frame]
|
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.react-native.resources :as resources]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[quo.core :as quo]
|
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]
|
|
||||||
[status-im.ui.components.react :as react]
|
|
||||||
[status-im.ui.components.topbar :as topbar]
|
|
||||||
[status-im.ui.components.toolbar :as toolbar]
|
|
||||||
[status-im.ui.screens.profile.tribute-to-talk.styles :as styles])
|
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
|
||||||
|
|
||||||
(defn separator []
|
|
||||||
[react/view {:style styles/separator-style}])
|
|
||||||
|
|
||||||
(defn steps-numbers [editing?]
|
|
||||||
{:intro 1
|
|
||||||
:set-snt-amount (if editing? 1 2)})
|
|
||||||
|
|
||||||
(def step-forward-label
|
|
||||||
{:intro :t/get-started
|
|
||||||
:set-snt-amount :t/continue
|
|
||||||
:finish :t/ok-got-it})
|
|
||||||
|
|
||||||
(defn intro
|
|
||||||
[]
|
|
||||||
[react/scroll-view
|
|
||||||
[react/view {:style styles/intro-container}
|
|
||||||
[react/view {:style {:flex 1
|
|
||||||
:min-height 32}}]
|
|
||||||
|
|
||||||
[react/image {:source (resources/get-image :tribute-to-talk)
|
|
||||||
:style styles/intro-image}]
|
|
||||||
[react/view {:style {:flex 1
|
|
||||||
:min-height 32}}]
|
|
||||||
|
|
||||||
[react/view
|
|
||||||
[react/i18n-text {:style styles/intro-text
|
|
||||||
:key :tribute-to-talk}]
|
|
||||||
[react/i18n-text {:style (assoc styles/description-label :margin-top 12)
|
|
||||||
:key :tribute-to-talk-desc}]
|
|
||||||
[react/view {:style styles/learn-more-link}
|
|
||||||
[react/text {:style styles/learn-more-link-text
|
|
||||||
:on-press #(re-frame/dispatch
|
|
||||||
[:tribute-to-talk.ui/learn-more-pressed])}
|
|
||||||
(i18n/label :t/learn-more)]]]]])
|
|
||||||
|
|
||||||
(defn snt-asset-value
|
|
||||||
[fiat-value]
|
|
||||||
[react/text {:style styles/snt-asset-value}
|
|
||||||
fiat-value])
|
|
||||||
|
|
||||||
(defn snt-amount-label
|
|
||||||
[snt-amount fiat-value]
|
|
||||||
[react/view {:style styles/snt-amount-container}
|
|
||||||
[react/nested-text {:style styles/snt-amount-label
|
|
||||||
:number-of-lines 1
|
|
||||||
:ellipsize-mode :middle}
|
|
||||||
[{:style styles/snt-amount} (or snt-amount "0")]
|
|
||||||
" SNT"]
|
|
||||||
[snt-asset-value fiat-value]])
|
|
||||||
|
|
||||||
(defn number-view
|
|
||||||
[numpad-symbol {:keys [on-press]}]
|
|
||||||
[react/touchable-opacity
|
|
||||||
{:on-press #(on-press numpad-symbol)}
|
|
||||||
[react/view {:style styles/number-container}
|
|
||||||
(if (= numpad-symbol :remove)
|
|
||||||
[icons/icon :main-icons/backspace {:color colors/blue}]
|
|
||||||
[react/text {:style styles/number} numpad-symbol])]])
|
|
||||||
|
|
||||||
(defn number-row
|
|
||||||
[[left middle right] opts]
|
|
||||||
[react/view {:style styles/number-row}
|
|
||||||
[number-view left opts]
|
|
||||||
[react/view {:style styles/vertical-number-separator}]
|
|
||||||
[number-view middle opts]
|
|
||||||
[react/view {:style styles/vertical-number-separator}]
|
|
||||||
[number-view right opts]])
|
|
||||||
|
|
||||||
(defn number-pad
|
|
||||||
[opts]
|
|
||||||
[react/view {:style styles/number-pad}
|
|
||||||
[number-row [1 2 3] opts]
|
|
||||||
[react/view {:style (styles/horizontal-separator 12 24)}]
|
|
||||||
[number-row [4 5 6] opts]
|
|
||||||
[react/view {:style (styles/horizontal-separator 12 24)}]
|
|
||||||
[number-row [7 8 9] opts]
|
|
||||||
[react/view {:style (styles/horizontal-separator 12 24)}]
|
|
||||||
[number-row ["." 0 :remove] opts]])
|
|
||||||
|
|
||||||
(defn set-snt-amount
|
|
||||||
[snt-amount]
|
|
||||||
[react/scroll-view
|
|
||||||
{:content-container-style styles/set-snt-amount-container}
|
|
||||||
[react/view {:style (styles/horizontal-separator 16 32)}]
|
|
||||||
[snt-amount-label snt-amount]
|
|
||||||
[react/view {:style (styles/horizontal-separator 16 40)}]
|
|
||||||
[number-pad {:on-press (fn [numpad-symbol]
|
|
||||||
(re-frame/dispatch
|
|
||||||
[:tribute-to-talk.ui/numpad-key-pressed numpad-symbol]))}]
|
|
||||||
[react/i18n-text {:style (assoc styles/description-label :margin-horizontal 16)
|
|
||||||
:key :tribute-to-talk-set-snt-amount}]])
|
|
||||||
|
|
||||||
(defn finish
|
|
||||||
[snt-amount state]
|
|
||||||
[react/view {:style styles/intro-container}
|
|
||||||
[react/view {:style {:flex 1
|
|
||||||
:min-height 32}}]
|
|
||||||
[react/view {:style {:justify-content :center
|
|
||||||
:align-items :center}}
|
|
||||||
[react/view {:style (styles/finish-circle
|
|
||||||
(case state
|
|
||||||
:completed
|
|
||||||
colors/green-transparent-10
|
|
||||||
:disabled
|
|
||||||
colors/gray-lighter
|
|
||||||
:pending
|
|
||||||
colors/gray-lighter
|
|
||||||
:signing
|
|
||||||
colors/gray-lighter
|
|
||||||
:transaction-failed
|
|
||||||
colors/red-transparent-10)
|
|
||||||
80)}
|
|
||||||
[react/view {:style styles/finish-circle-with-shadow}
|
|
||||||
(if (#{:signing :pending} state)
|
|
||||||
[react/activity-indicator {:animating true
|
|
||||||
:size :large
|
|
||||||
:color colors/gray}]
|
|
||||||
[icons/icon (case state
|
|
||||||
:completed :main-icons/check
|
|
||||||
:disabled :main-icons/cancel
|
|
||||||
:transaction-failed :main-icons/warning)
|
|
||||||
{:width 48 :height 48
|
|
||||||
:color (case state
|
|
||||||
:completed
|
|
||||||
colors/green
|
|
||||||
:disabled
|
|
||||||
colors/gray
|
|
||||||
:pending
|
|
||||||
colors/gray
|
|
||||||
:signing
|
|
||||||
colors/gray
|
|
||||||
:transaction-failed
|
|
||||||
colors/red)}])]]]
|
|
||||||
|
|
||||||
[react/view {:style {:flex 1
|
|
||||||
:min-height 32}}]
|
|
||||||
[react/view {:style {:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:margin-bottom 32}}
|
|
||||||
[react/text {:style styles/finish-label}
|
|
||||||
(i18n/label (case state
|
|
||||||
:completed
|
|
||||||
:t/you-are-all-set
|
|
||||||
:disabled
|
|
||||||
:t/tribute-to-talk-disabled
|
|
||||||
:pending
|
|
||||||
:t/tribute-to-talk-pending
|
|
||||||
:signing
|
|
||||||
:t/tribute-to-talk-signing
|
|
||||||
:transaction-failed
|
|
||||||
:t/transaction-failed))]
|
|
||||||
(case state
|
|
||||||
:completed
|
|
||||||
[react/nested-text {:style (assoc styles/description-label :margin-top 16)}
|
|
||||||
(i18n/label :t/tribute-to-talk-finish-desc)
|
|
||||||
[{:style {:color colors/black
|
|
||||||
:font-weight "600"}} snt-amount]
|
|
||||||
" SNT"]
|
|
||||||
:disabled
|
|
||||||
[react/text {:style (assoc styles/description-label :margin-top 16)}
|
|
||||||
(i18n/label :t/tribute-to-talk-disabled-note)]
|
|
||||||
:pending
|
|
||||||
[react/text {:style (assoc styles/description-label :margin-top 16)}
|
|
||||||
(i18n/label :t/tribute-to-talk-pending-note)]
|
|
||||||
:signing
|
|
||||||
nil
|
|
||||||
:transaction-failed
|
|
||||||
[react/text {:style (assoc styles/description-label :margin-top 16)}
|
|
||||||
(i18n/label :t/tribute-to-talk-transaction-failed-note)])]])
|
|
||||||
|
|
||||||
(defn enabled-note
|
|
||||||
[]
|
|
||||||
[react/view {:style styles/enabled-note}
|
|
||||||
[react/view {:flex-direction :row}
|
|
||||||
[icons/icon :main-icons/info {:color colors/gray}]
|
|
||||||
[react/text {:style (assoc styles/enabled-note-text
|
|
||||||
:margin-left 11)}
|
|
||||||
(i18n/label :t/tribute-to-talk-enabled)]]
|
|
||||||
[react/text {:style (assoc styles/enabled-note-text
|
|
||||||
:margin-left 35)}
|
|
||||||
(i18n/label :t/tribute-to-talk-add-friends)]])
|
|
||||||
|
|
||||||
(defn edit
|
|
||||||
[snt-amount fiat-value]
|
|
||||||
[react/scroll-view {:content-container-style styles/edit-container}
|
|
||||||
[react/view {:style styles/edit-screen-top-row}
|
|
||||||
[react/view {:style {:flex-direction :row
|
|
||||||
:justify-content :flex-start
|
|
||||||
:align-items :flex-start}}
|
|
||||||
[icons/icon :icons/logo {:container-style (styles/icon-view colors/blue)
|
|
||||||
:width 40
|
|
||||||
:height 40}]
|
|
||||||
[react/view {:style {:margin-left 16 :justify-content :flex-start}}
|
|
||||||
[react/view {:style {:justify-content :center
|
|
||||||
:align-items :center}}
|
|
||||||
[react/nested-text {:style styles/current-snt-amount}
|
|
||||||
snt-amount
|
|
||||||
[{:style (assoc styles/current-snt-amount :color colors/gray)}
|
|
||||||
" SNT"]]]
|
|
||||||
[snt-asset-value fiat-value]]]
|
|
||||||
[react/view {:flex 1}]
|
|
||||||
[react/text {:on-press #(re-frame/dispatch
|
|
||||||
[:tribute-to-talk.ui/edit-pressed])
|
|
||||||
:style styles/edit-label}
|
|
||||||
(i18n/label :t/edit)]]
|
|
||||||
[separator]
|
|
||||||
[react/text {:style styles/edit-note}
|
|
||||||
(i18n/label :t/tribute-to-talk-you-require-snt)]
|
|
||||||
|
|
||||||
[react/touchable-highlight {:on-press #(re-frame/dispatch
|
|
||||||
[:tribute-to-talk.ui/remove-pressed])
|
|
||||||
:style styles/remove-view}
|
|
||||||
[react/view {:style {:flex-direction :row}}
|
|
||||||
[react/view {:style (styles/icon-view colors/red-transparent-10)}
|
|
||||||
[icons/icon :main-icons/logout {:color colors/red}]]
|
|
||||||
[react/view {:style {:justify-content :center
|
|
||||||
:align-items :center}}
|
|
||||||
[react/text {:style styles/remove-text}
|
|
||||||
(i18n/label :t/remove)]]]]
|
|
||||||
[react/text {:style styles/remove-note}
|
|
||||||
(i18n/label :t/tribute-to-talk-removing-note)]
|
|
||||||
[react/view {:flex 1
|
|
||||||
:min-height 24}]
|
|
||||||
[enabled-note]])
|
|
||||||
|
|
||||||
(defn pay-to-chat-message
|
|
||||||
[{:keys [snt-amount style public-key tribute-status
|
|
||||||
tribute-label fiat-amount fiat-currency token]}]
|
|
||||||
[react/view {:style style}
|
|
||||||
[react/view {:style {:flex-direction :row
|
|
||||||
:align-items :center}}
|
|
||||||
[react/view {:style {:background-color colors/white
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center}}
|
|
||||||
[icons/tiny-icon :tiny-icons/tribute-to-talk {:color colors/blue}]]
|
|
||||||
[react/text {:style {:color colors/gray
|
|
||||||
:font-size 13
|
|
||||||
:margin-left 4}}
|
|
||||||
(i18n/label :t/tribute-to-talk)]]
|
|
||||||
(when snt-amount
|
|
||||||
[react/view {:style styles/pay-to-chat-bubble}
|
|
||||||
[react/nested-text {:style {:font-size 22}}
|
|
||||||
(str snt-amount)
|
|
||||||
[{:style {:font-size 22 :color colors/gray}} token]]
|
|
||||||
[react/nested-text
|
|
||||||
{:style {:font-size 12}}
|
|
||||||
fiat-amount
|
|
||||||
[{:style {:font-size 12 :color colors/gray}}
|
|
||||||
(str " " fiat-currency)]]
|
|
||||||
(if (or (nil? public-key) (= tribute-status :required))
|
|
||||||
[react/view {:style styles/pay-to-chat-container}
|
|
||||||
[react/text (cond-> {:style styles/pay-to-chat-text}
|
|
||||||
public-key
|
|
||||||
(assoc :on-press
|
|
||||||
#(re-frame/dispatch [:tribute-to-talk.ui/on-pay-to-chat-pressed
|
|
||||||
public-key])))
|
|
||||||
(i18n/label :t/pay-to-chat)]]
|
|
||||||
[react/view {:style styles/pay-to-chat-container}
|
|
||||||
[react/view {:style (styles/payment-status-icon (= tribute-status :pending))}
|
|
||||||
[icons/tiny-icon (if (= tribute-status :pending) :tiny-icons/tiny-pending :tiny-icons/tiny-check)
|
|
||||||
{:color (if (= tribute-status :pending) colors/black colors/white)}]]
|
|
||||||
[react/text {:style styles/payment-status-text} tribute-label]])])])
|
|
||||||
|
|
||||||
(defn learn-more [owner?]
|
|
||||||
[react/view {:flex 1}
|
|
||||||
(when-not owner?
|
|
||||||
[topbar/topbar {:modal? true
|
|
||||||
:title (i18n/label :t/tribute-to-talk)
|
|
||||||
:subtitle (i18n/label :t/learn-more)}])
|
|
||||||
[react/scroll-view {:content-container-style styles/learn-more-container}
|
|
||||||
[react/image {:source (resources/get-image :tribute-to-talk)
|
|
||||||
:style styles/learn-more-image}]
|
|
||||||
[react/text {:style styles/learn-more-title-text}
|
|
||||||
(i18n/label :t/tribute-to-talk)]
|
|
||||||
[react/view {:style styles/learn-more-text-container-1}
|
|
||||||
[react/text {:style styles/learn-more-text}
|
|
||||||
(i18n/label (if owner? :t/tribute-to-talk-learn-more-1
|
|
||||||
:t/tribute-to-talk-paywall-learn-more-1))]]
|
|
||||||
[separator]
|
|
||||||
[pay-to-chat-message {:snt-amount 1000
|
|
||||||
:token " SNT"
|
|
||||||
:fiat-currency "USD"
|
|
||||||
:fiat-amount "5"
|
|
||||||
:style (assoc styles/learn-more-section
|
|
||||||
:align-items :flex-start
|
|
||||||
:margin-top 24)}]
|
|
||||||
[react/view {:style styles/learn-more-text-container-2}
|
|
||||||
[react/text {:style styles/learn-more-text}
|
|
||||||
(i18n/label (if owner? :t/tribute-to-talk-learn-more-2
|
|
||||||
:t/tribute-to-talk-paywall-learn-more-2))]]
|
|
||||||
[react/view {:style (assoc styles/learn-more-section
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :stretch
|
|
||||||
:padding-horizontal 16
|
|
||||||
:padding-vertical 12)}
|
|
||||||
[react/view {:style (styles/icon-view colors/blue-light)}
|
|
||||||
[icons/icon :main-icons/add-contact {:color colors/blue}]]
|
|
||||||
[react/view {:style {:margin-left 16 :justify-content :center}}
|
|
||||||
[react/text {:style (assoc styles/learn-more-text :color colors/blue)}
|
|
||||||
(i18n/label (if owner? :t/add-to-contacts :t/share-profile))]]]
|
|
||||||
[react/view {:style styles/learn-more-text-container-2}
|
|
||||||
[react/text {:style styles/learn-more-text}
|
|
||||||
(i18n/label (if owner? :t/tribute-to-talk-learn-more-3
|
|
||||||
:t/tribute-to-talk-paywall-learn-more-3))]]]])
|
|
||||||
|
|
||||||
(defview tribute-to-talk []
|
|
||||||
(letsubs [{:keys [step snt-amount
|
|
||||||
fiat-value disable-button? state]}
|
|
||||||
[:tribute-to-talk/settings-ui]]
|
|
||||||
[react/keyboard-avoiding-view {:style styles/container}
|
|
||||||
[react/view {:style {:flex 1}}
|
|
||||||
;; [toolbar/toolbar
|
|
||||||
;; nil
|
|
||||||
;; (when-not (= :finish step)
|
|
||||||
;; (toolbar/nav-button
|
|
||||||
;; (actions/back #(re-frame/dispatch
|
|
||||||
;; [:tribute-to-talk.ui/step-back-pressed]))))
|
|
||||||
;; [react/view
|
|
||||||
;; [react/text {:style styles/tribute-to-talk}
|
|
||||||
;; (i18n/label :t/tribute-to-talk)]
|
|
||||||
;; (when-not (#{:edit :learn-more} step)
|
|
||||||
;; [react/text {:style styles/step-n}
|
|
||||||
;; (if (= step :finish)
|
|
||||||
;; (i18n/label (case state
|
|
||||||
;; :completed :t/completed
|
|
||||||
;; :pending :t/pending
|
|
||||||
;; :signing :t/signing
|
|
||||||
;; :transaction-failed :t/transaction-failed
|
|
||||||
;; :disabled :t/disabled))
|
|
||||||
;; (i18n/label :t/step-i-of-n {:step ((steps-numbers editing?) step)
|
|
||||||
;; :number (if editing? 2 3)}))])
|
|
||||||
;; (when (= step :learn-more)
|
|
||||||
;; [react/text {:style styles/step-n}
|
|
||||||
;; (i18n/label :t/learn-more)])]]
|
|
||||||
|
|
||||||
(case step
|
|
||||||
:intro [intro]
|
|
||||||
:set-snt-amount [set-snt-amount snt-amount]
|
|
||||||
:edit [edit snt-amount fiat-value]
|
|
||||||
:learn-more [learn-more step]
|
|
||||||
:finish [finish snt-amount state])
|
|
||||||
|
|
||||||
(when-not (#{:learn-more :edit} step)
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:show-border? true
|
|
||||||
:size :large
|
|
||||||
:center
|
|
||||||
[quo/button {:disabled disable-button?
|
|
||||||
:type :secondary
|
|
||||||
:on-press #(re-frame/dispatch
|
|
||||||
[:tribute-to-talk.ui/step-forward-pressed])}
|
|
||||||
(i18n/label (step-forward-label step))]}])]]))
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns status-im.ui.screens.routing.main
|
(ns status-im.ui.screens.routing.main
|
||||||
(:require-macros [status-im.utils.views :as views])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
|
(:require [status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
|
||||||
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
|
|
||||||
[status-im.ui.screens.wallet.recipient.views :as recipient]
|
[status-im.ui.screens.wallet.recipient.views :as recipient]
|
||||||
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
|
[status-im.ui.screens.qr-scanner.views :as qr-scanner]
|
||||||
[status-im.ui.screens.stickers.views :as stickers]
|
[status-im.ui.screens.stickers.views :as stickers]
|
||||||
|
@ -72,8 +71,6 @@
|
||||||
:component intro-login-stack/intro-stack})
|
:component intro-login-stack/intro-stack})
|
||||||
{:name :stickers-pack-modal
|
{:name :stickers-pack-modal
|
||||||
:component stickers/pack-modal}
|
:component stickers/pack-modal}
|
||||||
{:name :tribute-learn-more
|
|
||||||
:component tr-to-talk/learn-more}
|
|
||||||
{:name :welcome
|
{:name :welcome
|
||||||
:back-handler :noop
|
:back-handler :noop
|
||||||
:component home/welcome}
|
:component home/welcome}
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
[status-im.ui.screens.log-level-settings.views :as log-level-settings]
|
[status-im.ui.screens.log-level-settings.views :as log-level-settings]
|
||||||
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
|
[status-im.ui.screens.fleet-settings.views :as fleet-settings]
|
||||||
[status-im.ui.screens.profile.seed.views :as profile.seed]
|
[status-im.ui.screens.profile.seed.views :as profile.seed]
|
||||||
[status-im.ui.screens.profile.tribute-to-talk.views :as tr-to-talk]
|
|
||||||
[status-im.ui.screens.keycard.pin.views :as keycard.pin]
|
[status-im.ui.screens.keycard.pin.views :as keycard.pin]
|
||||||
[status-im.ui.screens.keycard.settings.views :as keycard.settings]
|
[status-im.ui.screens.keycard.settings.views :as keycard.settings]
|
||||||
[status-im.ui.components.tabbar.styles :as tabbar.styles]
|
[status-im.ui.components.tabbar.styles :as tabbar.styles]
|
||||||
|
@ -117,8 +116,6 @@
|
||||||
:component mobile-network-settings/mobile-network-settings}
|
:component mobile-network-settings/mobile-network-settings}
|
||||||
{:name :backup-seed
|
{:name :backup-seed
|
||||||
:component profile.seed/backup-seed}
|
:component profile.seed/backup-seed}
|
||||||
{:name :tribute-to-talk
|
|
||||||
:component tr-to-talk/tribute-to-talk}
|
|
||||||
{:name :delete-profile
|
{:name :delete-profile
|
||||||
:transition :presentation-ios
|
:transition :presentation-ios
|
||||||
:insets {:bottom true}
|
:insets {:bottom true}
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
(def blank-preview? (enabled? (get-config :BLANK_PREVIEW "1")))
|
(def blank-preview? (enabled? (get-config :BLANK_PREVIEW "1")))
|
||||||
(def group-chat-enabled? (enabled? (get-config :GROUP_CHATS_ENABLED "0")))
|
(def group-chat-enabled? (enabled? (get-config :GROUP_CHATS_ENABLED "0")))
|
||||||
(def tooltip-events? (enabled? (get-config :TOOLTIP_EVENTS "0")))
|
(def tooltip-events? (enabled? (get-config :TOOLTIP_EVENTS "0")))
|
||||||
(def nimbus-enabled? (enabled? (get-config :STATUS_GO_ENABLE_NIMBUS "0")))
|
|
||||||
(def commands-enabled? (enabled? (get-config :COMMANDS_ENABLED "0")))
|
(def commands-enabled? (enabled? (get-config :COMMANDS_ENABLED "0")))
|
||||||
(def keycard-test-menu-enabled? (enabled? (get-config :KEYCARD_TEST_MENU "0")))
|
(def keycard-test-menu-enabled? (enabled? (get-config :KEYCARD_TEST_MENU "0")))
|
||||||
(def qr-test-menu-enabled? (enabled? (get-config :QR_READ_TEST_MENU "0")))
|
(def qr-test-menu-enabled? (enabled? (get-config :QR_READ_TEST_MENU "0")))
|
||||||
|
@ -49,6 +48,7 @@
|
||||||
(def communities-enabled? (enabled? (get-config :COMMUNITIES_ENABLED "0")))
|
(def communities-enabled? (enabled? (get-config :COMMUNITIES_ENABLED "0")))
|
||||||
(def communities-management-enabled? (and (enabled? (get-config :COMMUNITIES_MANAGEMENT_ENABLED "0"))
|
(def communities-management-enabled? (and (enabled? (get-config :COMMUNITIES_MANAGEMENT_ENABLED "0"))
|
||||||
communities-enabled?))
|
communities-enabled?))
|
||||||
|
(def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0")))
|
||||||
|
|
||||||
;; CONFIG VALUES
|
;; CONFIG VALUES
|
||||||
(def log-level
|
(def log-level
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.68.8",
|
"version": "v0.69.0",
|
||||||
"commit-sha1": "d8bccaff1838b674be5fb362c601c8e122f01962",
|
"commit-sha1": "f73fb9c3f640d610ead693d95246b837b5c16990",
|
||||||
"src-sha256": "1487b2y849k535mskd81hzfhz622h588mbcmws0p2djhbcdnpvr4"
|
"src-sha256": "01fgsx8j2wvw58l73575b1rh6fjrrgbqqvpkyhzc4lxw2d6zhqk8"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue