[Fixes: #12550] Backup contacts through waku

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2021-10-25 09:46:33 +01:00
parent 179f1d26ae
commit e125164273
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
23 changed files with 218 additions and 133 deletions

View File

@ -26,7 +26,7 @@
[cofx {:keys [key id]} public] [cofx {:keys [key id]} public]
(fx/merge cofx (fx/merge cofx
{::persistence/chat-initalized! true} {::persistence/chat-initalized! true}
(chat/start-chat key))) (chat/start-chat key nil)))
(fx/defn start-public-chat (fx/defn start-public-chat
{:events [::start-public-chat]} {:events [::start-public-chat]}

View File

@ -78,9 +78,9 @@
(if-not validation-result (if-not validation-result
(if new-contact? (if new-contact?
(fx/merge cofx (fx/merge cofx
(contact/add-contact chat-key nil) (contact/add-contact chat-key nil nil)
(navigation/navigate-to-cofx :contacts-list {})) (navigation/navigate-to-cofx :contacts-list {}))
(chat/start-chat cofx chat-key)) (chat/start-chat cofx chat-key nil))
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (case validation-result :content (case validation-result
:invalid :invalid

View File

@ -0,0 +1,26 @@
(ns status-im.backup.core
(:require [re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.fx :as fx]))
(fx/defn handle-backup-failed
{:events [::backup-failed]}
[{:keys [db]}]
{:db (dissoc db :backup/performing-backup)})
(fx/defn handle-backup-perfomed
{:events [::backup-performed]}
[{:keys [db]}]
{:db (dissoc db :backup/performing-backup)})
(fx/defn handle-perform-backup-pressed
{:events [:multiaccounts.ui/perform-backup-pressed]}
[{:keys [db]}]
{:db (assoc db :backup/performing-backup true)
::json-rpc/call [{:method (json-rpc/call-ext-method "backupData")
:params []
:on-error #(do
(log/error "failed to perfom backup" %)
(re-frame/dispatch [::backup-failed %]))
:on-success #(re-frame/dispatch [::backup-performed %])}]})

View File

@ -4,6 +4,7 @@
[status-im.multiaccounts.model :as multiaccounts.model] [status-im.multiaccounts.model :as multiaccounts.model]
[status-im.chat.models.message-list :as message-list] [status-im.chat.models.message-list :as message-list]
[status-im.data-store.chats :as chats-store] [status-im.data-store.chats :as chats-store]
[status-im.data-store.contacts :as contacts-store]
[status-im.ethereum.json-rpc :as json-rpc] [status-im.ethereum.json-rpc :as json-rpc]
[status-im.i18n.i18n :as i18n] [status-im.i18n.i18n :as i18n]
[quo.design-system.colors :as colors] [quo.design-system.colors :as colors]
@ -254,9 +255,15 @@
(fx/defn handle-one-to-one-chat-created (fx/defn handle-one-to-one-chat-created
{:events [::one-to-one-chat-created]} {:events [::one-to-one-chat-created]}
[{:keys [db]} chat-id response] [{:keys [db]} chat-id response]
(let [chat (chats-store/<-rpc (first (:chats response)))] (let [chat (chats-store/<-rpc (first (:chats response)))
{:db (-> db contact-rpc (first (:contacts response))
contact (when contact-rpc (contacts-store/<-rpc contact-rpc))]
{:db (cond-> db
contact
(assoc-in [:contacts/contacts chat-id] contact)
:always
(assoc-in [:chats chat-id] chat) (assoc-in [:chats chat-id] chat)
:always
(update :chats-home-list conj chat-id)) (update :chats-home-list conj chat-id))
:dispatch [:chat.ui/navigate-to-chat chat-id]})) :dispatch [:chat.ui/navigate-to-chat chat-id]}))
@ -269,11 +276,11 @@
(fx/defn start-chat (fx/defn start-chat
"Start a chat, making sure it exists" "Start a chat, making sure it exists"
{:events [:chat.ui/start-chat]} {:events [:chat.ui/start-chat]}
[{:keys [db] :as cofx} chat-id] [{:keys [db] :as cofx} chat-id ens-name]
;; don't allow to open chat with yourself ;; don't allow to open chat with yourself
(when (not= (multiaccounts.model/current-public-key cofx) chat-id) (when (not= (multiaccounts.model/current-public-key cofx) chat-id)
{::json-rpc/call [{:method "wakuext_createOneToOneChat" {::json-rpc/call [{:method "wakuext_createOneToOneChat"
:params [{:id chat-id}] :params [{:id chat-id :ensName ens-name}]
:on-success #(re-frame/dispatch [::one-to-one-chat-created chat-id %]) :on-success #(re-frame/dispatch [::one-to-one-chat-created chat-id %])
:on-error #(log/error "failed to create one-to-on chat" chat-id %)}]})) :on-error #(log/error "failed to create one-to-on chat" chat-id %)}]}))

View File

@ -45,12 +45,11 @@
(fx/defn block-contact (fx/defn block-contact
{:events [:contact.ui/block-contact-confirmed]} {:events [:contact.ui/block-contact-confirmed]}
[{:keys [db now] :as cofx} public-key] [{:keys [db] :as cofx} public-key]
(let [contact (-> (contact.db/public-key->contact (let [contact (-> (contact.db/public-key->contact
(:contacts/contacts db) (:contacts/contacts db)
public-key) public-key)
(assoc :last-updated now (assoc :blocked true
:blocked true
:added false)) :added false))
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))] from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
(fx/merge cofx (fx/merge cofx
@ -59,20 +58,26 @@
(update :contacts/blocked (fnil conj #{}) public-key) (update :contacts/blocked (fnil conj #{}) public-key)
;; update the contact in contacts list ;; update the contact in contacts list
(assoc-in [:contacts/contacts public-key] contact))} (assoc-in [:contacts/contacts public-key] contact))}
(contacts-store/block contact #(do (re-frame/dispatch [::contact-blocked contact (map chats-store/<-rpc %)]) (contacts-store/block public-key #(do (re-frame/dispatch [::contact-blocked contact (map chats-store/<-rpc %)])
(re-frame/dispatch [:hide-popover]))) (re-frame/dispatch [:hide-popover])))
;; reset navigation to avoid going back to non existing one to one chat ;; reset navigation to avoid going back to non existing one to one chat
(if from-one-to-one-chat? (if from-one-to-one-chat?
(navigation/pop-to-root-tab :chat-stack) (navigation/pop-to-root-tab :chat-stack)
(navigation/navigate-back))))) (navigation/navigate-back)))))
(fx/defn unblock-contact (fx/defn contact-unblocked
{:events [:contact.ui/unblock-contact-pressed ::contact-unblocked]} {:events [::contact-unblocked]}
[{:keys [db now] :as cofx} public-key] [{:keys [db]} contact-id]
(let [contact (-> (get-in db [:contacts/contacts public-key]) (let [contact (-> (get-in db [:contacts/contacts contact-id])
(assoc :last-updated now :blocked false))] (assoc :blocked false))]
(fx/merge cofx
{:db (-> db {:db (-> db
(update :contacts/blocked disj public-key) (update :contacts/blocked disj contact-id)
(assoc-in [:contacts/contacts public-key] contact))} (assoc-in [:contacts/contacts contact-id] contact))}))
(contacts-store/save-contact contact nil))))
(fx/defn unblock-contact
{:events [:contact.ui/unblock-contact-pressed]}
[cofx contact-id]
(contacts-store/unblock
cofx
contact-id
#(re-frame/dispatch [::contact-unblocked contact-id])))

View File

@ -20,12 +20,10 @@
(let [{:keys [public-key ens-name]} new-identity] (let [{:keys [public-key ens-name]} new-identity]
(fx/merge cofx (fx/merge cofx
#(if new-contact? #(if new-contact?
(contact/add-contact % public-key nickname) (contact/add-contact % public-key nickname ens-name)
(chat/start-chat % public-key)) (chat/start-chat % public-key ens-name))
#(when new-contact? #(when new-contact?
(navigation/navigate-back %)) (navigation/navigate-back %)))))
#(when ens-name
(contact/name-verified % public-key ens-name)))))
(fx/defn pinned-messages-pressed (fx/defn pinned-messages-pressed
{:events [:contact.ui/pinned-messages-pressed]} {:events [:contact.ui/pinned-messages-pressed]}

View File

@ -3,11 +3,9 @@
[status-im.contact.db :as contact.db] [status-im.contact.db :as contact.db]
[status-im.data-store.contacts :as contacts-store] [status-im.data-store.contacts :as contacts-store]
[status-im.ethereum.json-rpc :as json-rpc] [status-im.ethereum.json-rpc :as json-rpc]
[status-im.mailserver.core :as mailserver]
[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]
[clojure.string :as string]
[status-im.constants :as constants] [status-im.constants :as constants]
[status-im.contact.block :as contact.block])) [status-im.contact.block :as contact.block]))
@ -54,10 +52,7 @@
(conj nil) (conj nil)
(and blocked (not was-blocked)) (and blocked (not was-blocked))
(conj [::contact.block/contact-blocked contact chats]) (conj [::contact.block/contact-blocked contact chats]))))
(and was-blocked (not blocked))
(conj [::contact.block/contact-unblocked public-key]))))
[[:offload-messages constants/timeline-chat-id]] [[:offload-messages constants/timeline-chat-id]]
contacts)] contacts)]
(merge (merge
@ -71,17 +66,6 @@
(when (> (count events) 1) (when (> (count events) 1)
{:dispatch-n events})))) {:dispatch-n events}))))
(fx/defn upsert-contact
[{:keys [db] :as cofx}
{:keys [public-key] :as contact}]
(fx/merge cofx
{:db (-> db
(update-in [:contacts/contacts public-key] merge contact))}
(fn [cf]
(contacts-store/save-contact cf
(get-in cf [:db :contacts/contacts public-key])
#(re-frame/dispatch [::send-contact-request public-key])))))
(fx/defn send-contact-request (fx/defn send-contact-request
{:events [::send-contact-request]} {:events [::send-contact-request]}
[{:keys [db] :as cofx} public-key] [{:keys [db] :as cofx} public-key]
@ -92,22 +76,17 @@
(fx/defn add-contact (fx/defn add-contact
"Add a contact and set pending to false" "Add a contact and set pending to false"
{:events [:contact.ui/add-to-contact-pressed] {:events [:contact.ui/add-to-contact-pressed]}
:interceptors [(re-frame/inject-cofx :random-id-generator)]} [{:keys [db] :as cofx} public-key nickname ens-name]
[{:keys [db] :as cofx} public-key nickname]
(when (not= (get-in db [:multiaccount :public-key]) public-key) (when (not= (get-in db [:multiaccount :public-key]) public-key)
(let [contact (cond-> (get-in db [:contacts/contacts public-key] (contacts-store/add
(build-contact cofx public-key)) cofx
(and nickname (not (string/blank? nickname))) public-key
(assoc :nickname nickname) nickname
:else ens-name
(assoc :added true))] #(do
(fx/merge cofx (re-frame/dispatch [:sanitize-messages-and-process-response %])
{:db (dissoc db :contacts/new-identity) (re-frame/dispatch [:offload-messages constants/timeline-chat-id])))))
:dispatch-n [[:start-profile-chat public-key]
[:offload-messages constants/timeline-chat-id]]}
(upsert-contact contact)
(mailserver/process-next-messages-request)))))
(fx/defn remove-contact (fx/defn remove-contact
"Remove a contact from current account's contact list" "Remove a contact from current account's contact list"
@ -119,16 +98,6 @@
:on-success #(log/debug "contact removed successfully")}] :on-success #(log/debug "contact removed successfully")}]
:dispatch [:offload-messages constants/timeline-chat-id]}) :dispatch [:offload-messages constants/timeline-chat-id]})
(fx/defn create-contact
"Create entry in contacts"
[{:keys [db] :as cofx} public-key]
(when (not= (get-in db [:multiaccount :public-key]) public-key)
(let [contact (build-contact cofx public-key)]
(log/info "create contact" contact)
(fx/merge cofx
{:db (dissoc db :contacts/new-identity)}
(upsert-contact contact)))))
(fx/defn initialize-contacts [cofx] (fx/defn initialize-contacts [cofx]
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %]))) (contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))
@ -141,29 +110,12 @@
:new-chat-name "")} :new-chat-name "")}
(navigation/navigate-to-cofx :contact-toggle-list nil))) (navigation/navigate-to-cofx :contact-toggle-list nil)))
(fx/defn name-verified
{:events [:contacts/ens-name-verified]}
[{:keys [db now] :as cofx} public-key ens-name]
(let [contact (-> (or (get-in db [:contacts/contacts public-key])
(build-contact cofx public-key))
(assoc :name ens-name
:ens-verified true))]
(fx/merge cofx
{:db (-> db
(update-in [:contacts/contacts public-key] merge contact))
::json-rpc/call [{:method "wakuext_ensVerified"
:params [public-key ens-name]
:on-success #(log/debug "ens name verified successuful")}]})))
(fx/defn update-nickname (fx/defn update-nickname
{:events [:contacts/update-nickname]} {:events [:contacts/update-nickname]}
[{:keys [db] :as cofx} public-key nickname] [{:keys [db] :as cofx} public-key nickname]
(let [contact (-> (build-contact cofx public-key)
(merge (get-in db [:contacts/contacts public-key])))]
(fx/merge cofx (fx/merge cofx
{:db (assoc-in db [:contacts/contacts public-key] (contacts-store/set-nickname
(if (string/blank? nickname) public-key
(dissoc contact :nickname) nickname
(assoc contact :nickname nickname)))} #(re-frame/dispatch [:sanitize-messages-and-process-response %]))
(upsert-contact {:public-key public-key}) (navigation/navigate-back)))
(navigation/navigate-back))))

View File

@ -13,15 +13,6 @@
:lastUpdated :last-updated :lastUpdated :last-updated
:localNickname :nickname})) :localNickname :nickname}))
(defn ->rpc [contact]
(clojure.set/rename-keys contact {:public-key :id
:ens-verified :ensVerified
:ens-verified-at :ensVerifiedAt
:last-ens-clock-value :lastENSClockValue
:ens-verification-retries :ensVerificationRetries
:last-updated :lastUpdated
:nickname :localNickname}))
(fx/defn fetch-contacts-rpc (fx/defn fetch-contacts-rpc
[_ on-success] [_ on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "contacts") {::json-rpc/call [{:method (json-rpc/call-ext-method "contacts")
@ -29,18 +20,37 @@
:on-success #(on-success (map <-rpc %)) :on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch contacts" %)}]}) :on-failure #(log/error "failed to fetch contacts" %)}]})
(fx/defn save-contact (fx/defn add
[_ {:keys [public-key] :as contact} on-success] [_ public-key nickname ens-name on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "saveContact") {::json-rpc/call [{:method (json-rpc/call-ext-method "addContact")
:params [(->rpc contact)] :params [{:id public-key :nickname nickname :ensName ens-name}]
:js-response true
:on-success #(do :on-success #(do
(log/debug "saved contact" public-key "successfuly") (log/info "saved contact" public-key "successfuly")
(when on-success (when on-success
(on-success))) (on-success %)))
:on-failure #(log/error "failed to save contact" public-key %)}]}) :on-failure #(log/error "failed to add contact" public-key %)}]})
(fx/defn block [_ contact on-success] (fx/defn set-nickname
[_ public-key nickname on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "setContactLocalNickname")
:params [{:id public-key :nickname nickname}]
:js-response true
:on-success #(do
(log/debug "set contact nickname" public-key "successfuly" nickname)
(when on-success
(on-success %)))
:on-failure #(log/error "failed to set contact nickname " public-key nickname %)}]})
(fx/defn block [_ contact-id on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "blockContact") {::json-rpc/call [{:method (json-rpc/call-ext-method "blockContact")
:params [(->rpc contact)] :params [contact-id]
:on-success on-success :on-success on-success
:on-failure #(log/error "failed to block contact" % contact)}]}) :on-failure #(log/error "failed to block contact" % contact-id)}]})
(fx/defn unblock [_ contact-id on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "unblockContact")
:params [contact-id]
:on-success on-success
:js-response true
:on-failure #(log/error "failed to unblock contact" % contact-id)}]})

View File

@ -2,21 +2,6 @@
(:require [cljs.test :refer-macros [deftest is testing]] (:require [cljs.test :refer-macros [deftest is testing]]
[status-im.data-store.contacts :as c])) [status-im.data-store.contacts :as c]))
(deftest contact->rpc
(let [contact {:public-key "pk"
:address "address"
:name "name"
:identicon "identicon"
:last-updated 1}
expected-contact {:id "pk"
:address "address"
:name "name"
:identicon "identicon"
:lastUpdated 1}]
(testing "->rpc"
(is (= expected-contact (c/->rpc contact))))))
(deftest contact<-rpc (deftest contact<-rpc
(let [contact {:id "pk" (let [contact {:id "pk"
:address "address" :address "address"

View File

@ -56,6 +56,7 @@
"wakuext_disableInstallation" {} "wakuext_disableInstallation" {}
"wakuext_sendChatMessage" {} "wakuext_sendChatMessage" {}
"wakuext_sendChatMessages" {} "wakuext_sendChatMessages" {}
"wakuext_backupData" {}
"wakuext_confirmJoiningGroup" {} "wakuext_confirmJoiningGroup" {}
"wakuext_addAdminsToGroupChat" {} "wakuext_addAdminsToGroupChat" {}
"wakuext_addMembersToGroupChat" {} "wakuext_addMembersToGroupChat" {}
@ -90,9 +91,12 @@
"wakuext_unmuteChat" {} "wakuext_unmuteChat" {}
"wakuext_contacts" {} "wakuext_contacts" {}
"wakuext_removeContact" {} "wakuext_removeContact" {}
"wakuext_setContactLocalNickname" {}
"wakuext_clearHistory" {} "wakuext_clearHistory" {}
"wakuext_prepareContent" {} "wakuext_prepareContent" {}
"wakuext_blockContact" {} "wakuext_blockContact" {}
"wakuext_unblockContact" {}
"wakuext_addContact" {}
"wakuext_updateMailservers" {} "wakuext_updateMailservers" {}
"wakuext_sendEmojiReaction" {} "wakuext_sendEmojiReaction" {}
"wakuext_sendEmojiReactionRetraction" {} "wakuext_sendEmojiReactionRetraction" {}

View File

@ -7,6 +7,7 @@
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
status-im.utils.logging.core status-im.utils.logging.core
status-im.backup.core
[status-im.wallet.core :as wallet] [status-im.wallet.core :as wallet]
[status-im.keycard.core :as keycard] [status-im.keycard.core :as keycard]
[status-im.utils.dimensions :as dimensions] [status-im.utils.dimensions :as dimensions]

View File

@ -191,6 +191,7 @@
:latest-derived-path 0 :latest-derived-path 0
:signing-phrase signing-phrase :signing-phrase signing-phrase
:send-push-notifications? true :send-push-notifications? true
:backup-enabled? true
:installation-id (random-guid-generator) :installation-id (random-guid-generator)
;; default mailserver (history node) setting ;; default mailserver (history node) setting
:use-mailservers? true :use-mailservers? true

View File

@ -47,6 +47,11 @@
(assoc-in db [:multiaccount setting] setting-value) (assoc-in db [:multiaccount setting] setting-value)
(update db :multiaccount dissoc setting))})) (update db :multiaccount dissoc setting))}))
(fx/defn toggle-backup-enabled
{:events [:multiaccounts.ui/switch-backup-enabled]}
[cofx enabled?]
(multiaccount-update cofx :backup-enabled? enabled? {}))
(fx/defn toggle-opensea-nfts-visibility (fx/defn toggle-opensea-nfts-visibility
{:events [::toggle-opensea-nfts-visiblity]} {:events [::toggle-opensea-nfts-visiblity]}
[cofx visible?] [cofx visible?]

View File

@ -43,7 +43,7 @@
(fx/defn handle-private-chat [{:keys [db] :as cofx} {:keys [chat-id]}] (fx/defn handle-private-chat [{:keys [db] :as cofx} {:keys [chat-id]}]
(if-not (new-chat.db/own-public-key? db chat-id) (if-not (new-chat.db/own-public-key? db chat-id)
(chat/start-chat cofx chat-id) (chat/start-chat cofx chat-id nil)
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}})) :content (i18n/label :t/can-not-add-yourself)}}))

View File

@ -53,7 +53,7 @@
(fx/defn process (fx/defn process
{:events [:signals/signal-received]} {:events [:signals/signal-received]}
[cofx event-str] [{:keys [db] :as cofx} event-str]
;; We only convert to clojure when strictly necessary or we know it ;; We only convert to clojure when strictly necessary or we know it
;; won't impact performance, as it is a fairly costly operation on large-ish ;; won't impact performance, as it is a fairly costly operation on large-ish
;; data structures ;; data structures
@ -62,6 +62,7 @@
type (.-type data)] type (.-type data)]
(case type (case type
"node.login" (status-node-started cofx (js->clj event-js :keywordize-keys true)) "node.login" (status-node-started cofx (js->clj event-js :keywordize-keys true))
"backup.performed" {:db (assoc-in db [:multiaccount :last-backup] (.-lastBackup event-js))}
"envelope.sent" (transport.message/update-envelopes-status cofx (:ids (js->clj event-js :keywordize-keys true)) :sent) "envelope.sent" (transport.message/update-envelopes-status cofx (:ids (js->clj event-js :keywordize-keys true)) :sent)
"envelope.expired" (transport.message/update-envelopes-status cofx (:ids (js->clj event-js :keywordize-keys true)) :not-sent) "envelope.expired" (transport.message/update-envelopes-status cofx (:ids (js->clj event-js :keywordize-keys true)) :not-sent)
"message.delivered" (let [{:keys [chatID messageID]} (js->clj event-js :keywordize-keys true)] "message.delivered" (let [{:keys [chatID messageID]} (js->clj event-js :keywordize-keys true)]

View File

@ -260,6 +260,8 @@
(reg-root-key-sub :bug-report/description-error :bug-report/description-error) (reg-root-key-sub :bug-report/description-error :bug-report/description-error)
(reg-root-key-sub :bug-report/details :bug-report/details) (reg-root-key-sub :bug-report/details :bug-report/details)
(reg-root-key-sub :backup/performing-backup :backup/performing-backup)
(re-frame/reg-sub (re-frame/reg-sub
:communities :communities
:<- [:raw-communities] :<- [:raw-communities]

View File

@ -0,0 +1,52 @@
(ns status-im.ui.screens.backup-settings.view
(:require-macros [status-im.utils.views :as views])
(:require [status-im.ui.components.react :as react]
[quo.design-system.colors :as colors]
[status-im.utils.datetime :as datetime]
[status-im.i18n.i18n :as i18n]
[quo.core :as quo]
[re-frame.core :as re-frame]))
(defn perform-backup! []
(re-frame/dispatch [:multiaccounts.ui/perform-backup-pressed]))
(defn footer [performing-backup?]
[react/touchable-highlight {:on-press (when-not performing-backup?
perform-backup!)
:style {:height 52}}
[react/view
{:style {:justify-content :center
:flex 1
:align-items :center}}
[react/text
{:color colors/blue
:text-align :center}
(if performing-backup?
(i18n/label :t/backing-up)
(i18n/label :t/perform-backup))]]])
(views/defview backup-settings []
(views/letsubs
[{:keys [last-backup backup-enabled?]}
[:multiaccount]
performing-backup? [:backup/performing-backup]]
[:<>
[react/scroll-view
[quo/list-item
{:size :small
:title (i18n/label :t/backup-through-waku)
:accessibility-label :backup-enabled
:container-margin-bottom 8
:on-press
#(re-frame/dispatch
[:multiaccounts.ui/switch-backup-enabled (not backup-enabled?)])
:accessory :switch
:active backup-enabled?}]
[quo/list-item
{:size :small
:title (i18n/label :t/last-backup-performed)
:accessory :text
:subtitle (if (pos? last-backup)
(datetime/time-ago-long (datetime/to-date last-backup))
(i18n/label :t/never))}]]
[footer performing-backup?]]))

View File

@ -95,6 +95,7 @@
[status-im.ui.screens.progress.views :as progress] [status-im.ui.screens.progress.views :as progress]
[status-im.ui.screens.qr-scanner.views :as qr-scanner] [status-im.ui.screens.qr-scanner.views :as qr-scanner]
[status-im.ui.screens.referrals.public-chat :as referrals.public-chat] [status-im.ui.screens.referrals.public-chat :as referrals.public-chat]
[status-im.ui.screens.backup-settings.view :as backup-settings]
[status-im.ui.screens.reset-password.views :as reset-password] [status-im.ui.screens.reset-password.views :as reset-password]
[status-im.ui.screens.rpc-usage-info :as rpc-usage-info] [status-im.ui.screens.rpc-usage-info :as rpc-usage-info]
[status-im.ui.screens.status.new.views :as status.new] [status-im.ui.screens.status.new.views :as status.new]
@ -546,6 +547,9 @@
{:name :mobile-network-settings {:name :mobile-network-settings
:options {:topBar {:title {:text (i18n/label :t/mobile-network-settings)}}} :options {:topBar {:title {:text (i18n/label :t/mobile-network-settings)}}}
:component mobile-network-settings/mobile-network-settings} :component mobile-network-settings/mobile-network-settings}
{:name :backup-settings
:options {:topBar {:title {:text (i18n/label :t/backup-settings)}}}
:component backup-settings/backup-settings}
{:name :backup-seed {:name :backup-seed
;;TODO dynamic navigation ;;TODO dynamic navigation
:options {:topBar {:visible false}} :options {:topBar {:visible false}}

View File

@ -9,6 +9,7 @@
(views/defview sync-settings [] (views/defview sync-settings []
(views/letsubs [{:keys [syncing-on-mobile-network? (views/letsubs [{:keys [syncing-on-mobile-network?
backup-enabled?
default-sync-period default-sync-period
use-mailservers?]} [:multiaccount] use-mailservers?]} [:multiaccount]
current-mailserver-name [:mailserver/current-name]] current-mailserver-name [:mailserver/current-name]]
@ -23,6 +24,15 @@
:accessory-text (if syncing-on-mobile-network? :accessory-text (if syncing-on-mobile-network?
(i18n/label :t/mobile-network-use-mobile) (i18n/label :t/mobile-network-use-mobile)
(i18n/label :t/mobile-network-use-wifi))}] (i18n/label :t/mobile-network-use-wifi))}]
[quo/list-item {:size :small
:title (i18n/label :t/backup-settings)
:accessibility-label :backup-settings-button
:on-press #(re-frame/dispatch [:navigate-to :backup-settings])
:chevron true
:accessory :text
:accessory-text (if backup-enabled?
(i18n/label :t/backup-enabled)
(i18n/label :t/backup-disabled))}]
[quo/list-item {:size :small [quo/list-item {:size :small
:title (i18n/label :t/default-sync-period) :title (i18n/label :t/default-sync-period)
:accessibility-label :default-sync-period-button :accessibility-label :default-sync-period-button

View File

@ -140,6 +140,20 @@
int int
(format-time-ago unit)))) (format-time-ago unit))))
(defn time-ago-long [time]
(let [seconds-ago (seconds-ago time)
unit (first (drop-while #(and (>= seconds-ago (:limit %))
(:limit %))
units))
diff (-> (/ seconds-ago (:in-second unit))
Math/floor
int)
name (label-pluralize diff (:name unit))]
(label :t/datetime-ago-format {:ago (label :t/datetime-ago)
:number diff
:time-intervals name})))
(defn to-date [ms] (defn to-date [ms]
(from-long ms)) (from-long ms))

View File

@ -57,7 +57,7 @@
(log/info "universal-links: handling private chat" chat-id) (log/info "universal-links: handling private chat" chat-id)
(when chat-id (when chat-id
(if-not (new-chat.db/own-public-key? db chat-id) (if-not (new-chat.db/own-public-key? db chat-id)
(chat/start-chat cofx chat-id) (chat/start-chat cofx chat-id nil)
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}}))) :content (i18n/label :t/can-not-add-yourself)}})))

View File

@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>", "_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im", "owner": "status-im",
"repo": "status-go", "repo": "status-go",
"version": "v0.89.20", "version": "v0.90.0",
"commit-sha1": "e940434becc1522eeb26c4ce5f98fc3bc6b273a3", "commit-sha1": "6724cf4c753da412926e931996367a48c798f650",
"src-sha256": "0y0139gbbpyfpsgv6fgrc0jhhkfd3b8ci7qcjjrgxgmdff65krl4" "src-sha256": "013yfkw79rsqrw73cdnhrkrncfma5yikghgvn9s3b6vmfx5kznkr"
} }

View File

@ -1275,6 +1275,13 @@
"keycard-backup-success-body": "Backup card created successfully. You can now use it with your account just like the primary card.", "keycard-backup-success-body": "Backup card created successfully. You can now use it with your account just like the primary card.",
"type-a-message": "Message", "type-a-message": "Message",
"ulc-enabled": "ULC enabled", "ulc-enabled": "ULC enabled",
"backup-enabled": "Enabled",
"backup-disabled": "Disabled",
"backup-settings": "Backup settings",
"backup-through-waku": "Backup through waku",
"perform-backup": "Perform backup",
"backing-up": "Backing up...",
"last-backup-performed": "Last backup performed:",
"unable-to-read-this-code": "Unable to read this code", "unable-to-read-this-code": "Unable to read this code",
"unblock-contact": "Unblock this user", "unblock-contact": "Unblock this user",
"unknown-status-go-error": "Unknown status-go error", "unknown-status-go-error": "Unknown status-go error",
@ -1676,6 +1683,7 @@
"hide": "Hide", "hide": "Hide",
"account-is-used": "The account is being used with Dapps in the browser.", "account-is-used": "The account is being used with Dapps in the browser.",
"normal": "Normal", "normal": "Normal",
"never": "Never",
"fee-options": "Suggested fee options", "fee-options": "Suggested fee options",
"fee-cap": "Fee cap", "fee-cap": "Fee cap",
"tip-cap": "Tip cap", "tip-cap": "Tip cap",