diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 8d8f5b26dc..7642eb05df 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -38,13 +38,13 @@ :builds {:mobile {:target :react-native :output-dir "app" - :init-fn status-im.core/init + :init-fn status-im2.setup.core/init ;; When false, the Shadow-CLJS watcher won't automatically refresh ;; the target files (a.k.a hot reload). When false, you can manually ;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`. :devtools {:autobuild #shadow/env ["SHADOW_AUTOBUILD_ENABLED" :default true :as :bool]} - :dev {:devtools {:after-load status-im.reloader/reload - :build-notify status-im.reloader/build-notify + :dev {:devtools {:after-load status-im2.setup.hot-reload/reload + :build-notify status-im2.setup.hot-reload/build-notify :preloads [re-frisk-remote.preload]} :closure-defines {status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN" diff --git a/src/i18n/i18n.cljs b/src/i18n/i18n.cljs new file mode 100644 index 0000000000..1ca5ef181e --- /dev/null +++ b/src/i18n/i18n.cljs @@ -0,0 +1,66 @@ +(ns i18n.i18n + (:require + ["i18n-js" :as i18n] + [clojure.string :as string] + [status-im.goog.i18n :as goog.i18n])) + +(defn init [default-device-language translations-by-locale] + (set! (.-fallbacks i18n) true) + (set! (.-defaultSeparator i18n) "/") + (set! (.-locale i18n) default-device-language) + (set! (.-translations i18n) translations-by-locale)) + +(defn get-translations [] + (.-translations i18n)) + +(defn set-language [lang] + (set! (.-locale i18n) lang)) + +;;:zh, :zh-hans-xx, :zh-hant-xx have been added until this bug will be fixed https://github.com/fnando/i18n-js/issues/460 + +(def delimeters + "This function is a hack: mobile Safari doesn't support toLocaleString(), so we need to pass + this map to WKWebView to make number formatting work." + (let [n (.toLocaleString ^js (js/Number 1000.1)) + delimiter? (= (count n) 7)] + (if delimiter? + {:delimiter (subs n 1 2) + :separator (subs n 5 6)} + {:delimiter "" + :separator (subs n 4 5)}))) + +(defn label-number [number] + (when number + (let [{:keys [delimiter separator]} delimeters] + (.toNumber i18n + (string/replace number #"," ".") + (clj->js {:precision 10 + :strip_insignificant_zeros true + :delimiter delimiter + :separator separator}))))) + +(def default-option-value "") + +(defn label-options [options] + ;; i18n ignores nil value, leading to misleading messages + (into {} (for [[k v] options] [k (or v default-option-value)]))) + +(defn label-fn + ([path] (label-fn path {})) + ([path options] + (if (exists? (.t i18n)) + (let [options (update options :amount label-number)] + (.t i18n (name path) (clj->js (label-options options)))) + (name path)))) + +(def label (memoize label-fn)) + +(defn label-pluralize [count path & options] + (if (exists? (.t i18n)) + (.p i18n count (name path) (clj->js options)) + (name path))) + +(def locale + (.-locale i18n)) + +(def format-currency goog.i18n/format-currency) diff --git a/src/react_native/background_timer.cljs b/src/react_native/background_timer.cljs new file mode 100644 index 0000000000..a0ea87bf7b --- /dev/null +++ b/src/react_native/background_timer.cljs @@ -0,0 +1,14 @@ +(ns react-native.background-timer + (:require ["react-native-background-timer" :default background-timer])) + +(defn set-timeout [cb ms] + (.setTimeout background-timer cb ms)) + +(defn clear-timeout [id] + (.clearTimeout background-timer id)) + +(defn set-interval [cb ms] + (.setInterval background-timer cb ms)) + +(defn clear-interval [id] + (.clearInterval background-timer id)) diff --git a/src/react_native/config.cljs b/src/react_native/config.cljs new file mode 100644 index 0000000000..c90b23aa48 --- /dev/null +++ b/src/react_native/config.cljs @@ -0,0 +1,8 @@ +(ns react-native.config + (:require ["react-native-config" :default react-native-config])) + +(def config (js->clj react-native-config :keywordize-keys true)) + +(defn get-config + ([k] (get config k)) + ([k not-found] (get config k not-found))) diff --git a/src/react_native/core.cljs b/src/react_native/core.cljs index ba87a43056..c3f71f06b8 100644 --- a/src/react_native/core.cljs +++ b/src/react_native/core.cljs @@ -3,6 +3,8 @@ ["react-native" :as react-native] [react-native.flat-list :as flat-list])) +(def app-state ^js (.-AppState ^js react-native)) + (def view (reagent/adapt-react-class (.-View ^js react-native))) (def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native))) (def image (reagent/adapt-react-class (.-Image ^js react-native))) @@ -28,4 +30,21 @@ {:font-scale (.-fontScale window) :height (.-height window) :scale (.-scale window) - :width (.-width window)})) \ No newline at end of file + :width (.-width window)})) + +(defn hide-splash-screen [] + (.hide ^js (-> react-native .-NativeModules .-SplashScreen))) + +(defn alert [title message buttons options] + (.alert (.-Alert ^js react-native) title message (clj->js buttons) (clj->js options))) + +(def appearance ^js (.-Appearance ^js react-native)) + +(defn get-color-scheme [] + (.getColorScheme appearance)) + +(defn appearance-add-change-listener [handler] + (.addChangeListener appearance handler)) + +(defn get-window [] + (js->clj (.get (.-Dimensions ^js react-native) "window") :keywordize-keys true)) diff --git a/src/react_native/flat_list.cljs b/src/react_native/flat_list.cljs index a9baf00cf5..67a368f08e 100644 --- a/src/react_native/flat_list.cljs +++ b/src/react_native/flat_list.cljs @@ -32,4 +32,4 @@ (dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn))) (defn flat-list [props] - [react-native-flat-list (base-list-props props)]) \ No newline at end of file + [react-native-flat-list (base-list-props props)]) diff --git a/src/react_native/gesture.cljs b/src/react_native/gesture.cljs index eeec80e5b8..00593227de 100644 --- a/src/react_native/gesture.cljs +++ b/src/react_native/gesture.cljs @@ -1,8 +1,9 @@ (ns react-native.gesture - (:require ["react-native-gesture-handler" :refer (GestureDetector Gesture)] + (:require ["react-native-gesture-handler" :refer (GestureDetector Gesture gestureHandlerRootHOC)] [reagent.core :as reagent])) (def gesture-detector (reagent/adapt-react-class GestureDetector)) +(def gesture-handler-root-hoc gestureHandlerRootHOC) (defn gesture-pan [] (.Pan ^js Gesture)) @@ -10,4 +11,4 @@ (defn on-start [^js pan handler] (.onStart pan handler)) -(defn on-end [^js pan handler] (.onEnd pan handler)) \ No newline at end of file +(defn on-end [^js pan handler] (.onEnd pan handler)) diff --git a/src/react_native/hole_view.cljs b/src/react_native/hole_view.cljs index 8ce6bd3d15..eb60711d20 100644 --- a/src/react_native/hole_view.cljs +++ b/src/react_native/hole_view.cljs @@ -2,4 +2,4 @@ (:require [reagent.core :as reagent] ["react-native-hole-view" :refer (RNHoleView)])) -(def hole-view (reagent/adapt-react-class RNHoleView)) \ No newline at end of file +(def hole-view (reagent/adapt-react-class RNHoleView)) diff --git a/src/react_native/languages.cljs b/src/react_native/languages.cljs new file mode 100644 index 0000000000..c291dabdc9 --- /dev/null +++ b/src/react_native/languages.cljs @@ -0,0 +1,8 @@ +(ns react-native.languages + (:require ["react-native-languages" :default react-native-languages])) + +(defn add-change-listener [handler] + (.addEventListener ^js react-native-languages "change" (fn [^js event] (handler (.-language event))))) + +(defn get-lang-keyword [] + (keyword (.-language ^js react-native-languages))) diff --git a/src/react_native/linear_gradient.cljs b/src/react_native/linear_gradient.cljs index 33ae621193..3f95d9b5a3 100644 --- a/src/react_native/linear_gradient.cljs +++ b/src/react_native/linear_gradient.cljs @@ -2,4 +2,4 @@ (:require ["react-native-linear-gradient" :default LinearGradient] [reagent.core :as reagent])) -(def linear-gradient (reagent/adapt-react-class LinearGradient)) \ No newline at end of file +(def linear-gradient (reagent/adapt-react-class LinearGradient)) diff --git a/src/react_native/mail.cljs b/src/react_native/mail.cljs new file mode 100644 index 0000000000..62d1f86e95 --- /dev/null +++ b/src/react_native/mail.cljs @@ -0,0 +1,5 @@ +(ns react-native.mail + (:require ["react-native-mail" :default react-native-mail])) + +(defn mail [opts callback] + (.mail react-native-mail (clj->js opts) callback)) diff --git a/src/react_native/masked_view.cljs b/src/react_native/masked_view.cljs index 765b67559c..56f2bdaa19 100644 --- a/src/react_native/masked_view.cljs +++ b/src/react_native/masked_view.cljs @@ -2,4 +2,4 @@ (:require ["@react-native-community/masked-view" :default MaskedView] [reagent.core :as reagent])) -(def masked-view (reagent/adapt-react-class MaskedView)) \ No newline at end of file +(def masked-view (reagent/adapt-react-class MaskedView)) diff --git a/src/react_native/navigation.cljs b/src/react_native/navigation.cljs new file mode 100644 index 0000000000..7e7f2d81ee --- /dev/null +++ b/src/react_native/navigation.cljs @@ -0,0 +1,58 @@ +(ns react-native.navigation + (:refer-clojure :exclude [pop]) + (:require ["react-native-navigation" :refer (Navigation)])) + +(defn set-default-options [opts] + (.setDefaultOptions ^js Navigation (clj->js opts))) + +(defn register-component [arg1 arg2 arg3] (.registerComponent ^js Navigation arg1 arg2 arg3)) +(defn set-lazy-component-registrator [handler] (.setLazyComponentRegistrator ^js Navigation handler)) + +(defn set-root [root] + (.setRoot ^js Navigation (clj->js root))) + +(defn set-stack-root [stack comp] + (.setStackRoot ^js Navigation stack (clj->js comp))) + +(defn push [arg1 arg2] + (.push ^js Navigation arg1 (clj->js arg2))) + +(defn pop [comp] (.pop ^js Navigation comp)) + +(defn show-modal [arg] + (.showModal ^js Navigation (clj->js arg))) + +(defn dismiss-modal [comp] (.dismissModal ^js Navigation comp)) + +(defn show-overlay [comp] + (.showOverlay Navigation (clj->js comp))) + +(defn dissmiss-overlay [comp] + (.catch (.dismissOverlay Navigation comp) #())) + +(defn reg-app-launched-listener [handler] + (.registerAppLaunchedListener ^js (.events ^js Navigation) handler)) + +(defn reg-button-pressed-listener [handler] + (.registerNavigationButtonPressedListener + (.events Navigation) + (fn [^js evn] + (handler (.-buttonId evn))))) + +(defn reg-modal-dismissed-listener [handler] + (.registerModalDismissedListener ^js (.events ^js Navigation) handler)) + +(defn reg-component-did-appear-listener [handler] + (.registerComponentDidAppearListener + ^js (.events ^js Navigation) + (fn [^js evn] + (handler (keyword (.-componentName evn)))))) + +(defn reg-component-did-disappear-listener [handler] + (.registerComponentDidDisappearListener + ^js (.events ^js Navigation) + (fn [^js evn] + (handler (.-componentName evn))))) + +(defn merge-options [id opts] + (.mergeOptions Navigation id (clj->js opts))) diff --git a/src/react_native/platform.cljs b/src/react_native/platform.cljs index 85f70142a4..a3543ab37c 100644 --- a/src/react_native/platform.cljs +++ b/src/react_native/platform.cljs @@ -6,4 +6,4 @@ (def os (when platform (.-OS ^js platform))) (def android? (= os "android")) -(def ios? (= os "ios")) \ No newline at end of file +(def ios? (= os "ios")) diff --git a/src/react_native/safe_area.cljs b/src/react_native/safe_area.cljs index 706d0cb2ad..5c9309c641 100644 --- a/src/react_native/safe_area.cljs +++ b/src/react_native/safe_area.cljs @@ -1,6 +1,6 @@ (ns react-native.safe-area (:require ["react-native-safe-area-context" :as safe-area-context - :refer (SafeAreaInsetsContext)] + :refer (SafeAreaProvider SafeAreaInsetsContext)] [reagent.core :as reagent])) (def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext))) @@ -10,3 +10,6 @@ (fn [insets] (reagent/as-element [component (js->clj insets :keywordize-keys true)]))]) + +(def safe-area-provider (reagent/adapt-react-class SafeAreaProvider)) +(def safe-area-consumer consumer-raw) diff --git a/src/react_native/shake.cljs b/src/react_native/shake.cljs new file mode 100644 index 0000000000..ef1b9c91a1 --- /dev/null +++ b/src/react_native/shake.cljs @@ -0,0 +1,5 @@ +(ns react-native.shake + (:require ["react-native-shake" :as react-native-shake])) + +(defn add-shake-listener [handler] + (.addEventListener react-native-shake "ShakeEvent" handler)) diff --git a/src/react_native/syntax_highlighter.cljs b/src/react_native/syntax_highlighter.cljs index 84186916e1..ec9a5d2936 100644 --- a/src/react_native/syntax_highlighter.cljs +++ b/src/react_native/syntax_highlighter.cljs @@ -2,4 +2,4 @@ (:require ["react-syntax-highlighter" :default Highlighter] [reagent.core :as reagent])) -(def highlighter (reagent/adapt-react-class Highlighter)) \ No newline at end of file +(def highlighter (reagent/adapt-react-class Highlighter)) diff --git a/src/status_im/activity_center/core_test.cljs b/src/status_im/activity_center/core_test.cljs index b0699d1e96..8f7da7d756 100644 --- a/src/status_im/activity_center/core_test.cljs +++ b/src/status_im/activity_center/core_test.cljs @@ -10,7 +10,7 @@ (defn setup [] (h/register-helper-events) - (rf/dispatch [:init/app-started])) + (rf/dispatch [:setup/app-started])) ;;;; Contact verification diff --git a/src/status_im/add_new/core.cljs b/src/status_im/add_new/core.cljs index a24bd0b610..4e3f3648ed 100644 --- a/src/status_im/add_new/core.cljs +++ b/src/status_im/add_new/core.cljs @@ -11,7 +11,7 @@ [status-im.i18n.i18n :as i18n] [status-im.contact.core :as contact] [status-im.router.core :as router] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.ethereum.stateofus :as stateofus] [status-im.utils.db :as utils.db])) diff --git a/src/status_im/add_new/db.cljs b/src/status_im/add_new/db.cljs index bff095a025..d0fc062a32 100644 --- a/src/status_im/add_new/db.cljs +++ b/src/status_im/add_new/db.cljs @@ -1,6 +1,7 @@ (ns status-im.add-new.db (:require [status-im.ethereum.ens :as ens] - [cljs.spec.alpha :as spec])) + [cljs.spec.alpha :as spec] + [status-im.utils.db :as utils.db])) (defn own-public-key? [{:keys [multiaccount]} public-key] @@ -8,18 +9,19 @@ (defn validate-pub-key [db public-key] (cond - (or (not (spec/valid? :global/public-key public-key)) + (or (not (utils.db/valid-public-key? public-key)) (= public-key ens/default-key)) :invalid (own-public-key? db public-key) :yourself)) -(spec/def ::name :global/not-empty-string) +(spec/def ::name (spec/and string? not-empty)) -(spec/def ::topic (spec/and :global/not-empty-string +(spec/def ::topic (spec/and string? + not-empty (partial re-matches #"[a-z0-9\-]+"))) (defn valid-topic? [topic] (and topic (spec/valid? ::topic topic) - (not (spec/valid? :global/public-key topic)))) \ No newline at end of file + (not (utils.db/valid-public-key? topic)))) \ No newline at end of file diff --git a/src/status_im/bootnodes/core.cljs b/src/status_im/bootnodes/core.cljs index 5d20a3b51a..fc2bbcab00 100644 --- a/src/status_im/bootnodes/core.cljs +++ b/src/status_im/bootnodes/core.cljs @@ -3,7 +3,7 @@ [re-frame.core :as re-frame] [status-im.i18n.i18n :as i18n] [status-im.multiaccounts.update.core :as multiaccounts.update] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx])) (def address-regex #"enode://[a-zA-Z0-9]+:?(.*)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})") diff --git a/src/status_im/browser/core.cljs b/src/status_im/browser/core.cljs index 37e25e50fa..c99f4d799e 100644 --- a/src/status_im/browser/core.cljs +++ b/src/status_im/browser/core.cljs @@ -9,7 +9,7 @@ [status-im.i18n.i18n :as i18n] [status-im.native-module.core :as status] [status-im.ui.components.list-selection :as list-selection] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.http :as http] [status-im.utils.platform :as platform] diff --git a/src/status_im/browser/permissions.cljs b/src/status_im/browser/permissions.cljs index 2d9658b6c3..f83c1c7210 100644 --- a/src/status_im/browser/permissions.cljs +++ b/src/status_im/browser/permissions.cljs @@ -2,7 +2,7 @@ (:require [status-im.constants :as constants] [status-im.ethereum.json-rpc :as json-rpc] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.qr-scanner.core :as qr-scanner] [status-im.utils.fx :as fx])) diff --git a/src/status_im/chat/models.cljs b/src/status_im/chat/models.cljs index 4edf5e4b33..7f588646e4 100644 --- a/src/status_im/chat/models.cljs +++ b/src/status_im/chat/models.cljs @@ -10,8 +10,6 @@ [status-im.i18n.i18n :as i18n] [quo.design-system.colors :as colors] [status-im.constants :as constants] - [status-im.navigation :as navigation] - [status-im.navigation2 :as navigation2] [status-im.utils.clocks :as utils.clocks] [status-im.utils.fx :as fx] [status-im.utils.utils :as utils] @@ -19,7 +17,8 @@ [status-im.add-new.db :as new-public-chat.db] [status-im.chat.models.loading :as loading] [status-im.ui.screens.chat.state :as chat.state] - [clojure.set :as set])) + [clojure.set :as set] + [status-im2.navigation.events :as navigation])) (defn chats [] (:chats (types/json->clj (js/require "./chats.js")))) @@ -270,7 +269,7 @@ {:db (assoc db :current-chat-id chat-id)} (offload-messages chat-id) (preload-chat-data chat-id) - (navigation2/navigate-to-nav2 :chat chat-id nil from-switcher?))) + (navigation/navigate-to-nav2 :chat chat-id nil from-switcher?))) (fx/defn handle-clear-history-response {:events [::history-cleared]} diff --git a/src/status_im/communities/core.cljs b/src/status_im/communities/core.cljs index df064fa249..aed1cbc3ef 100644 --- a/src/status_im/communities/core.cljs +++ b/src/status_im/communities/core.cljs @@ -12,7 +12,7 @@ [status-im.utils.universal-links.core :as universal-links] [status-im.ethereum.json-rpc :as json-rpc] [quo.design-system.colors :as colors] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.handlers :refer [>evt]] [status-im.ui.components.emoji-thumbnail.styles :as emoji-thumbnail-styles] [status-im.notifications-center.core :as notification-center])) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 85a34d09a1..cf7dc9640a 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -195,3 +195,5 @@ (def ^:const sticker-pack-status-installed 1) (def ^:const sticker-pack-status-pending 2) (def ^:const sticker-pack-status-owned 3) + +(def ^:const delete-message-for-me-undo-time-limit-ms 4000) diff --git a/src/status_im/contact/block.cljs b/src/status_im/contact/block.cljs index 49a80ff8b3..ef141c65d8 100644 --- a/src/status_im/contact/block.cljs +++ b/src/status_im/contact/block.cljs @@ -4,7 +4,7 @@ [status-im.contact.db :as contact.db] [status-im.data-store.chats :as chats-store] [status-im.data-store.contacts :as contacts-store] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.types :as types] [status-im.notifications-center.core :as notification-center] [status-im.utils.fx :as fx])) diff --git a/src/status_im/contact/chat.cljs b/src/status_im/contact/chat.cljs index ef40564082..34e9af415d 100644 --- a/src/status_im/contact/chat.cljs +++ b/src/status_im/contact/chat.cljs @@ -1,6 +1,6 @@ (ns status-im.contact.chat (:require [re-frame.core :as re-frame] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.chat.models :as chat] [status-im.contact.core :as contact] diff --git a/src/status_im/contact/core.cljs b/src/status_im/contact/core.cljs index fc3a771890..6a2db9730c 100644 --- a/src/status_im/contact/core.cljs +++ b/src/status_im/contact/core.cljs @@ -3,7 +3,7 @@ [status-im.contact.db :as contact.db] [status-im.data-store.contacts :as contacts-store] [status-im.ethereum.json-rpc :as json-rpc] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.utils.fx :as fx] [taoensso.timbre :as log] diff --git a/src/status_im/core.cljs b/src/status_im/core.cljs deleted file mode 100644 index 8ea1ede79f..0000000000 --- a/src/status_im/core.cljs +++ /dev/null @@ -1,54 +0,0 @@ -(ns status-im.core - (:require ["react-native" :refer (DevSettings LogBox)] - ["react-native-languages" :default react-native-languages] - ["react-native-shake" :as react-native-shake] - [re-frame.core :as re-frame] - [re-frame.interop :as interop] - [reagent.impl.batching :as batching] - status-im.events - [status-im.i18n.i18n :as i18n] - [status-im.native-module.core :as status] - status-im.navigation.core - [status-im.notifications.local :as notifications] - status-im.subs.root - [status-im.ui.components.react :as react] - [status-im.utils.config :as config] - status-im.utils.db - [status-im.utils.error-handler :as error-handler] - [status-im.utils.logging.core :as utils.logs] - [status-im.utils.platform :as platform] - [status-im.utils.snoopy :as snoopy] - [status-im.switcher.animation :as animation] - [status-im.async-storage.core :as async-storage] - [status-im.utils.universal-links.core :as utils.universal-links])) - -(set! interop/next-tick js/setTimeout) -(set! batching/fake-raf #(js/setTimeout % 0)) -(.ignoreAllLogs LogBox) - -(defn init [] - (utils.logs/init-logs config/log-level) - (error-handler/register-exception-handler!) - (when platform/android? - (status/set-soft-input-mode status/adjust-resize)) - (notifications/listen-notifications) - (.addEventListener ^js react/app-state "change" #(re-frame/dispatch [:app-state-change %])) - (.addEventListener react-native-languages "change" (fn [^js event] - (i18n/set-language (.-language event)))) - (.addEventListener react-native-shake "ShakeEvent" #(re-frame/dispatch [:shake-event])) - - (re-frame/dispatch-sync [:init/app-started]) - - (utils.universal-links/initialize) - - ;; TODO(parvesh) - Remove while moving functionality to status-go - (async-storage/get-item :selected-stack-id #(animation/selected-stack-id-loaded %)) - - ;;DEV - (snoopy/subscribe!) - (when (and js/goog.DEBUG platform/ios? DevSettings) - ;;on Android this method doesn't work - (when-let [nm (.-_nativeModule DevSettings)] - ;;there is a bug in RN, so we have to enable it first and then disable - (.setHotLoadingEnabled ^js nm true) - (js/setTimeout #(.setHotLoadingEnabled ^js nm false) 1000)))) diff --git a/src/status_im/ens/core.cljs b/src/status_im/ens/core.cljs index 78888b11ea..5106c60812 100644 --- a/src/status_im/ens/core.cljs +++ b/src/status_im/ens/core.cljs @@ -7,7 +7,7 @@ [status-im.ethereum.ens :as ens] [status-im.ethereum.stateofus :as stateofus] [status-im.multiaccounts.update.core :as multiaccounts.update] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.datetime :as datetime] [status-im.utils.fx :as fx] [status-im.utils.random :as random] diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 79efc40f8e..a860198005 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -5,7 +5,6 @@ [status-im.async-storage.core :as async-storage] status-im.backup.core status-im.bootnodes.core - [status-im.bottom-sheet.core :as bottom-sheet] status-im.browser.core status-im.browser.permissions [status-im.chat.models :as chat] @@ -23,7 +22,6 @@ status-im.fleet.core status-im.http.core [status-im.i18n.i18n :as i18n] - status-im.init.core [status-im.keycard.core :as keycard] status-im.log-level.core status-im.mailserver.constants @@ -34,11 +32,10 @@ status-im.multiaccounts.logout.core status-im.multiaccounts.update.core [status-im.native-module.core :as status] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] status-im.notifications-center.core status-im.activity-center.core status-im.pairing.core - [status-im.popover.core :as popover] status-im.profile.core status-im.search.core status-im.signals.core @@ -49,23 +46,17 @@ status-im.ui.screens.privacy-and-security-settings.events [status-im.utils.dimensions :as dimensions] [status-im.utils.fx :as fx] - status-im.utils.logging.core [status-im.utils.universal-links.core :as universal-links] [status-im.utils.utils :as utils] - [status-im.visibility-status-popover.core :as visibility-status-popover] status-im.visibility-status-updates.core status-im.waku.core status-im.wallet.accounts.core status-im.wallet.choose-recipient.core [status-im.wallet.core :as wallet] status-im.wallet.custom-tokens.core - [status-im.navigation.core :as navigation.core] - [status-im.navigation.state :as navigation.state] - [status-im.signing.core :as signing] status-im.wallet-connect.core status-im.wallet-connect-legacy.core - status-im.navigation2 - status-im.navigation2.core)) + status-im.network.net-info)) (re-frame/reg-fx :dismiss-keyboard @@ -119,56 +110,9 @@ (fx/defn system-theme-mode-changed {:events [:system-theme-mode-changed]} - [{:keys [db] :as cofx} theme] - (let [cur-theme (get-in db [:multiaccount :appearance]) - current-tab (get db :current-tab :chat) - view-id (:view-id db) - screen-params (get-in db [:navigation/screen-params view-id]) - root-id @navigation.state/root-id - key-uid (get-in db [:multiaccounts/login :key-uid]) - keycard-account? (boolean (get-in db [:multiaccounts/multiaccounts - key-uid - :keycard-pairing])) - dispatch-later (cond-> [] - (= view-id :chat) - (conj {:ms 1000 - :dispatch [:chat.ui/navigate-to-chat (:current-chat-id db)]}) - - (and - (= root-id :chat-stack) - (not-any? #(= view-id %) '(:home :empty-tab :wallet :status :my-profile :chat))) - (conj {:ms 1000 - :dispatch [:navigate-to view-id screen-params]}) - - (some #(= view-id %) navigation.core/community-screens) - (conj {:ms 800 :dispatch - [:navigate-to :community - (get-in db [:navigation/screen-params :community])]}) - - (= view-id :community-emoji-thumbnail-picker) - (conj {:ms 900 :dispatch - [:navigate-to :create-community-channel - (get-in db [:navigation/screen-params :create-community-channel])]}))] - (when (and (some? root-id) (or (nil? cur-theme) (zero? cur-theme))) - (navigation.core/dismiss-all-modals) - (fx/merge cofx - (merge - {::multiaccounts/switch-theme (if (= :dark theme) 2 1)} - (when (seq dispatch-later) - {:utils/dispatch-later dispatch-later})) - (when (get-in db [:bottom-sheet/show?]) - (bottom-sheet/hide-bottom-sheet)) - (when (get-in db [:popover/popover]) - (popover/hide-popover)) - (when (get-in db [:visibility-status-popover/popover]) - (visibility-status-popover/hide-visibility-status-popover)) - (when (get-in db [:signing/tx]) - (signing/discard)) - (if (and (= root-id :multiaccounts) keycard-account?) - (navigation/init-root-with-component :multiaccounts-keycard :multiaccounts) - (navigation/init-root root-id)) - (when (= root-id :chat-stack) - (navigation/change-tab current-tab)))))) + [_ theme] + {::multiaccounts/switch-theme (if (= :dark theme) 2 1) + :dispatch [:reload-new-ui]}) (def authentication-options {:reason (i18n/label :t/biometric-auth-reason-login)}) @@ -195,9 +139,7 @@ (>= (- now app-in-background-since) constants/ms-in-bg-for-require-bioauth))] (fx/merge cofx - {:db (-> db - (dissoc :app-in-background-since) - (assoc :app-active-since now))} + {:db (dissoc db :app-in-background-since)} (mailserver/process-next-messages-request) (wallet/restart-wallet-service-after-background app-in-background-since) (universal-links/process-stored-event) @@ -207,10 +149,8 @@ (biometric/authenticate % on-biometric-auth-result authentication-options))))) (fx/defn on-going-in-background - [{:keys [db now] :as cofx}] - {:db (-> db - (dissoc :app-active-since) - (assoc :app-in-background-since now)) + [{:keys [db now]}] + {:db (assoc db :app-in-background-since now) :dispatch-n [[:audio-recorder/on-background] [:audio-message/on-background]]}) (fx/defn app-state-change diff --git a/src/status_im/group_chats/core.cljs b/src/status_im/group_chats/core.cljs index 92c09aa480..3044cb4c92 100644 --- a/src/status_im/group_chats/core.cljs +++ b/src/status_im/group_chats/core.cljs @@ -5,7 +5,7 @@ [re-frame.core :as re-frame] [status-im.chat.models :as models.chat] [status-im.ethereum.json-rpc :as json-rpc] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.constants :as constants] [status-im.i18n.i18n :as i18n] diff --git a/src/status_im/i18n/i18n.cljs b/src/status_im/i18n/i18n.cljs index 29b6672f2f..e9ca9e80f5 100644 --- a/src/status_im/i18n/i18n.cljs +++ b/src/status_im/i18n/i18n.cljs @@ -4,6 +4,8 @@ ["i18n-js" :as i18n] [status-im.i18n.i18n-resources :as i18n-resources] [status-im.goog.i18n :as goog.i18n])) +;;TODO (14/11/22 flexsurfer) this namespace has been moved to the root level, we keep this only for old (status 1.0) code, +;; can be removed with old code later (set! (.-locale i18n) (name i18n-resources/default-device-language)) (set! (.-fallbacks i18n) true) diff --git a/src/status_im/i18n/i18n_resources.cljs b/src/status_im/i18n/i18n_resources.cljs index b72b36332f..f31c2a2be6 100644 --- a/src/status_im/i18n/i18n_resources.cljs +++ b/src/status_im/i18n/i18n_resources.cljs @@ -2,6 +2,8 @@ (:require [clojure.string :as string] ["i18n-js" :as i18n-js] ["react-native-languages" :default react-native-languages])) +;;TODO (14/11/22 flexsurfer) this namespace has been moved to the status-im2 namespace, we keep this only for old (status 1.0) code, +;; can be removed with old code later (def default-device-language (keyword (.-language react-native-languages))) diff --git a/src/status_im/i18n/i18n_test.cljs b/src/status_im/i18n/i18n_test.cljs index 89c60a15bc..e967376e5b 100644 --- a/src/status_im/i18n/i18n_test.cljs +++ b/src/status_im/i18n/i18n_test.cljs @@ -5,6 +5,8 @@ [clojure.set :as set] [cljs.spec.alpha :as spec] [clojure.string :as string])) +;;TODO (14/11/22 flexsurfer) this namespace has been moved to the status-im2 namespace, we keep this only for old (status 1.0) code, +;; can be removed with old code later ;; english as source of truth (def labels (set (keys (js->clj (:en i18n-resources/translations-by-locale) diff --git a/src/status_im/integration_test.cljs b/src/status_im/integration_test.cljs index 22fdd61c5c..d0a81acfaa 100644 --- a/src/status_im/integration_test.cljs +++ b/src/status_im/integration_test.cljs @@ -4,11 +4,12 @@ [clojure.string :as string] [re-frame.core :as rf] status-im.events + status-im2.navigation.core [status-im.chat.models :as chat.models] [status-im.utils.security :as security] [status-im.multiaccounts.logout.core :as logout] [status-im.transport.core :as transport] - status-im.subs.root ;;so integration tests can run independently + status-im2.subs.root ;;so integration tests can run independently [status-im.ethereum.core :as ethereum] [status-im.utils.test :as utils.test] [taoensso.timbre :as log])) @@ -22,7 +23,7 @@ (utils.test/init!) (defn initialize-app! [] - (rf/dispatch [:init/app-started])) + (rf/dispatch [:setup/app-started])) (defn generate-and-derive-addresses! [] (rf/dispatch [:generate-and-derive-addresses])) @@ -71,11 +72,11 @@ (deftest initialize-app-test (log/info "========= initialize-app-test ==================") (rf-test/run-test-async - (rf/dispatch [:init/app-started]) + (rf/dispatch [:setup/app-started]) (rf-test/wait-for ;; use initialize-view because it has the longest avg. time and ;; is dispatched by initialize-multiaccounts (last non-view event) - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (assert-app-initialized)))) (deftest create-account-test @@ -83,7 +84,7 @@ (rf-test/run-test-async (initialize-app!) ; initialize app (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) ; generate 5 new keys (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] ; wait for the keys @@ -101,7 +102,7 @@ (rf-test/run-test-async (initialize-app!) ; initialize app (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) ; generate 5 new keys (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] @@ -126,7 +127,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) ; generate 5 new keys (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] @@ -148,7 +149,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] @@ -185,7 +186,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (rf/dispatch-sync [:init-root :onboarding]) (rf/dispatch-sync [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]) (rf/dispatch-sync [:status-im.multiaccounts.recover.core/enter-phrase-pressed]) @@ -215,7 +216,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] ; wait for the keys @@ -237,7 +238,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] ; wait for the keys @@ -265,7 +266,7 @@ (rf-test/run-test-async (initialize-app!) (rf-test/wait-for - [:status-im.init.core/initialize-view] + [:setup/initialize-view] (generate-and-derive-addresses!) (rf-test/wait-for [:multiaccount-generate-and-derive-addresses-success] ; wait for the keys diff --git a/src/status_im/keycard/backup_key.cljs b/src/status_im/keycard/backup_key.cljs index 1dbafad8ee..e2a9eb63c0 100644 --- a/src/status_im/keycard/backup_key.cljs +++ b/src/status_im/keycard/backup_key.cljs @@ -6,7 +6,7 @@ [status-im.ethereum.mnemonic :as mnemonic] [status-im.keycard.common :as common] [status-im.multiaccounts.recover.core :as multiaccounts.recover] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.signing.core :as signing.core] [taoensso.timbre :as log])) diff --git a/src/status_im/keycard/change_pin.cljs b/src/status_im/keycard/change_pin.cljs index 6a6d10adb6..9121298830 100644 --- a/src/status_im/keycard/change_pin.cljs +++ b/src/status_im/keycard/change_pin.cljs @@ -1,6 +1,6 @@ (ns status-im.keycard.change-pin (:require [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.keycard.onboarding :as onboarding] [status-im.utils.fx :as fx] [taoensso.timbre :as log] diff --git a/src/status_im/keycard/common.cljs b/src/status_im/keycard/common.cljs index fa4e41ad6a..f4a1aa4452 100644 --- a/src/status_im/keycard/common.cljs +++ b/src/status_im/keycard/common.cljs @@ -4,7 +4,7 @@ [status-im.ethereum.core :as ethereum] [status-im.keycard.nfc :as nfc] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.ui.screens.keycard.keycard-interaction :as keycard-sheet] [status-im.utils.fx :as fx] [status-im.utils.keychain.core :as keychain] diff --git a/src/status_im/keycard/core.cljs b/src/status_im/keycard/core.cljs index 0947f37774..3d5adb3c7d 100644 --- a/src/status_im/keycard/core.cljs +++ b/src/status_im/keycard/core.cljs @@ -16,7 +16,7 @@ [status-im.i18n.i18n :as i18n] [status-im.multiaccounts.recover.core :as multiaccounts.recover] [status-im.multiaccounts.update.core :as multiaccounts.update] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.datetime :as utils.datetime] [status-im.utils.fx :as fx] [taoensso.timbre :as log])) diff --git a/src/status_im/keycard/delete_key.cljs b/src/status_im/keycard/delete_key.cljs index 5cc4789395..39b204c9cd 100644 --- a/src/status_im/keycard/delete_key.cljs +++ b/src/status_im/keycard/delete_key.cljs @@ -1,5 +1,5 @@ (ns status-im.keycard.delete-key - (:require [status-im.navigation :as navigation] + (:require [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.keycard.common :as common])) diff --git a/src/status_im/keycard/login.cljs b/src/status_im/keycard/login.cljs index 1cd585d871..34d4d3dfed 100644 --- a/src/status_im/keycard/login.cljs +++ b/src/status_im/keycard/login.cljs @@ -1,6 +1,6 @@ (ns status-im.keycard.login (:require [status-im.ethereum.core :as ethereum] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.types :as types] [taoensso.timbre :as log] diff --git a/src/status_im/keycard/mnemonic.cljs b/src/status_im/keycard/mnemonic.cljs index 077070d84b..0ddb291beb 100644 --- a/src/status_im/keycard/mnemonic.cljs +++ b/src/status_im/keycard/mnemonic.cljs @@ -1,5 +1,5 @@ (ns status-im.keycard.mnemonic - (:require [status-im.navigation :as navigation] + (:require [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [taoensso.timbre :as log] [status-im.keycard.common :as common] diff --git a/src/status_im/keycard/onboarding.cljs b/src/status_im/keycard/onboarding.cljs index e138f0f219..64cb7d50fd 100644 --- a/src/status_im/keycard/onboarding.cljs +++ b/src/status_im/keycard/onboarding.cljs @@ -2,7 +2,7 @@ (:require [clojure.string :as string] [re-frame.core :as re-frame] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.utils :as utils] [status-im.keycard.common :as common] diff --git a/src/status_im/keycard/recovery.cljs b/src/status_im/keycard/recovery.cljs index 331d81dbf9..3aee428e52 100644 --- a/src/status_im/keycard/recovery.cljs +++ b/src/status_im/keycard/recovery.cljs @@ -1,5 +1,5 @@ (ns status-im.keycard.recovery - (:require [status-im.navigation :as navigation] + (:require [status-im2.navigation.events :as navigation] [status-im.utils.datetime :as utils.datetime] [status-im.multiaccounts.create.core :as multiaccounts.create] [status-im.multiaccounts.model :as multiaccounts.model] diff --git a/src/status_im/keycard/unpair.cljs b/src/status_im/keycard/unpair.cljs index 34aa75aa80..7e9cdb51a5 100644 --- a/src/status_im/keycard/unpair.cljs +++ b/src/status_im/keycard/unpair.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :as re-frame] [status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [taoensso.timbre :as log] [status-im.keycard.common :as common] diff --git a/src/status_im/mailserver/core.cljs b/src/status_im/mailserver/core.cljs index e2d59cd8ef..8673f965fe 100644 --- a/src/status_im/mailserver/core.cljs +++ b/src/status_im/mailserver/core.cljs @@ -7,7 +7,7 @@ [status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.node.core :as node] [status-im.utils.mobile-sync :as mobile-network-utils] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [taoensso.timbre :as log])) diff --git a/src/status_im/mobile_sync_settings/core.cljs b/src/status_im/mobile_sync_settings/core.cljs index 0b1b7db842..ef2daffb2c 100644 --- a/src/status_im/mobile_sync_settings/core.cljs +++ b/src/status_im/mobile_sync_settings/core.cljs @@ -5,7 +5,7 @@ [status-im.wallet.core :as wallet] [status-im.bottom-sheet.core :as bottom-sheet] [status-im.multiaccounts.model :as multiaccounts.model] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.mailserver.core :as mailserver] [status-im.utils.mobile-sync :as utils] [taoensso.timbre :as log])) diff --git a/src/status_im/multiaccounts/core.cljs b/src/status_im/multiaccounts/core.cljs index a0254c3677..b28e4948d3 100644 --- a/src/status_im/multiaccounts/core.cljs +++ b/src/status_im/multiaccounts/core.cljs @@ -8,12 +8,12 @@ [status-im.utils.fx :as fx] [status-im.utils.gfycat.core :as gfycat] [status-im.utils.identicon :as identicon] - [status-im.utils.theme :as utils.theme] [status-im.theme.core :as theme] [status-im.utils.utils :as utils] [quo.platform :as platform] [taoensso.timbre :as log] - [clojure.string :as string])) + [clojure.string :as string] + [status-im2.common.theme.core :as utils.theme])) ;; validate that the given mnemonic was generated from Status Dictionary (re-frame/reg-fx @@ -164,7 +164,7 @@ (re-frame/reg-fx ::switch-theme (fn [theme-id] - (let [theme (if (or (= 2 theme-id) (and (= 0 theme-id) (utils.theme/is-dark-mode))) + (let [theme (if (or (= 2 theme-id) (and (= 0 theme-id) (utils.theme/dark-mode?))) :dark :light)] (theme/change-theme theme)))) diff --git a/src/status_im/multiaccounts/db.cljs b/src/status_im/multiaccounts/db.cljs index 9cdf5b5626..7af08de910 100644 --- a/src/status_im/multiaccounts/db.cljs +++ b/src/status_im/multiaccounts/db.cljs @@ -5,4 +5,4 @@ (defn valid-length? [password] (>= (count password) const/min-password-length)) -(spec/def ::password (spec/and :global/not-empty-string valid-length?)) +(spec/def ::password (spec/and string? not-empty valid-length?)) diff --git a/src/status_im/multiaccounts/key_storage/core.cljs b/src/status_im/multiaccounts/key_storage/core.cljs index cd4fefa0b3..a32cdaf3e9 100644 --- a/src/status_im/multiaccounts/key_storage/core.cljs +++ b/src/status_im/multiaccounts/key_storage/core.cljs @@ -8,7 +8,7 @@ [status-im.multiaccounts.model :as multiaccounts.model] [status-im.multiaccounts.logout.core :as multiaccounts.logout] [status-im.native-module.core :as native-module] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.popover.core :as popover] [status-im.utils.fx :as fx] [status-im.utils.security :as security] diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index 9fc05cb6be..c0779ae734 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -20,7 +20,7 @@ [status-im.mobile-sync-settings.core :as mobile-network] [status-im.utils.fx :as fx] [status-im.utils.keychain.core :as keychain] - [status-im.utils.logging.core :as logging] + [status-im2.setup.log :as logging] [status-im.utils.security :as security] [status-im.utils.types :as types] [status-im.utils.utils :as utils] @@ -33,7 +33,7 @@ [status-im.utils.mobile-sync :as utils.mobile-sync] [status-im.async-storage.core :as async-storage] [status-im.notifications-center.core :as notifications-center] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.signing.eip1559 :as eip1559] [status-im.data-store.chats :as data-store.chats] [status-im.data-store.visibility-status-updates :as visibility-status-updates-store] diff --git a/src/status_im/multiaccounts/logout/core.cljs b/src/status_im/multiaccounts/logout/core.cljs index 81bab21553..182d60aa2b 100644 --- a/src/status_im/multiaccounts/logout/core.cljs +++ b/src/status_im/multiaccounts/logout/core.cljs @@ -1,13 +1,13 @@ (ns status-im.multiaccounts.logout.core (:require [re-frame.core :as re-frame] [status-im.i18n.i18n :as i18n] - [status-im.init.core :as init] [status-im.native-module.core :as status] [status-im.utils.fx :as fx] [status-im.multiaccounts.core :as multiaccounts] [status-im.utils.keychain.core :as keychain] [status-im.notifications.core :as notifications] - [status-im.wallet.core :as wallet])) + [status-im.wallet.core :as wallet] + [status-im2.setup.events :as init])) (fx/defn logout-method {:events [::logout-method]} diff --git a/src/status_im/multiaccounts/recover/core.cljs b/src/status_im/multiaccounts/recover/core.cljs index a28d59cbc8..bf88de6bee 100644 --- a/src/status_im/multiaccounts/recover/core.cljs +++ b/src/status_im/multiaccounts/recover/core.cljs @@ -10,7 +10,7 @@ [status-im.multiaccounts.create.core :as multiaccounts.create] [status-im.native-module.core :as status] [status-im.popover.core :as popover] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.security :as security] [status-im.utils.types :as types] diff --git a/src/status_im/navigation/core.cljs b/src/status_im/navigation/core.cljs deleted file mode 100644 index d11343d9e7..0000000000 --- a/src/status_im/navigation/core.cljs +++ /dev/null @@ -1,444 +0,0 @@ -(ns status-im.navigation.core - (:require - ["react-native" :as rn] - ["react-native-gesture-handler" :refer (gestureHandlerRootHOC)] - ["react-native-navigation" :refer (Navigation)] - [clojure.set :as clojure.set] - [quo.components.text-input :as quo.text-input] - [quo.design-system.colors :as quo.colors] - [re-frame.core :as re-frame] - [status-im.multiaccounts.login.core :as login-core] - [status-im.navigation.roots :as roots] - [status-im.navigation.state :as state] - [status-im.ui.components.icons.icons :as icons] - [status-im.ui.components.react :as react] - [status-im.ui.screens.views :as views] - [status-im.utils.fx :as fx] - [status-im.utils.platform :as platform] - [taoensso.encore :as enc] - [taoensso.timbre :as log])) - -(def debug? ^boolean js/goog.DEBUG) - -(def splash-screen (-> rn .-NativeModules .-SplashScreen)) - -(defonce set-navigation-default-options - (.setDefaultOptions Navigation (clj->js {:layout {:orientation "portrait"}}))) - -;; REGISTER COMPONENT (LAZY) -(defn reg-comp [key] - (log/debug "reg-comp" key) - (if-let [comp (get views/components (keyword key))] - (.registerComponent Navigation key (fn [] (views/component comp))) - (let [screen (views/screen key)] - (.registerComponent Navigation key (fn [] (gestureHandlerRootHOC screen)) (fn [] screen))))) - -(defonce rset-lazy-reg - (.setLazyComponentRegistrator Navigation reg-comp)) - -(defn dismiss-all-modals [] - (log/debug "dissmiss-all-modals") - (when @state/curr-modal - (reset! state/curr-modal false) - (reset! state/dissmissing true) - (doseq [modal @state/modals] - (.dismissModal Navigation (name modal))) - (reset! state/modals []))) - -;; PUSH SCREEN -(defn navigate [comp] - (log/debug "NAVIGATE" comp) - (let [{:keys [options]} (get views/screens comp)] - (.push Navigation - (name @state/root-comp-id) - (clj->js {:component {:id comp - :name comp - :options (merge options - (roots/status-bar-options) - (roots/merge-top-bar (roots/topbar-options) options))}})) - ;;if we push the screen from modal, we want to dismiss all modals - (dismiss-all-modals))) - -;; OPEN MODAL -(defn update-modal-topbar-options [options] - (log/debug "update-modal-topbar-options" options) - (merge options - (roots/merge-top-bar {:elevation 0 - :noBorder true - :title {:color quo.colors/black} - :background {:color quo.colors/white} - :leftButtonColor quo.colors/black - :leftButtons {:id "dismiss-modal" - :icon (icons/icon-source :main-icons/close)}} - options))) - -(defn open-modal [comp] - (log/debug "open-modal" comp) - (let [{:keys [options]} (get views/screens comp)] - (if @state/dissmissing - (reset! state/dissmissing comp) - (do - (reset! state/curr-modal true) - (swap! state/modals conj comp) - (.showModal Navigation - (clj->js {:stack {:children - [{:component - {:name comp - :id comp - :options (update-modal-topbar-options - (merge (roots/status-bar-options) - (roots/default-root) - options))}}]}})))))) - -(re-frame/reg-fx :open-modal-fx open-modal) - -;; DISSMISS MODAL -(defn dissmissModal [] - (log/debug "dissmissModal") - (reset! state/dissmissing true) - (.dismissModal Navigation (name (last @state/modals)))) - -(defonce register-nav-button-reg - (.registerNavigationButtonPressedListener - (.events Navigation) - (fn [^js evn] - (let [id (.-buttonId evn)] - (if (= "dismiss-modal" id) - (do - (when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])] - (re-frame/dispatch event)) - (dissmissModal)) - (when-let [handler (get-in views/screens [(keyword id) :right-handler])] - (handler))))))) - -(defn set-view-id [view-id] - (log/debug "set-view-id" view-id) - (when-let [{:keys [on-focus]} (get views/screens view-id)] - (re-frame/dispatch [:set-view-id view-id]) - (re-frame/dispatch [:screens/on-will-focus view-id]) - (when on-focus - (re-frame/dispatch on-focus)))) - -(defonce register-modal-reg - (.registerModalDismissedListener - (.events Navigation) - (fn [_] - (if (> (count @state/modals) 1) - (let [new-modals (butlast @state/modals)] - (reset! state/modals (vec new-modals)) - (set-view-id (last new-modals))) - (do - (reset! state/modals []) - (reset! state/curr-modal false) - (set-view-id @state/pushed-screen-id))) - - (let [comp @state/dissmissing] - (reset! state/dissmissing false) - (when (keyword? comp) - (open-modal comp)))))) - -;; SCREEN DID APPEAR -(defonce screen-appear-reg - (.registerComponentDidAppearListener - (.events Navigation) - (fn [^js evn] - (let [view-id (keyword (.-componentName evn))] - (log/debug "screen-appear-reg" view-id) - (when (get views/screens view-id) - (when (and (not= view-id :bottom-sheet) - (not= view-id :popover) - (not= view-id :visibility-status-popover)) - (set-view-id view-id) - (when-not @state/curr-modal - (reset! state/pushed-screen-id view-id)))))))) - -;; SCREEN DID DISAPPEAR -(defonce screen-disappear-reg - (.registerComponentDidDisappearListener - (.events Navigation) - (fn [^js evn] - (let [view-id (keyword (.-componentName evn))] - (when-not (#{"popover" "bottom-sheet" "signing-sheet" "visibility-status-popover" "wallet-connect-sheet" "wallet-connect-success-sheet" "wallet-connect-app-management-sheet"} - (.-componentName evn)) - (re-frame/dispatch [::view-disappeared view-id]) - (doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs] - (.setNativeProps ^js ref (clj->js {:text value}))) - (doseq [[^js text-input default-value] @react/text-input-refs] - (.setNativeProps text-input (clj->js {:text default-value})))))))) - -;; SET ROOT -(re-frame/reg-fx - :init-root-fx - (fn [new-root-id] - (log/debug :init-root-fx new-root-id) - (reset! state/root-comp-id new-root-id) - (reset! state/root-id @state/root-comp-id) - (.setRoot Navigation (clj->js (get (roots/roots) new-root-id))))) - -(re-frame/reg-fx - :init-root-with-component-fx - (fn [[new-root-id new-root-comp-id]] - (log/debug :init-root-with-component-fx new-root-id new-root-comp-id) - (reset! state/root-comp-id new-root-comp-id) - (reset! state/root-id @state/root-comp-id) - (.setRoot Navigation (clj->js (get (roots/roots) new-root-id))))) - -(fx/defn set-multiaccount-root - {:events [::set-multiaccount-root]} - [{:keys [db]}] - (log/debug :set-multiaccounts-root) - (let [key-uid (get-in db [:multiaccounts/login :key-uid]) - keycard-account? (boolean (get-in db [:multiaccounts/multiaccounts - key-uid - :keycard-pairing]))] - {:init-root-fx (if keycard-account? :multiaccounts-keycard :multiaccounts)})) - -(defonce rset-app-launched - (.registerAppLaunchedListener (.events Navigation) - (fn [] - (reset! state/curr-modal false) - (reset! state/dissmissing false) - (if (or (= @state/root-id :multiaccounts) - (= @state/root-id :multiaccounts-keycard)) - (re-frame/dispatch-sync [::set-multiaccount-root]) - (when @state/root-id - (reset! state/root-comp-id @state/root-id) - (.setRoot Navigation (clj->js (get (roots/roots) @state/root-id))) - (re-frame/dispatch [::login-core/check-last-chat]))) - (.hide ^js splash-screen)))) - -(defn get-screen-component [comp] - (log/debug :get-screen-component comp) - (let [{:keys [options]} (get views/screens comp)] - {:component {:id comp - :name comp - :options (merge options - (roots/status-bar-options) - (roots/merge-top-bar (roots/topbar-options) options))}})) - -;; SET STACK ROOT -(re-frame/reg-fx - :set-stack-root-fx - (fn [[stack comp]] - (log/debug :set-stack-root-fx stack comp) - (.setStackRoot Navigation - (name stack) - (clj->js (if (vector? comp) - (mapv get-screen-component comp) - (get-screen-component comp)))))) - -;; BOTTOM TABS -(def tab-root-ids {0 :chat-stack - 1 :browser-stack - 2 :wallet-stack - 3 :status-stack - 4 :profile-stack}) - -(def tab-key-idx {:chat 0 - :browser 1 - :wallet 2 - :status 3 - :profile 4}) - -(re-frame/reg-fx - :change-tab-fx - (fn [tab] - (log/debug :change-tab-fx) - (reset! state/root-comp-id (get tab-root-ids (get tab-key-idx tab))) - (.mergeOptions Navigation "tabs-stack" (clj->js {:bottomTabs {:currentTabIndex (get tab-key-idx tab)}})) - ;;when we change tab we want to dismiss all modals - (dismiss-all-modals))) - -;issue on ios https://github.com/wix/react-native-navigation/issues/7146 -(re-frame/reg-fx - :change-tab-count-fx - (fn [[tab cnt]] - (log/debug :change-tab-count-fx tab cnt) - (.mergeOptions Navigation - (name (get tab-root-ids (get tab-key-idx tab))) - (clj->js {:bottomTab (cond - (or (pos? cnt) (pos? (:other cnt))) - (if (and (= :chat tab) platform/ios?) - {:dotIndicator {:visible true}} - {:badge (str (or (:other cnt) cnt)) :dotIndicator {:visible false}}) - (pos? (:public cnt)) - (if platform/ios? - {:dotIndicator {:visible true}} - {:badge nil :dotIndicator {:visible true}}) - :else - (if (and (= :chat tab) platform/ios?) - {:dotIndicator {:visible false}} - {:dotIndicator {:visible false} :badge ""}))})))) - -(re-frame/reg-fx - :pop-to-root-tab-fx - (fn [comp] - (log/debug :pop-to-root-tab-fx comp) - (dismiss-all-modals) - (.popToRoot Navigation (name comp)))) - -(defonce register-bottom-tab-reg - (.registerBottomTabSelectedListener - (.events Navigation) - (fn [^js evn] - (let [selected-tab-index (.-selectedTabIndex evn) - comp (get tab-root-ids selected-tab-index) - tab-key (get (clojure.set/map-invert tab-key-idx) selected-tab-index)] - (re-frame/dispatch [:set :current-tab tab-key]) - (when (= @state/root-comp-id comp) - (when (= :chat tab-key) - (re-frame/dispatch [:close-chat])) - (when platform/android? - (.popToRoot Navigation (name comp)))) - (reset! state/root-comp-id comp))))) - -;; OVERLAY (Popover and bottom sheets) -(defn dissmiss-overlay [comp] - (.catch (.dismissOverlay Navigation comp) #())) - -(defn show-overlay [comp] - (dissmiss-overlay comp) - (.showOverlay Navigation - (clj->js - {:component {:name comp - :id comp - :options (merge (cond-> (roots/status-bar-options) - (and platform/android? (not (quo.colors/dark?))) - (assoc-in [:statusBar :backgroundColor] "#99999A")) - {:layout {:componentBackgroundColor (if platform/android? - (:backdrop @quo.colors/theme) - "transparent")} - :overlay {:interceptTouchOutside true}})}}))) - -;; POPOVER -(defonce popover-reg - (.registerComponent Navigation - "popover" - (fn [] (gestureHandlerRootHOC views/popover-comp)) - (fn [] views/popover-comp))) - -(re-frame/reg-fx :show-popover (fn [] (show-overlay "popover"))) -(re-frame/reg-fx :hide-popover (fn [] (dissmiss-overlay "popover"))) - -;; VISIBILITY STATUS POPOVER -(defonce visibility-status-popover-reg - (.registerComponent Navigation - "visibility-status-popover" - (fn [] (gestureHandlerRootHOC views/visibility-status-popover-comp)) - (fn [] views/visibility-status-popover-comp))) - -(re-frame/reg-fx :show-visibility-status-popover - (fn [] (show-overlay "visibility-status-popover"))) -(re-frame/reg-fx :hide-visibility-status-popover - (fn [] (dissmiss-overlay "visibility-status-popover"))) - -;; BOTTOM SHEETS -(defonce bottom-sheet-reg - (.registerComponent Navigation - "bottom-sheet" - (fn [] (gestureHandlerRootHOC views/sheet-comp)) - (fn [] views/sheet-comp))) - -(re-frame/reg-fx :show-bottom-sheet (fn [] (show-overlay "bottom-sheet"))) -(re-frame/reg-fx :hide-bottom-sheet (fn [] (dissmiss-overlay "bottom-sheet"))) - -;; WALLET CONNECT - -(defonce wallet-connect-sheet-reg - (.registerComponent Navigation - "wallet-connect-sheet" - (fn [] (gestureHandlerRootHOC views/wallet-connect-comp)) - (fn [] views/wallet-connect-comp))) - -(defonce wallet-connect-success-sheet-reg - (.registerComponent Navigation - "wallet-connect-success-sheet" - (fn [] (gestureHandlerRootHOC views/wallet-connect-success-comp)) - (fn [] views/wallet-connect-success-comp))) - -(defonce wallet-connect-app-management-sheet-reg - (.registerComponent Navigation - "wallet-connect-app-management-sheet" - (fn [] (gestureHandlerRootHOC views/wallet-connect-app-management-comp)) - (fn [] views/wallet-connect-app-management-comp))) - -(re-frame/reg-fx :show-wallet-connect-sheet (fn [] (show-overlay "wallet-connect-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-sheet (fn [] (dissmiss-overlay "wallet-connect-sheet"))) -(re-frame/reg-fx :show-wallet-connect-success-sheet (fn [] (show-overlay "wallet-connect-success-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-success-sheet (fn [] (dissmiss-overlay "wallet-connect-success-sheet"))) -(re-frame/reg-fx :show-wallet-connect-app-management-sheet (fn [] (show-overlay "wallet-connect-app-management-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-app-management-sheet (fn [] (dissmiss-overlay "wallet-connect-app-management-sheet"))) - -;; SIGNING - -(defonce signing-sheet-reg - (.registerComponent Navigation - "signing-sheet" - (fn [] (gestureHandlerRootHOC views/signing-comp)) - (fn [] views/signing-comp))) - -(re-frame/reg-fx :show-signing-sheet (fn [] (show-overlay "signing-sheet"))) -(re-frame/reg-fx :hide-signing-sheet (fn [] (dissmiss-overlay "signing-sheet"))) - -;; Select account -;; TODO why is this not a regular bottom sheet ? - -(defonce select-acc-sheet-reg - (.registerComponent Navigation - "select-acc-sheet" - (fn [] (gestureHandlerRootHOC views/select-acc-comp)) - (fn [] views/select-acc-comp))) - -(re-frame/reg-fx :show-select-acc-sheet (fn [] (show-overlay "select-acc-sheet"))) -(re-frame/reg-fx :hide-select-acc-sheet (fn [] (dissmiss-overlay "select-acc-sheet"))) - -;; NAVIGATION - -(re-frame/reg-fx - :navigate-to-fx - (fn [key] - (log/debug :navigate-to-fx key) - (navigate key))) - -(re-frame/reg-fx - :navigate-back-fx - (fn [] - (log/debug :navigate-back-fx) - (if @state/curr-modal - (dissmissModal) - (.pop Navigation (name @state/root-comp-id))))) - -(re-frame/reg-fx - :navigate-replace-fx - (fn [view-id] - (log/debug :navigate-replace-fx view-id) - (.pop Navigation (name @state/root-comp-id)) - (navigate view-id))) - -(def community-screens '(:community-management - :community-members - :community-requests-to-join - :create-community-channel - :community-emoji-thumbnail-picker - :create-community-category - :community-edit-chats - :community-edit - :community-reorder-categories)) - -;; change view-id if it is still same after component is disappeared -;; https://github.com/wix/react-native-navigation/issues/5744#issuecomment-563226820 -(fx/defn view-disappeared - {:events [::view-disappeared]} - [{:keys [db]} view-id] - (when (= view-id (:view-id db)) - {:db (assoc db :view-id (cond - (= view-id :community-emoji-thumbnail-picker) - :create-community-channel - - (some #(= view-id %) community-screens) - :community - - :else - :home)) - :dispatch-n (enc/conj-when [] - (and (= view-id :chat) [:chat.ui/sync-all-deleted-for-me-messages]))})) diff --git a/src/status_im/navigation/roots.cljs b/src/status_im/navigation/roots.cljs deleted file mode 100644 index 1c7e74141b..0000000000 --- a/src/status_im/navigation/roots.cljs +++ /dev/null @@ -1,193 +0,0 @@ -(ns status-im.navigation.roots - (:require [quo.design-system.colors :as colors] - [status-im.utils.platform :as platform] - [status-im.ui.components.icons.icons :as icons] - [status-im.ui.screens.views :as views] - [status-im.navigation2.roots :as nav2-roots])) - -(defn status-bar-options [] - (if platform/android? - {:navigationBar {:backgroundColor colors/white} - :statusBar {:backgroundColor colors/white - :style (if (colors/dark?) :light :dark)}} - {:statusBar {:style (if (colors/dark?) :light :dark)}})) - -(defn topbar-options [] - {:noBorder true - :scrollEdgeAppearance {:active false - :noBorder true} - :elevation 0 - :title {:color colors/black} - :rightButtonColor colors/black - :background {:color colors/white} - :backButton {:icon (icons/icon-source :main-icons/arrow-left) - :color colors/black}}) - -(defn bottom-tab-general [icon accessibility] - (merge - {:testID accessibility - :accessibilityLabel accessibility - :fontSize 11 - :icon (icons/icon-source icon) - :badgeColor colors/blue - :dotIndicator {:color colors/blue :visible false :size 10} - :iconColor colors/gray :selectedIconColor colors/blue - :textColor colors/gray :selectedTextColor colors/blue} - (when platform/android? - {:badge ""}))) - -(defn default-root [] - {:layout {:componentBackgroundColor colors/white - :orientation "portrait" - :backgroundColor colors/white}}) - -(defn merge-top-bar [root-options options] - (let [options (:topBar options)] - {:topBar - (merge root-options - options - (when (or (:title root-options) (:title options)) - {:title (merge (:title root-options) (:title options))}) - (when (or (:background root-options) (:background options)) - {:background (merge (:background root-options) (:background options))}) - (when (or (:backButton root-options) (:backButton options)) - {:backButton (merge (:backButton root-options) (:backButton options))}) - (when (or (:leftButtons root-options) (:leftButtons options)) - {:leftButtons (merge (:leftButtons root-options) (:leftButtons options))}) - (when (or (:rightButtons root-options) (:rightButtons options)) - {:rightButtons (merge (:rightButtons root-options) (:rightButtons options))}))})) - -(defn get-screen-options [screen] - (merge (get-in views/screens [screen :options]) - (status-bar-options) - (merge-top-bar (topbar-options) - (get-in views/screens [screen :options])))) - -;;TODO problem here is that we have two places for screens, here and in screens ns, and we have handler in navigate -(defn roots [] - ;;TABS - (merge - {:chat-stack - {:root - {:bottomTabs - {:id :tabs-stack - :options (merge (default-root) - {:bottomTabs {:titleDisplayMode :alwaysHide - :tabsAttachMode :onSwitchToTab - :backgroundColor colors/white}}) - :children [;CHAT STACK - {:stack {:id :chat-stack - :children [{:component {:name :home - :id :home - :options (merge (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}] - :options {:bottomTab (bottom-tab-general :main-icons/message :home-tab-button)}}} - ;BROWSER STACK - {:stack {:id :browser-stack - :children [{:component {:name :empty-tab - :id :empty-tab - :options (merge (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}] - - :options {:bottomTab (bottom-tab-general :main-icons/browser :dapp-tab-button)}}} - ;WALLET STACK - {:stack {:id :wallet-stack - :children [{:component {:name :wallet - :id :wallet - :options (merge (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}] - :options {:bottomTab (bottom-tab-general :main-icons/wallet :wallet-tab-button)}}} - ;STATUS STACK - {:stack {:id :status-stack - :children [{:component {:name :status - :id :status - :options (merge (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}] - :options {:bottomTab (bottom-tab-general :main-icons/status :status-tab-button)}}} - ;PROFILE STACK - {:stack {:id :profile-stack - :children [{:component {:name :my-profile - :id :my-profile - :options (merge (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}] - :options {:bottomTab (bottom-tab-general :main-icons/user-profile :profile-tab-button)}}}]}}} - - ;;INTRO (onboarding carousel) - :intro - {:root {:stack {:children [{:component {:name :intro - :id :intro - :options (status-bar-options)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}} - - ;; ONBOARDING - :onboarding - {:root {:stack {:id :onboarding - :children [{:component {:name :get-your-keys - :id :get-your-keys - :options (status-bar-options)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (assoc (topbar-options) :elevation 0 :noBorder true :animate false)})}}} - - ;;PROGRESS - :progress - {:root {:stack {:children [{:component {:name :progress - :id :progress - :options (status-bar-options)}}] - :options (merge (default-root) - {:topBar (assoc (topbar-options) :visible false)})}}} - - ;;LOGIN - :multiaccounts - {:root {:stack {:id :multiaccounts-stack - :children [{:component {:name :multiaccounts - :id :multiaccounts - :options (get-screen-options :multiaccounts)}} - {:component {:name :login - :id :login - :options (get-screen-options :login)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (topbar-options)})}}} - - :multiaccounts-keycard - {:root {:stack {:id :multiaccounts-stack - :children [{:component {:name :multiaccounts - :id :multiaccounts - :options (get-screen-options :multiaccounts)}} - {:component {:name :keycard-login-pin - :id :keycard-login-pin - :options (get-screen-options :keycard-login-pin)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (topbar-options)})}}} - - ;;WELCOME - :welcome - {:root {:stack {:children [{:component {:name :welcome - :id :welcome - :options (status-bar-options)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}} - - ;;NOTIFICATIONS - :onboarding-notification - {:root {:stack {:children [{:component {:name :onboarding-notification - :id :onboarding-notification - :options (status-bar-options)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}} - - ;; TERMS OF SERVICE - :tos - {:root {:stack {:children [{:component {:name :force-accept-tos - :id :force-accept-tos - :options (get-screen-options :force-accept-tos)}}] - :options (merge (default-root) - (status-bar-options) - {:topBar (assoc (topbar-options) :visible false)})}}}} - (nav2-roots/roots))) diff --git a/src/status_im/navigation2.cljs b/src/status_im/navigation2.cljs deleted file mode 100644 index 01e4457ba1..0000000000 --- a/src/status_im/navigation2.cljs +++ /dev/null @@ -1,60 +0,0 @@ -(ns status-im.navigation2 - (:require [status-im.utils.fx :as fx] - [status-im.reloader :as reloader] - [status-im.utils.datetime :as datetime])) - -(def parent-stack (atom :shell-stack)) - -(fx/defn reload-new-ui - {:events [:reload-new-ui]} - [_] - (reloader/reload) - {:new-ui/reset-bottom-tabs nil - :dispatch [:init-root :shell-stack]}) - -(fx/defn init-root-nav2 - {:events [:init-root-nav2]} - [_ root-id] - {:init-root-fx-nav2 root-id}) - -(fx/defn open-modal-nav2 - {:events [:open-modal-nav2]} - [_ modal] - {:open-modal-fx-nav2 modal}) - -(fx/defn close-modal-nav2 - {:events [:close-modal-nav2]} - [_ modal] - {:close-modal-fx-nav2 modal}) - -(defn navigate-from-shell-stack [go-to-view-id id db] - (reset! parent-stack go-to-view-id) - {:navigate-to-fx-nav2 [go-to-view-id id] - :db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id - :id id - :clock (datetime/timestamp)})}) - -(defn navigate-from-switcher [go-to-view-id id db from-home?] - (reset! parent-stack go-to-view-id) - {:navigate-from-switcher-fx [go-to-view-id id from-home?] - :db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id - :id id - :clock (datetime/timestamp)})}) - -(fx/defn navigate-to-nav2 - {:events [:navigate-to-nav2]} - [{:keys [db]} go-to-view-id id _ from-switcher?] - (let [view-id (:view-id db) - from-home? (= view-id :chat-stack)] - (if from-switcher? - (navigate-from-switcher go-to-view-id id db from-home?) - (if from-home? - (navigate-from-shell-stack go-to-view-id id db) - ;; TODO(parvesh) - new stacks created from other screens should be stacked on current stack, instead of creating new entry - (navigate-from-shell-stack go-to-view-id id db))))) - -(fx/defn change-root-status-bar-style - {:events [:change-root-status-bar-style]} - [_ style] - {:change-root-status-bar-style-fx style}) - diff --git a/src/status_im/navigation2/core.cljs b/src/status_im/navigation2/core.cljs deleted file mode 100644 index 61bab6f364..0000000000 --- a/src/status_im/navigation2/core.cljs +++ /dev/null @@ -1,85 +0,0 @@ -(ns status-im.navigation2.core - (:require [re-frame.core :as re-frame] - [quo2.foundations.colors :as colors] - [status-im.ui.screens.views :as views] - [status-im.navigation2.roots :as roots] - [status-im.utils.platform :as platform] - [status-im.navigation.roots :as nav-roots] - [status-im.navigation2.utils :as nav2-utils] - ["react-native-navigation" :refer (Navigation)])) - -(def tab-key-idx {:home 0 - :communities 1 - :wallet 2 - :browser 3}) - -(defn change-root-status-bar-style [style] - (.mergeOptions Navigation - "shell-stack" - (clj->js {:statusBar {:style style}}))) - -;; TODO (parvesh) - improve open-modal and close-modal -(defn open-modal [comp] - (.showModal Navigation - (clj->js {:stack {:children - [{:component - {:name comp - :id comp - :options {:topBar {:visible false}}}}]}}))) - -(defn close-modal [_]) - -(defn close-all-modals [] - (.dismissAllModals Navigation)) - -(defn get-id [comp id] - (str comp "-" id)) - -(defn get-options [show-topbar? options] - (merge options - (roots/status-bar-options) - (when platform/android? - {:navigationBar {:backgroundColor (colors/theme-colors colors/white colors/neutral-90)}}) - (if show-topbar? - (nav-roots/merge-top-bar (nav-roots/topbar-options) options) - {:topBar {:visible false}}))) - -(defn change-stack-root [[comp _]] - (let [{:keys [options]} (get views/screens comp)] - (.setStackRoot Navigation - (name comp) - (clj->js {:stack {:id comp - :children [{:component {:id comp - :name comp - :options (get-options false options)}}]}})))) - -(defn navigate [[comp _]] - (let [{:keys [options]} (get views/screens comp)] - (reset! nav2-utils/container-stack-view-id comp) - (.push Navigation - "shell-stack" - (clj->js {:stack {:id comp - :children [{:component {:id comp - :name comp - :options (get-options false options)}}]}})))) - -(defn navigate-from-switcher [[comp id from-home?]] - (if from-home? - (navigate [comp id]) - (change-stack-root [comp id]))) - -(re-frame/reg-fx - :init-root-fx-nav2 - (fn [new-root-id] - (reset! nav2-utils/container-stack-view-id new-root-id) - (.setRoot Navigation (clj->js (get (roots/roots) new-root-id))))) - -(re-frame/reg-fx :open-modal-fx-nav2 open-modal) - -(re-frame/reg-fx :close-modal-fx-nav2 close-modal) - -(re-frame/reg-fx :navigate-to-fx-nav2 navigate) - -(re-frame/reg-fx :navigate-from-switcher-fx navigate-from-switcher) - -(re-frame/reg-fx :change-root-status-bar-style-fx change-root-status-bar-style) diff --git a/src/status_im/navigation2/roots.cljs b/src/status_im/navigation2/roots.cljs deleted file mode 100644 index 7a0ade1fac..0000000000 --- a/src/status_im/navigation2/roots.cljs +++ /dev/null @@ -1,20 +0,0 @@ -(ns status-im.navigation2.roots - (:require [quo2.foundations.colors :as colors] - [status-im.utils.platform :as platform])) - -(defn status-bar-options [] - (if platform/android? - {:navigationBar {:backgroundColor colors/neutral-100} - :statusBar {:backgroundColor :transparent - :style :light - :drawBehind true}} - {:statusBar {:style :light}})) - -(defn roots [] - {:shell-stack - {:root - {:stack {:id :shell-stack - :children [{:component {:name :chat-stack - :id :chat-stack - :options (merge (status-bar-options) - {:topBar {:visible false}})}}]}}}}) diff --git a/src/status_im/navigation2/screens.cljs b/src/status_im/navigation2/screens.cljs deleted file mode 100644 index fbb5b53fd5..0000000000 --- a/src/status_im/navigation2/screens.cljs +++ /dev/null @@ -1,22 +0,0 @@ -(ns status-im.navigation2.screens - (:require [status-im.ui2.screens.chat.view :as chat] - [status-im.switcher.shell-stack :as shell-stack] - [status-im.ui2.screens.communities.discover-communities :as discover-communities])) - - -;; We have to use the home screen name :chat-stack for now, for compatibility with navigation.cljs - - -(def screens [{:name :chat-stack ;; TODO(parvesh) - rename to shell-stack - :insets {:top false} - :component shell-stack/shell-stack} - {:name :discover-communities - ;;TODO animated-header scroll behaviours - :options {:topBar {:visible false}} - :component discover-communities/communities}]) - -;; These screens will overwrite navigation/screens.cljs screens on enabling new UI toggle -(def screen-overwrites - [{:name :chat - :options {:topBar {:visible false}} - :component chat/chat}]) diff --git a/src/status_im/navigation2/utils.cljs b/src/status_im/navigation2/utils.cljs deleted file mode 100644 index aebe9a65dd..0000000000 --- a/src/status_im/navigation2/utils.cljs +++ /dev/null @@ -1,3 +0,0 @@ -(ns status-im.navigation2.utils) - -(defonce container-stack-view-id (atom nil)) diff --git a/src/status_im/network/core.cljs b/src/status_im/network/core.cljs index 4cc2e916d0..5d121d8b0d 100644 --- a/src/status_im/network/core.cljs +++ b/src/status_im/network/core.cljs @@ -5,7 +5,7 @@ [status-im.ethereum.json-rpc :as json-rpc] [status-im.i18n.i18n :as i18n] [status-im.node.core :as node] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.http :as http] [status-im.utils.types :as types])) diff --git a/src/status_im/network/net_info.cljs b/src/status_im/network/net_info.cljs index aecc5dc91c..aed78daa7e 100644 --- a/src/status_im/network/net_info.cljs +++ b/src/status_im/network/net_info.cljs @@ -51,7 +51,7 @@ (js->clj % :keywordize-keys true)])))) (re-frame/reg-fx - ::listen-to-network-info + :network/listen-to-network-info (fn [] (add-net-info-listener))) diff --git a/src/status_im/pairing/core.cljs b/src/status_im/pairing/core.cljs index 6c7dfc4312..c52299e4d4 100644 --- a/src/status_im/pairing/core.cljs +++ b/src/status_im/pairing/core.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :as re-frame] [status-im.ethereum.json-rpc :as json-rpc] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.config :as config] [status-im.utils.fx :as fx] [status-im.utils.platform :as utils.platform] diff --git a/src/status_im/qr_scanner/core.cljs b/src/status_im/qr_scanner/core.cljs index f5a84d9022..790a78beb2 100644 --- a/src/status_im/qr_scanner/core.cljs +++ b/src/status_im/qr_scanner/core.cljs @@ -3,7 +3,7 @@ [status-im.i18n.i18n :as i18n] [status-im.chat.models :as chat] [status-im.router.core :as router] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.utils :as utils] [status-im.ethereum.core :as ethereum] [status-im.add-new.db :as new-chat.db] diff --git a/src/status_im/router/core.cljs b/src/status_im/router/core.cljs index c2d6e096ac..ea8ad9f09a 100644 --- a/src/status_im/router/core.cljs +++ b/src/status_im/router/core.cljs @@ -1,6 +1,5 @@ (ns status-im.router.core (:require [bidi.bidi :as bidi] - [cljs.spec.alpha :as spec] [clojure.string :as string] [re-frame.core :as re-frame] [status-im.add-new.db :as public-chat.db] @@ -65,7 +64,7 @@ (defn match-contact-async [chain {:keys [user-id ens-name]} callback] - (let [valid-key (and (spec/valid? :global/public-key user-id) + (let [valid-key (and (utils.db/valid-public-key? user-id) (not= user-id ens/default-key))] (cond valid-key @@ -200,7 +199,7 @@ (= handler :group-chat) (cb (match-group-chat chats query-params)) - (spec/valid? :global/public-key uri) + (utils.db/valid-public-key? uri) (match-contact-async chain {:user-id uri} cb) (= handler :community-requests) diff --git a/src/status_im/search/core_test.cljs b/src/status_im/search/core_test.cljs index 753f37d51f..cf8cf4137c 100644 --- a/src/status_im/search/core_test.cljs +++ b/src/status_im/search/core_test.cljs @@ -1,6 +1,6 @@ (ns status-im.search.core-test (:require [cljs.test :refer-macros [deftest testing is]] - [status-im.subs.search :as search.subs])) + [status-im2.subs.search :as search.subs])) (defn extract-chat-attributes [chat] (let [{:keys [name alias tags]} (val chat)] diff --git a/src/status_im/stickers/core.cljs b/src/status_im/stickers/core.cljs index 02d9cb25d3..c291bc4f74 100644 --- a/src/status_im/stickers/core.cljs +++ b/src/status_im/stickers/core.cljs @@ -3,7 +3,7 @@ [re-frame.core :as re-frame] [status-im.ethereum.core :as ethereum] [status-im.ethereum.json-rpc :as json-rpc] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.utils :as utils] [status-im.utils.config :as config] diff --git a/src/status_im/ui/components/tabbar/core.cljs b/src/status_im/ui/components/tabbar/core.cljs index efa4a6e025..80691c84a7 100644 --- a/src/status_im/ui/components/tabbar/core.cljs +++ b/src/status_im/ui/components/tabbar/core.cljs @@ -1,25 +1,9 @@ (ns status-im.ui.components.tabbar.core - (:require [re-frame.core :as re-frame] - [status-im.utils.platform :as platform])) + (:require [status-im.utils.platform :as platform])) (defn get-height [] (if platform/android? 56 (if platform/iphone-x? 84 - 50))) - -(defn chat-tab [] - (let [count-subscription @(re-frame/subscribe [:chats/unread-messages-number])] - (re-frame/dispatch [:change-tab-count :chat count-subscription]) - nil)) - -(defn profile-tab [] - (let [count-subscription @(re-frame/subscribe [:get-profile-unread-messages-number])] - (re-frame/dispatch [:change-tab-count :profile count-subscription]) - nil)) - -(defn tabs-counts-subscriptions [] - [:<> - [chat-tab] - [profile-tab]]) \ No newline at end of file + 50))) \ No newline at end of file diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 822573caa4..6fb32948a1 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -36,7 +36,7 @@ [status-im.utils.utils :as utils] [status-im.ui.screens.chat.sheets :as sheets] [status-im.utils.debounce :as debounce] - [status-im.navigation.state :as navigation.state] + [status-im2.navigation.state :as navigation.state] [status-im.react-native.resources :as resources])) (defn invitation-requests [chat-id admins] diff --git a/src/status_im/ui/screens/group/views.cljs b/src/status_im/ui/screens/group/views.cljs index fc8b7dab89..b28b31bea4 100644 --- a/src/status_im/ui/screens/group/views.cljs +++ b/src/status_im/ui/screens/group/views.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.group.views - (:require [cljs.spec.alpha :as spec] - [clojure.string :as string] + (:require [clojure.string :as string] [re-frame.core :as re-frame] [reagent.core :as reagent] [status-im.constants :as constants] @@ -100,7 +99,7 @@ (views/defview new-group [] (views/letsubs [contacts [:selected-group-contacts] group-name [:new-chat-name]] - (let [group-name-empty? (not (spec/valid? :global/not-empty-string group-name))] + (let [group-name-empty? (not (and (string? group-name) (not-empty group-name)))] [react/keyboard-avoiding-view {:style styles/group-container :ignore-offset true} [react/view {:flex 1} diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index 4765504fa4..d37a357440 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -21,7 +21,6 @@ [status-im.ui.components.topbar :as topbar] [status-im.ui.components.plus-button :as components.plus-button] [status-im.ui.screens.chat.sheets :as sheets] - [status-im.ui.components.tabbar.core :as tabbar] [status-im.ui.components.invite.views :as invite] [status-im.utils.config :as config] [quo2.components.markdown.text :as quo2.text] @@ -340,8 +339,7 @@ :margin-bottom 8} [quo2.text/text {:size :heading-1 :weight :semi-bold} (i18n/label :t/messages)] [plus-button]] - [chats-list] - [tabbar/tabs-counts-subscriptions]]) + [chats-list]]) (defn home-old [] [react/keyboard-avoiding-view {:style {:flex 1} @@ -352,5 +350,4 @@ [connectivity/connectivity-button] [notifications-button-old]]}] [chats-list-old] - [plus-button-old] - [tabbar/tabs-counts-subscriptions]]) + [plus-button-old]]) diff --git a/src/status_im/ui/screens/keycard/pin/views.cljs b/src/status_im/ui/screens/keycard/pin/views.cljs index 60d5a26aa4..eae9ccd481 100644 --- a/src/status_im/ui/screens/keycard/pin/views.cljs +++ b/src/status_im/ui/screens/keycard/pin/views.cljs @@ -9,8 +9,7 @@ [status-im.ui.components.react :as react] [status-im.ui.screens.keycard.pin.styles :as styles] [status-im.ui.components.checkbox.view :as checkbox] - [status-im.utils.platform :as platform] - [status-im.utils.utils :as utils])) + [status-im.utils.platform :as platform])) (def default-pin-retries-number 3) (def default-puk-retries-number 5) @@ -164,7 +163,6 @@ (case new-status :error (when (or (nil? previous-status) (= :verifying previous-status)) - (utils/vibrate) (reset! !error? true) (animate-info-in error-y-translation error-opacity diff --git a/src/status_im/ui/screens/keycard/views.cljs b/src/status_im/ui/screens/keycard/views.cljs index 287d45fe1c..701ff1fdcf 100644 --- a/src/status_im/ui/screens/keycard/views.cljs +++ b/src/status_im/ui/screens/keycard/views.cljs @@ -20,7 +20,7 @@ [status-im.ui.screens.keycard.frozen-card.view :as frozen-card.view] [status-im.multiaccounts.create.core :as multiaccounts.create] [status-im.bottom-sheet.core :as bottom-sheet] - [status-im.navigation :as navigation]) + [status-im2.navigation.events :as navigation]) (:require-macros [status-im.utils.views :refer [defview letsubs]])) ;; NOTE(Ferossgp): Seems like it should be in popover diff --git a/src/status_im/ui/screens/screens.cljs b/src/status_im/ui/screens/screens.cljs index 7f536ae6bb..f854562f96 100644 --- a/src/status_im/ui/screens/screens.cljs +++ b/src/status_im/ui/screens/screens.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.screens (:require [quo.design-system.colors :as colors] - [quo.previews.main :as quo.preview] [status-im.add-new.core :as new-chat.events] [status-im.i18n.i18n :as i18n] [status-im.ui.components.icons.icons :as icons] @@ -119,795 +118,778 @@ [status-im.ui.screens.wallet.buy-crypto.views :as wallet.buy-crypto] [status-im.ui.screens.wallet.recipient.views :as recipient] [status-im.ui.screens.wallet.send.views :as wallet.send] - [status-im.ui2.screens.quo2-preview.main :as quo2.preview] [status-im.utils.config :as config] - [status-im.ui.screens.wallet.manage-connections.views :as manage-all-connections] - [status-im.navigation2.screens :as navigation2.screens])) - -(def components - []) + [status-im.ui.screens.wallet.manage-connections.views :as manage-all-connections])) (defn right-button-options [id icon] {:id id :icon (icons/icon-source icon)}) (defn screens [] - (concat [;;INTRO, ONBOARDING, LOGIN + [;;INTRO, ONBOARDING, LOGIN - ;Multiaccounts - {:name :multiaccounts - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/your-keys)} - :rightButtons (right-button-options :multiaccounts :more)}} - :right-handler multiaccounts/topbar-button - :component multiaccounts/multiaccounts} + ;Multiaccounts + {:name :multiaccounts + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/your-keys)} + :rightButtons (right-button-options :multiaccounts :more)}} + :right-handler multiaccounts/topbar-button + :component multiaccounts/multiaccounts} - ;Login - {:name :login - :insets {:bottom true} - :options {:topBar {:rightButtons (right-button-options :login :more)}} - :right-handler login/topbar-button - :component login/login} + ;Login + {:name :login + :insets {:bottom true} + :options {:topBar {:rightButtons (right-button-options :login :more)}} + :right-handler login/topbar-button + :component login/login} - {:name :progress - :component progress/progress} + {:name :progress + :component progress/progress} - ;[Onboarding] - {:name :intro - :insets {:bottom true} - :component onboarding.intro/intro} + ;[Onboarding] + {:name :intro + :insets {:bottom true} + :component onboarding.intro/intro} - ;[Onboarding] - {:name :get-your-keys - :insets {:bottom true} - :component onboarding.keys/get-your-keys} + ;[Onboarding] + {:name :get-your-keys + :insets {:bottom true} + :component onboarding.keys/get-your-keys} - ;[Onboarding] - {:name :choose-name - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component onboarding.keys/choose-a-chat-name} + ;[Onboarding] + {:name :choose-name + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component onboarding.keys/choose-a-chat-name} - ;[Onboarding] - {:name :select-key-storage - :insets {:bottom true} - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component onboarding.storage/select-key-storage} + ;[Onboarding] + {:name :select-key-storage + :insets {:bottom true} + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component onboarding.storage/select-key-storage} - ;[Onboarding] Create Password - {:name :create-password - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component onboarding.password/screen} + ;[Onboarding] Create Password + {:name :create-password + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component onboarding.password/screen} - ;[Onboarding] Welcome - {:name :welcome - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component onboarding.welcome/welcome} + ;[Onboarding] Welcome + {:name :welcome + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component onboarding.welcome/welcome} - ;[Onboarding] Notification - {:name :onboarding-notification - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component onboarding.notifications/notifications-onboarding} + ;[Onboarding] Notification + {:name :onboarding-notification + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component onboarding.notifications/notifications-onboarding} - ;[Onboarding] Recovery - {:name :recover-multiaccount-enter-phrase - :insets {:bottom true} - :component onboarding.phrase/enter-phrase} - {:name :recover-multiaccount-success - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component onboarding.phrase/wizard-recovery-success} + ;[Onboarding] Recovery + {:name :recover-multiaccount-enter-phrase + :insets {:bottom true} + :component onboarding.phrase/enter-phrase} + {:name :recover-multiaccount-success + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component onboarding.phrase/wizard-recovery-success} - ;;CHAT + ;;CHAT - ;Home - {:name :home - :component (if config/new-ui-enabled? chat.home/home old-chat.home/home-old)} + ;Home + {:name :home + :component (if config/new-ui-enabled? chat.home/home old-chat.home/home-old)} - ;Chat - {:name :chat - :options {:popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false} - :topBar {:visible false}} - :component chat/chat} + ;Chat + {:name :chat + :options {:popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false} + :topBar {:visible false}} + :component chat/chat} - ;Pinned messages - {:name :chat-pinned-messages - ;TODO custom subtitle - :options {:topBar {:visible false}} - :component pin-messages/pinned-messages} + ;Pinned messages + {:name :chat-pinned-messages + ;TODO custom subtitle + :options {:topBar {:visible false}} + :component pin-messages/pinned-messages} - {:name :group-chat-profile - :insets {:top false} - ;;TODO animated-header - :options {:topBar {:visible false}} - :component profile.group-chat/group-chat-profile} - {:name :group-chat-invite - ;;TODO parameter in the event - :options {:topBar {:visible false}} - :component profile.group-chat/group-chat-invite} + {:name :group-chat-profile + :insets {:top false} + ;;TODO animated-header + :options {:topBar {:visible false}} + :component profile.group-chat/group-chat-profile} + {:name :group-chat-invite + ;;TODO parameter in the event + :options {:topBar {:visible false}} + :component profile.group-chat/group-chat-invite} - {:name :stickers - :options {:topBar {:title {:text (i18n/label :t/sticker-market)}}} - :component stickers/packs} + {:name :stickers + :options {:topBar {:title {:text (i18n/label :t/sticker-market)}}} + :component stickers/packs} - {:name :stickers-pack - :component stickers/pack} + {:name :stickers-pack + :component stickers/pack} - {:name :notifications-center - ;;TODO custom nav - :options {:topBar {:visible false}} - :component notifications-center/center} - {:name :activity-center - :options {:topBar {:visible false}} - :component activity-center/activity-center} - ;; Community - {:name :community - ;;TODO custom - :options {:topBar {:visible false}} - :component community/community} - {:name :community-management - :insets {:top false} - ;;TODO animated-header - :options {:topBar {:visible false}} - :component community.profile/management-container} - {:name :community-members - ;;TODO custom subtitle - :options {:topBar {:visible false}} - :component members/members-container} - {:name :community-requests-to-join - ;;TODO custom subtitle - :options {:topBar {:visible false}} - :component requests-to-join/requests-to-join-container} - {:name :create-community-channel - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/create-channel-title)}}} - :component create-channel/view} - {:name :community-emoji-thumbnail-picker - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/community-emoji-thumbnail-title)}}} - :component community-emoji-thumbnail-picker/view} - {:name :create-community-category - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/new-category)}}} - :component create-category/view} - {:name :select-category - :insets {:bottom true} - ;;TODO custom - :options {:topBar {:visible false}} - :component select-category/view} - {:name :community-reorder-categories - :insets {:top false} - :options {:topBar {:visible false}} - :component reorder-categories/view} - {:name :community-channel-details - :insets {:top false} - ;;TODO custom - :options {:topBar {:visible false}} - :component communities.channel-details/view} - {:name :edit-community-channel - :options {:topBar {:title {:text (i18n/label :t/edit-channel-title)}}} - :insets {:bottom true} - :component edit-channel/view} - {:name :contact-toggle-list - ;;TODO custom subtitle - :options {:topBar {:visible false}} - :component group-chat/contact-toggle-list} - {:name :new-group - :options {:topBar {:visible false}} - ;;TODO custom subtitle - :component group-chat/new-group} - {:name :communities - ;;TODO custom - :options {:topBar {:visible false}} - :component communities/communities} - {:name :community-import - :options {:topBar {:title {:text (i18n/label :t/import-community-title)}}} - :component communities.import/view} - {:name :community-edit - :options {:topBar {:title {:text (i18n/label :t/community-edit-title)}}} - :component community.edit/edit} - {:name :community-create - :options {:topBar {:title {:text (i18n/label :t/new-community-title)}}} - :component communities.create/view} - {:name :community-membership - :options {:topBar {:title {:text (i18n/label :t/membership-title)}}} - :component membership/membership} - {:name :community-overview - :options {:topBar {:visible false}} - :component community-overview/overview} - ;;BROWSER + {:name :notifications-center + ;;TODO custom nav + :options {:topBar {:visible false}} + :component notifications-center/center} + {:name :activity-center + :options {:topBar {:visible false}} + :component activity-center/activity-center} + ;; Community + {:name :community + ;;TODO custom + :options {:topBar {:visible false}} + :component community/community} + {:name :community-management + :insets {:top false} + ;;TODO animated-header + :options {:topBar {:visible false}} + :component community.profile/management-container} + {:name :community-members + ;;TODO custom subtitle + :options {:topBar {:visible false}} + :component members/members-container} + {:name :community-requests-to-join + ;;TODO custom subtitle + :options {:topBar {:visible false}} + :component requests-to-join/requests-to-join-container} + {:name :create-community-channel + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/create-channel-title)}}} + :component create-channel/view} + {:name :community-emoji-thumbnail-picker + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/community-emoji-thumbnail-title)}}} + :component community-emoji-thumbnail-picker/view} + {:name :create-community-category + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/new-category)}}} + :component create-category/view} + {:name :select-category + :insets {:bottom true} + ;;TODO custom + :options {:topBar {:visible false}} + :component select-category/view} + {:name :community-reorder-categories + :insets {:top false} + :options {:topBar {:visible false}} + :component reorder-categories/view} + {:name :community-channel-details + :insets {:top false} + ;;TODO custom + :options {:topBar {:visible false}} + :component communities.channel-details/view} + {:name :edit-community-channel + :options {:topBar {:title {:text (i18n/label :t/edit-channel-title)}}} + :insets {:bottom true} + :component edit-channel/view} + {:name :contact-toggle-list + ;;TODO custom subtitle + :options {:topBar {:visible false}} + :component group-chat/contact-toggle-list} + {:name :new-group + :options {:topBar {:visible false}} + ;;TODO custom subtitle + :component group-chat/new-group} + {:name :communities + ;;TODO custom + :options {:topBar {:visible false}} + :component communities/communities} + {:name :community-import + :options {:topBar {:title {:text (i18n/label :t/import-community-title)}}} + :component communities.import/view} + {:name :community-edit + :options {:topBar {:title {:text (i18n/label :t/community-edit-title)}}} + :component community.edit/edit} + {:name :community-create + :options {:topBar {:title {:text (i18n/label :t/new-community-title)}}} + :component communities.create/view} + {:name :community-membership + :options {:topBar {:title {:text (i18n/label :t/membership-title)}}} + :component membership/membership} + {:name :community-overview + :options {:topBar {:visible false}} + :component community-overview/overview} + ;;BROWSER - {:name :empty-tab - :insets {:top true} - :options {:topBar {:visible false} - :hardwareBackButton {:popStackOnPress false}} - :component empty-tab/empty-tab} - {:name :browser - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component browser/browser} - {:name :browser-tabs - :insets {:top true} - :options {:topBar {:visible false} - :hardwareBackButton {:popStackOnPress false}} - :component browser.tabs/tabs} + {:name :empty-tab + :insets {:top true} + :options {:topBar {:visible false} + :hardwareBackButton {:popStackOnPress false}} + :component empty-tab/empty-tab} + {:name :browser + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component browser/browser} + {:name :browser-tabs + :insets {:top true} + :options {:topBar {:visible false} + :hardwareBackButton {:popStackOnPress false}} + :component browser.tabs/tabs} - ;;WALLET + ;;WALLET - {:name :wallet - :insets {:top false} - :on-focus [:wallet/tab-opened] - ;;TODO wallet redesign - ;;:options {:statusBar {:backgroundColor quo2.colors/neutral-5}} - :component wallet.accounts/accounts-overview-old} - {:name :wallet-account - ;;TODO dynamic titleaccounts-overview - :options {:topBar {:visible false}} - :component wallet.account/account} - {:name :add-new-account - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component add-account/add-account} - {:name :add-new-account-pin - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component add-account/pin} - {:name :account-settings - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component account-settings/account-settings} - {:name :wallet-transaction-details - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wallet-transactions/transaction-details} - {:name :wallet-settings-assets - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wallet-settings/manage-assets} - {:name :wallet-add-custom-token - :on-focus [:wallet/wallet-add-custom-token] - :options {:topBar {:title {:text (i18n/label :t/add-custom-token)}}} - :component custom-tokens/add-custom-token} - {:name :wallet-custom-token-details - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component custom-tokens/custom-token-details} - {:name :currency-settings - :options {:topBar {:title {:text (i18n/label :t/main-currency)}}} - :component currency-settings/currency-settings} + {:name :wallet + :insets {:top false} + :on-focus [:wallet/tab-opened] + ;;TODO wallet redesign + ;;:options {:statusBar {:backgroundColor quo2.colors/neutral-5}} + :component wallet.accounts/accounts-overview-old} + {:name :wallet-account + ;;TODO dynamic titleaccounts-overview + :options {:topBar {:visible false}} + :component wallet.account/account} + {:name :add-new-account + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component add-account/add-account} + {:name :add-new-account-pin + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component add-account/pin} + {:name :account-settings + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component account-settings/account-settings} + {:name :wallet-transaction-details + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wallet-transactions/transaction-details} + {:name :wallet-settings-assets + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wallet-settings/manage-assets} + {:name :wallet-add-custom-token + :on-focus [:wallet/wallet-add-custom-token] + :options {:topBar {:title {:text (i18n/label :t/add-custom-token)}}} + :component custom-tokens/add-custom-token} + {:name :wallet-custom-token-details + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component custom-tokens/custom-token-details} + {:name :currency-settings + :options {:topBar {:title {:text (i18n/label :t/main-currency)}}} + :component currency-settings/currency-settings} - {:name :manage-accounts - :options {:topBar {:title {:text (i18n/label :t/wallet-manage-accounts)}}} - :component accounts-manage/manage} + {:name :manage-accounts + :options {:topBar {:title {:text (i18n/label :t/wallet-manage-accounts)}}} + :component accounts-manage/manage} - {:name :token-swap - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wallet.swap/swap} + {:name :token-swap + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wallet.swap/swap} - {:name :token-swap-advanced-nonce - :options {:topBar {:title {:text (i18n/label :t/nonce)}}} - :component wallet.swap/nonce-modal} + {:name :token-swap-advanced-nonce + :options {:topBar {:title {:text (i18n/label :t/nonce)}}} + :component wallet.swap/nonce-modal} - {:name :token-swap-advanced-approve-token - :options {:topBar {:title {:text (i18n/label :t/approve-token)}}} - :component wallet.swap/approve-token-modal} + {:name :token-swap-advanced-approve-token + :options {:topBar {:title {:text (i18n/label :t/approve-token)}}} + :component wallet.swap/approve-token-modal} - {:name :token-swap-advanced-transaction-fee - :options {:topBar {:title {:text (i18n/label :t/transaction-fee)}}} - :component wallet.swap/transaction-fee-modal} + {:name :token-swap-advanced-transaction-fee + :options {:topBar {:title {:text (i18n/label :t/transaction-fee)}}} + :component wallet.swap/transaction-fee-modal} - {:name :token-swap-advanced-swap-details - :options {:topBar {:title {:text (i18n/label :t/swap-details)}}} - :component wallet.swap/swap-details-modal} + {:name :token-swap-advanced-swap-details + :options {:topBar {:title {:text (i18n/label :t/swap-details)}}} + :component wallet.swap/swap-details-modal} - {:name :swap-asset-selector - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wallet.swap/asset-selector} + {:name :swap-asset-selector + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wallet.swap/asset-selector} - ;;MY STATUS + ;;MY STATUS - {:name :status - :on-focus [:init-timeline-chat] - :insets {:top true} - :component status.views/timeline} + {:name :status + :on-focus [:init-timeline-chat] + :insets {:top true} + :component status.views/timeline} - ;;PROFILE + ;;PROFILE - {:name :my-profile - :insets {:top false} - :options {:topBar {:visible false}} - :component profile.user/my-profile} - {:name :contacts-list - :options {:topBar {:title {:text (i18n/label :t/contacts)}}} - :component contacts-list/contacts-list} - {:name :ens-main - :options {:topBar {:title {:text (i18n/label :t/ens-usernames)}}} - :component ens/main} - {:name :ens-search - :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} - :component ens/search} - {:name :ens-checkout - :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} - :component ens/checkout} - {:name :ens-confirmation - :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} - :component ens/confirmation} - {:name :ens-terms - :options {:topBar {:title {:text (i18n/label :t/ens-terms-registration)}}} - :component ens/terms} - {:name :ens-name-details - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component ens/name-details} - {:name :blocked-users-list - :options {:topBar {:title {:text (i18n/label :t/blocked-users)}}} - :component contacts-list/blocked-users-list} - {:name :wakuv2-settings - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wakuv2-settings/wakuv2-settings} - {:name :edit-wakuv2-node - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component edit-wakuv2-node/edit-node} - {:name :bootnodes-settings - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component bootnodes-settings/bootnodes-settings} - {:name :installations - :options {:topBar {:title {:text (i18n/label :t/devices)}}} - :component pairing/installations} - {:name :edit-bootnode - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component edit-bootnode/edit-bootnode} - {:name :offline-messaging-settings - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component offline-messaging-settings/offline-messaging-settings} - {:name :edit-mailserver - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component edit-mailserver/edit-mailserver} - {:name :dapps-permissions - :options {:topBar {:title {:text (i18n/label :t/dapps-permissions)}}} - :component dapps-permissions/dapps-permissions} - {:name :link-previews-settings - :options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}} - :component link-previews-settings/link-previews-settings} - {:name :privacy-and-security - :options {:topBar {:title {:text (i18n/label :t/privacy-and-security)}}} - :component privacy-and-security/privacy-and-security} - {:name :messages-from-contacts-only - :options {:topBar {:title {:text (i18n/label :t/accept-new-chats-from)}}} - :component messages-from-contacts-only/messages-from-contacts-only} - {:name :appearance - :options {:topBar {:title {:text (i18n/label :t/appearance)}}} - :component appearance/appearance} - {:name :privacy-and-security-profile-pic-show-to - :options {:topbar {:title {:text (i18n/label :t/show-profile-pictures-to)}}} - :component privacy-and-security/profile-pic-show-to} - {:name :privacy-and-security-profile-pic - :options {:topBar {:title {:text (i18n/label :t/show-profile-pictures)}}} - :component privacy-and-security/profile-pic} - {:name :notifications - :options {:topBar {:title {:text (i18n/label :t/notification-settings)}}} - :component notifications-settings/notifications-settings} - {:name :notifications-servers - :options {:topBar {:title {:text (i18n/label :t/notifications-servers)}}} - :component notifications-settings/notifications-servers} - {:name :sync-settings - :options {:topBar {:title {:text (i18n/label :t/sync-settings)}}} - :component sync-settings/sync-settings} - {:name :advanced-settings - :options {:topBar {:title {:text (i18n/label :t/advanced)}}} - :component advanced-settings/advanced-settings} - {:name :help-center - :options {:topBar {:title {:text (i18n/label :t/need-help)}}} - :component help-center/help-center} - {:name :glossary - :options {:topBar {:title {:text (i18n/label :t/glossary)}}} - :component glossary/glossary} - {:name :about-app - :options {:topBar {:title {:text (i18n/label :t/about-app)}}} - :component about-app/about-app} - {:name :privacy-policy - :options {:topBar {:title {:text (i18n/label :t/privacy-policy)}}} - :component about-app/privacy-policy} - {:name :terms-of-service - :options {:topBar {:title {:text (i18n/label :t/terms-of-service)}}} - :component about-app/tos} - {:name :principles - :options {:topBar {:title {:text (i18n/label :t/principles)}}} - :component about-app/principles} - {:name :force-accept-tos - :options {:topBar {:visible false}} - :component terms-of-service/force-accept-tos} - {:name :manage-dapps-permissions - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component dapps-permissions/manage} - {:name :network-settings - ;;TODO accessories - :options {:topBar {:visible false}} - :component network/network-settings} - {:name :network-details - :options {:topBar {:title {:text (i18n/label :t/network-details)}}} - :component network-details/network-details} - {:name :network-info - :options {:topBar {:title {:text (i18n/label :t/network-info)}}} - :component network-info/network-info} - {:name :rpc-usage-info - :options {:topBar {:title {:text (i18n/label :t/rpc-usage-info)}}} - :component rpc-usage-info/usage-info} - {:name :edit-network - :options {:topBar {:title {:text (i18n/label :t/add-network)}}} - :component edit-network/edit-network} - {:name :log-level-settings - :options {:topBar {:title {:text (i18n/label :t/log-level-settings)}}} - :component log-level-settings/log-level-settings} - {:name :fleet-settings - :options {:topBar {:title {:text (i18n/label :t/fleet-settings)}}} - :component fleet-settings/fleet-settings} - {:name :mobile-network-settings - :options {:topBar {:title {:text (i18n/label :t/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 - ;;TODO dynamic navigation - :options {:topBar {:visible false}} - :component profile.seed/backup-seed} - {:name :reset-password - :options {:topBar {:title {:text (i18n/label :t/reset-password)}}} - :component reset-password/reset-password} - {:name :delete-profile - :insets {:bottom true} - :component delete-profile/delete-profile} - {:name :default-sync-period-settings - :options {:topBar {:title {:text (i18n/label :t/default-sync-period)}}} - :component default-sync-period-settings/default-sync-period-settings} + {:name :my-profile + :insets {:top false} + :options {:topBar {:visible false}} + :component profile.user/my-profile} + {:name :contacts-list + :options {:topBar {:title {:text (i18n/label :t/contacts)}}} + :component contacts-list/contacts-list} + {:name :ens-main + :options {:topBar {:title {:text (i18n/label :t/ens-usernames)}}} + :component ens/main} + {:name :ens-search + :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} + :component ens/search} + {:name :ens-checkout + :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} + :component ens/checkout} + {:name :ens-confirmation + :options {:topBar {:title {:text (i18n/label :t/ens-your-username)}}} + :component ens/confirmation} + {:name :ens-terms + :options {:topBar {:title {:text (i18n/label :t/ens-terms-registration)}}} + :component ens/terms} + {:name :ens-name-details + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component ens/name-details} + {:name :blocked-users-list + :options {:topBar {:title {:text (i18n/label :t/blocked-users)}}} + :component contacts-list/blocked-users-list} + {:name :wakuv2-settings + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wakuv2-settings/wakuv2-settings} + {:name :edit-wakuv2-node + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component edit-wakuv2-node/edit-node} + {:name :bootnodes-settings + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component bootnodes-settings/bootnodes-settings} + {:name :installations + :options {:topBar {:title {:text (i18n/label :t/devices)}}} + :component pairing/installations} + {:name :edit-bootnode + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component edit-bootnode/edit-bootnode} + {:name :offline-messaging-settings + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component offline-messaging-settings/offline-messaging-settings} + {:name :edit-mailserver + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component edit-mailserver/edit-mailserver} + {:name :dapps-permissions + :options {:topBar {:title {:text (i18n/label :t/dapps-permissions)}}} + :component dapps-permissions/dapps-permissions} + {:name :link-previews-settings + :options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}} + :component link-previews-settings/link-previews-settings} + {:name :privacy-and-security + :options {:topBar {:title {:text (i18n/label :t/privacy-and-security)}}} + :component privacy-and-security/privacy-and-security} + {:name :messages-from-contacts-only + :options {:topBar {:title {:text (i18n/label :t/accept-new-chats-from)}}} + :component messages-from-contacts-only/messages-from-contacts-only} + {:name :appearance + :options {:topBar {:title {:text (i18n/label :t/appearance)}}} + :component appearance/appearance} + {:name :privacy-and-security-profile-pic-show-to + :options {:topbar {:title {:text (i18n/label :t/show-profile-pictures-to)}}} + :component privacy-and-security/profile-pic-show-to} + {:name :privacy-and-security-profile-pic + :options {:topBar {:title {:text (i18n/label :t/show-profile-pictures)}}} + :component privacy-and-security/profile-pic} + {:name :notifications + :options {:topBar {:title {:text (i18n/label :t/notification-settings)}}} + :component notifications-settings/notifications-settings} + {:name :notifications-servers + :options {:topBar {:title {:text (i18n/label :t/notifications-servers)}}} + :component notifications-settings/notifications-servers} + {:name :sync-settings + :options {:topBar {:title {:text (i18n/label :t/sync-settings)}}} + :component sync-settings/sync-settings} + {:name :advanced-settings + :options {:topBar {:title {:text (i18n/label :t/advanced)}}} + :component advanced-settings/advanced-settings} + {:name :help-center + :options {:topBar {:title {:text (i18n/label :t/need-help)}}} + :component help-center/help-center} + {:name :glossary + :options {:topBar {:title {:text (i18n/label :t/glossary)}}} + :component glossary/glossary} + {:name :about-app + :options {:topBar {:title {:text (i18n/label :t/about-app)}}} + :component about-app/about-app} + {:name :privacy-policy + :options {:topBar {:title {:text (i18n/label :t/privacy-policy)}}} + :component about-app/privacy-policy} + {:name :terms-of-service + :options {:topBar {:title {:text (i18n/label :t/terms-of-service)}}} + :component about-app/tos} + {:name :principles + :options {:topBar {:title {:text (i18n/label :t/principles)}}} + :component about-app/principles} + {:name :force-accept-tos + :options {:topBar {:visible false}} + :component terms-of-service/force-accept-tos} + {:name :manage-dapps-permissions + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component dapps-permissions/manage} + {:name :network-settings + ;;TODO accessories + :options {:topBar {:visible false}} + :component network/network-settings} + {:name :network-details + :options {:topBar {:title {:text (i18n/label :t/network-details)}}} + :component network-details/network-details} + {:name :network-info + :options {:topBar {:title {:text (i18n/label :t/network-info)}}} + :component network-info/network-info} + {:name :rpc-usage-info + :options {:topBar {:title {:text (i18n/label :t/rpc-usage-info)}}} + :component rpc-usage-info/usage-info} + {:name :edit-network + :options {:topBar {:title {:text (i18n/label :t/add-network)}}} + :component edit-network/edit-network} + {:name :log-level-settings + :options {:topBar {:title {:text (i18n/label :t/log-level-settings)}}} + :component log-level-settings/log-level-settings} + {:name :fleet-settings + :options {:topBar {:title {:text (i18n/label :t/fleet-settings)}}} + :component fleet-settings/fleet-settings} + {:name :mobile-network-settings + :options {:topBar {:title {:text (i18n/label :t/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 + ;;TODO dynamic navigation + :options {:topBar {:visible false}} + :component profile.seed/backup-seed} + {:name :reset-password + :options {:topBar {:title {:text (i18n/label :t/reset-password)}}} + :component reset-password/reset-password} + {:name :delete-profile + :insets {:bottom true} + :component delete-profile/delete-profile} + {:name :default-sync-period-settings + :options {:topBar {:title {:text (i18n/label :t/default-sync-period)}}} + :component default-sync-period-settings/default-sync-period-settings} - ;;MODALS + ;;MODALS - ;[Chat] New Chat - {:name :new-chat - :on-focus [::new-chat.events/new-chat-focus] - ;;TODO accessories - :options {:topBar {:visible false}} - :component new-chat/new-chat} + ;[Chat] New Chat + {:name :new-chat + :on-focus [::new-chat.events/new-chat-focus] + ;;TODO accessories + :options {:topBar {:visible false}} + :component new-chat/new-chat} - ;[Chat] New Public chat - {:name :new-public-chat - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}} - :component new-public-chat/new-public-chat} + ;[Chat] New Public chat + {:name :new-public-chat + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}} + :component new-public-chat/new-public-chat} - ;[Chat] Link preview settings - {:name :link-preview-settings - :options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}} - :component link-previews-settings/link-previews-settings} + ;[Chat] Link preview settings + {:name :link-preview-settings + :options {:topBar {:title {:text (i18n/label :t/chat-link-previews)}}} + :component link-previews-settings/link-previews-settings} - ;[Chat] Edit nickname - {:name :nickname - :insets {:bottom true} - ;;TODO dyn subtitle - :options {:topBar {:visible false}} - :component contact/nickname} + ;[Chat] Edit nickname + {:name :nickname + :insets {:bottom true} + ;;TODO dyn subtitle + :options {:topBar {:visible false}} + :component contact/nickname} - ;[Group chat] Edit group chat name - {:name :edit-group-chat-name - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/edit-group)}}} - :component group-chat/edit-group-chat-name} + ;[Group chat] Edit group chat name + {:name :edit-group-chat-name + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/edit-group)}}} + :component group-chat/edit-group-chat-name} - ;[Group chat] Add participants - {:name :add-participants-toggle-list - :on-focus [:group/add-participants-toggle-list] - :insets {:bottom true} - ;;TODO dyn subtitle - :options {:topBar {:visible false}} - :component group-chat/add-participants-toggle-list} + ;[Group chat] Add participants + {:name :add-participants-toggle-list + :on-focus [:group/add-participants-toggle-list] + :insets {:bottom true} + ;;TODO dyn subtitle + :options {:topBar {:visible false}} + :component group-chat/add-participants-toggle-list} - ;[Communities] Invite people - {:name :invite-people-community - ;;TODO dyn title - :options {:topBar {:visible false}} - :component communities.invite/invite - :insets {:bottom true}} + ;[Communities] Invite people + {:name :invite-people-community + ;;TODO dyn title + :options {:topBar {:visible false}} + :component communities.invite/invite + :insets {:bottom true}} - ;New Contact - {:name :new-contact - :on-focus [::new-chat.events/new-chat-focus] - ;;TODO accessories - :options {:topBar {:visible false}} - :component new-chat/new-contact} + ;New Contact + {:name :new-contact + :on-focus [::new-chat.events/new-chat-focus] + ;;TODO accessories + :options {:topBar {:visible false}} + :component new-chat/new-contact} - ;[Wallet] Recipient - {:name :recipient - :insets {:bottom true} - ;;TODO accessories - :options {:topBar {:visible false}} - :component recipient/recipient} + ;[Wallet] Recipient + {:name :recipient + :insets {:bottom true} + ;;TODO accessories + :options {:topBar {:visible false}} + :component recipient/recipient} - ;[Wallet] New favourite - {:name :new-favourite - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/new-favourite)}}} - :component recipient/new-favourite} + ;[Wallet] New favourite + {:name :new-favourite + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/new-favourite)}}} + :component recipient/new-favourite} - ;QR Scanner - {:name :qr-scanner - :insets {:top false :bottom false} - ;;TODO custom topbar - :options {:topBar {:visible false} - :navigationBar {:backgroundColor colors/black-persist} - :statusBar {:backgroundColor colors/black-persist - :style :light}} - :component qr-scanner/qr-scanner} + ;QR Scanner + {:name :qr-scanner + :insets {:top false :bottom false} + ;;TODO custom topbar + :options {:topBar {:visible false} + :navigationBar {:backgroundColor colors/black-persist} + :statusBar {:backgroundColor colors/black-persist + :style :light}} + :component qr-scanner/qr-scanner} - ;;TODO WHY MODAL? - ;[Profile] Notifications settings - {:name :notifications-settings - :options {:topBar {:title {:text (i18n/label :t/notification-settings)}} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component notifications-settings/notifications-settings} + ;;TODO WHY MODAL? + ;[Profile] Notifications settings + {:name :notifications-settings + :options {:topBar {:title {:text (i18n/label :t/notification-settings)}} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component notifications-settings/notifications-settings} - ;;TODO WHY MODAL? - ;[Profile] Notifications Advanced settings - {:name :notifications-advanced-settings - :options {:topBar {:title {:text (i18n/label :t/notification-settings)}} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :insets {:bottom true} - :component notifications-settings/notifications-advanced-settings} + ;;TODO WHY MODAL? + ;[Profile] Notifications Advanced settings + {:name :notifications-advanced-settings + :options {:topBar {:title {:text (i18n/label :t/notification-settings)}} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :insets {:bottom true} + :component notifications-settings/notifications-advanced-settings} - ;[Wallet] Prepare Transaction - {:name :prepare-send-transaction - :insets {:bottom true} - :on-dissmiss [:wallet/cancel-transaction-command] - :options {:topBar {:title {:text (i18n/label :t/send-transaction)}} - :swipeToDismiss false - :hardwareBackButton {:dismissModalOnPress false}} - :component wallet.send/prepare-send-transaction} + ;[Wallet] Prepare Transaction + {:name :prepare-send-transaction + :insets {:bottom true} + :on-dissmiss [:wallet/cancel-transaction-command] + :options {:topBar {:title {:text (i18n/label :t/send-transaction)}} + :swipeToDismiss false + :hardwareBackButton {:dismissModalOnPress false}} + :component wallet.send/prepare-send-transaction} - ;[Wallet] Request Transaction - {:name :request-transaction - :insets {:bottom true} - :on-dissmiss [:wallet/cancel-transaction-command] - :options {:topBar {:title {:text (i18n/label :t/request-transaction)}} - :swipeToDismiss false - :hardwareBackButton {:dismissModalOnPress false}} - :component wallet.send/request-transaction} + ;[Wallet] Request Transaction + {:name :request-transaction + :insets {:bottom true} + :on-dissmiss [:wallet/cancel-transaction-command] + :options {:topBar {:title {:text (i18n/label :t/request-transaction)}} + :swipeToDismiss false + :hardwareBackButton {:dismissModalOnPress false}} + :component wallet.send/request-transaction} - ;[Wallet] Buy crypto - {:name :buy-crypto - :insets {:bottom true} - :component wallet.buy-crypto/container} + ;[Wallet] Buy crypto + {:name :buy-crypto + :insets {:bottom true} + :component wallet.buy-crypto/container} - ;[Wallet] Buy crypto website - {:name :buy-crypto-website - :insets {:bottom true} - ;;TODO subtitle - :options {:topBar {:visible false}} - :component wallet.buy-crypto/website} + ;[Wallet] Buy crypto website + {:name :buy-crypto-website + :insets {:bottom true} + ;;TODO subtitle + :options {:topBar {:visible false}} + :component wallet.buy-crypto/website} - {:name :nft-details - :insets {:bottom true} - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component wallet.collectibles/nft-details-modal} + {:name :nft-details + :insets {:bottom true} + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component wallet.collectibles/nft-details-modal} - ;My Status - {:name :my-status - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/my-status)}}} - :component status.new/my-status} + ;My Status + {:name :my-status + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/my-status)}}} + :component status.new/my-status} - ;[Browser] New bookmark - {:name :new-bookmark - :insets {:bottom true} - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component bookmarks/new-bookmark} + ;[Browser] New bookmark + {:name :new-bookmark + :insets {:bottom true} + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component bookmarks/new-bookmark} - ;Profile - {:name :profile - :insets {:bottom true} - ;;TODO custom toolbar - :options {:topBar {:visible false}} - :component contact/profile} + ;Profile + {:name :profile + :insets {:bottom true} + ;;TODO custom toolbar + :options {:topBar {:visible false}} + :component contact/profile} - ;KEYCARD - {:name :keycard-onboarding-intro - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.onboarding/intro} - {:name :keycard-onboarding-puk-code - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - ;;TODO dynamic - :component keycard.onboarding/puk-code} - {:name :keycard-onboarding-pin - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - ;;TODO dynamic - :component keycard.onboarding/pin} - {:name :keycard-recovery-pair - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/step-i-of-n {:number 2 :step 1})}} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.recovery/pair} - {:name :seed-phrase - :insets {:bottom true} - ;;TODO subtitle - :options {:topBar {:visible false}} - :component key-storage.views/seed-phrase} - {:name :keycard-recovery-pin - :insets {:bottom true} - ;;TODO dynamic - :options {:topBar {:visible false}} - :component keycard.recovery/pin} - {:name :keycard-wrong - :insets {:bottom true} - ;;TODO move to popover? - :options {:topBar {:visible false}} - :component keycard/wrong} - {:name :not-keycard - :insets {:bottom true} - :options {:topBar {:visible false}} - ;;TODO move to popover? - :component keycard/not-keycard} - {:name :keycard-onboarding-recovery-phrase - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.onboarding/recovery-phrase} - {:name :keycard-onboarding-recovery-phrase-confirm-word1 - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.onboarding/recovery-phrase-confirm-word} - {:name :keycard-onboarding-recovery-phrase-confirm-word2 - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.onboarding/recovery-phrase-confirm-word} - {:name :keycard-recovery-intro - :insets {:bottom true} - :component keycard.recovery/intro} - {:name :keycard-recovery-success - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.recovery/success} - {:name :keycard-recovery-no-key - :insets {:bottom true} - :options {:topBar {:visible false} - :popGesture false - :hardwareBackButton {:dismissModalOnPress false - :popStackOnPress false}} - :component keycard.recovery/no-key} - {:name :keycard-authentication-method - :insets {:bottom true} - :options {:topBar {:visible false}} - :component keycard.authentication/keycard-authentication-method} - {:name :keycard-login-pin - :insets {:bottom true} - :options {:topBar {:visible false}} - :component keycard/login-pin} - {:name :keycard-blank - :insets {:bottom true} - :options {:topBar {:visible false}} - :component keycard/blank} - {:name :keycard-unpaired - :insets {:bottom true} - :options {:topBar {:visible false}} - :component keycard/unpaired} - {:name :keycard-settings - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/status-keycard)}}} - :component keycard.settings/keycard-settings} - {:name :reset-card - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/reset-card)}}} - :component keycard.settings/reset-card} - {:name :keycard-pin - :insets {:bottom true} - ;;TODO dynamic title - :options {:topBar {:visible false}} - :component keycard.settings/reset-pin} - {:name :enter-pin-settings - :insets {:bottom true} - :component keycard.pin/enter-pin} - {:name :change-pairing-code - :insets {:bottom true} - :component keycard.pairing/change-pairing-code} + ;KEYCARD + {:name :keycard-onboarding-intro + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.onboarding/intro} + {:name :keycard-onboarding-puk-code + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + ;;TODO dynamic + :component keycard.onboarding/puk-code} + {:name :keycard-onboarding-pin + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + ;;TODO dynamic + :component keycard.onboarding/pin} + {:name :keycard-recovery-pair + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/step-i-of-n {:number 2 :step 1})}} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.recovery/pair} + {:name :seed-phrase + :insets {:bottom true} + ;;TODO subtitle + :options {:topBar {:visible false}} + :component key-storage.views/seed-phrase} + {:name :keycard-recovery-pin + :insets {:bottom true} + ;;TODO dynamic + :options {:topBar {:visible false}} + :component keycard.recovery/pin} + {:name :keycard-wrong + :insets {:bottom true} + ;;TODO move to popover? + :options {:topBar {:visible false}} + :component keycard/wrong} + {:name :not-keycard + :insets {:bottom true} + :options {:topBar {:visible false}} + ;;TODO move to popover? + :component keycard/not-keycard} + {:name :keycard-onboarding-recovery-phrase + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.onboarding/recovery-phrase} + {:name :keycard-onboarding-recovery-phrase-confirm-word1 + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.onboarding/recovery-phrase-confirm-word} + {:name :keycard-onboarding-recovery-phrase-confirm-word2 + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.onboarding/recovery-phrase-confirm-word} + {:name :keycard-recovery-intro + :insets {:bottom true} + :component keycard.recovery/intro} + {:name :keycard-recovery-success + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.recovery/success} + {:name :keycard-recovery-no-key + :insets {:bottom true} + :options {:topBar {:visible false} + :popGesture false + :hardwareBackButton {:dismissModalOnPress false + :popStackOnPress false}} + :component keycard.recovery/no-key} + {:name :keycard-authentication-method + :insets {:bottom true} + :options {:topBar {:visible false}} + :component keycard.authentication/keycard-authentication-method} + {:name :keycard-login-pin + :insets {:bottom true} + :options {:topBar {:visible false}} + :component keycard/login-pin} + {:name :keycard-blank + :insets {:bottom true} + :options {:topBar {:visible false}} + :component keycard/blank} + {:name :keycard-unpaired + :insets {:bottom true} + :options {:topBar {:visible false}} + :component keycard/unpaired} + {:name :keycard-settings + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/status-keycard)}}} + :component keycard.settings/keycard-settings} + {:name :reset-card + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :t/reset-card)}}} + :component keycard.settings/reset-card} + {:name :keycard-pin + :insets {:bottom true} + ;;TODO dynamic title + :options {:topBar {:visible false}} + :component keycard.settings/reset-pin} + {:name :enter-pin-settings + :insets {:bottom true} + :component keycard.pin/enter-pin} + {:name :change-pairing-code + :insets {:bottom true} + :component keycard.pairing/change-pairing-code} - ;;KEYSTORAGE - {:name :actions-not-logged-in - ;;TODO: topbar - :insets {:bottom true} - :options {:topBar {:visible false}} - ;;TODO move to popover? - :component key-storage.views/actions-not-logged-in} - {:name :actions-logged-in - ;;TODO: topbar - :options {:topBar {:visible false}} - :insets {:bottom true} - ;;TODO move to popover? - :component key-storage.views/actions-logged-in} - {:name :storage - ;;TODO: topbar - :options {:topBar {:visible false}} - :insets {:bottom true} - ;;TODO move to popover? - :component key-storage.views/storage} + ;;KEYSTORAGE + {:name :actions-not-logged-in + ;;TODO: topbar + :insets {:bottom true} + :options {:topBar {:visible false}} + ;;TODO move to popover? + :component key-storage.views/actions-not-logged-in} + {:name :actions-logged-in + ;;TODO: topbar + :options {:topBar {:visible false}} + :insets {:bottom true} + ;;TODO move to popover? + :component key-storage.views/actions-logged-in} + {:name :storage + ;;TODO: topbar + :options {:topBar {:visible false}} + :insets {:bottom true} + ;;TODO move to popover? + :component key-storage.views/storage} - {:name :show-all-connections - :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :all-connections)}}} - :component manage-all-connections/views} + {:name :show-all-connections + :insets {:bottom true} + :options {:topBar {:title {:text (i18n/label :all-connections)}}} + :component manage-all-connections/views} - ;; BUG REPORT - {:name :bug-report - :options {:topBar {:visible false}} - :component bug-report/bug-report}] - - navigation2.screens/screens - (when config/quo-preview-enabled? - quo.preview/screens) - (when config/quo-preview-enabled? - quo.preview/main-screens) - (when config/quo-preview-enabled? - quo2.preview/screens) - (when config/new-ui-enabled? - navigation2.screens/screen-overwrites) - (when config/quo-preview-enabled? - quo2.preview/main-screens))) + ;; BUG REPORT + {:name :bug-report + :options {:topBar {:visible false}} + :component bug-report/bug-report}]) diff --git a/src/status_im/ui2/screens/chat/home.cljs b/src/status_im/ui2/screens/chat/home.cljs index bae7b8d997..fd65f3b5eb 100644 --- a/src/status_im/ui2/screens/chat/home.cljs +++ b/src/status_im/ui2/screens/chat/home.cljs @@ -17,7 +17,6 @@ [status-im.utils.utils :as utils] [status-im.ui.components.topbar :as topbar] [status-im.ui.components.plus-button :as components.plus-button] - [status-im.ui.components.tabbar.core :as tabbar] [status-im.ui.components.invite.views :as invite] [status-im.utils.handlers :refer [evt]] [status-im.utils.config :as config] @@ -377,6 +376,5 @@ :margin-bottom 20} [quo2.text/text {:size :heading-1 :weight :semi-bold} (i18n/label :t/messages)] [plus-button]] - [chats-list] - [tabbar/tabs-counts-subscriptions]])]) + [chats-list]])]) diff --git a/src/status_im/ui2/screens/chat/messages/message.cljs b/src/status_im/ui2/screens/chat/messages/message.cljs index 14fc62e037..9b43503063 100644 --- a/src/status_im/ui2/screens/chat/messages/message.cljs +++ b/src/status_im/ui2/screens/chat/messages/message.cljs @@ -439,7 +439,7 @@ (when pinned (pin-message message)) (re-frame/dispatch [:chat.ui/delete-message-for-me message - config/delete-message-for-me-undo-time-limit-ms])) + constants/delete-message-for-me-undo-time-limit-ms])) :label (i18n/label :t/delete-for-me) :icon :i/delete :id :delete-for-me}] @@ -590,7 +590,7 @@ [{:type :danger :on-press #(re-frame/dispatch [:chat.ui/delete-message-for-me message - config/delete-message-for-me-undo-time-limit-ms]) + constants/delete-message-for-me-undo-time-limit-ms]) :label (i18n/label :t/delete-for-me) :icon :i/delete-context20 :id :delete-for-me}] @@ -627,7 +627,7 @@ {:type :danger :on-press #(re-frame/dispatch [:chat.ui/delete-message-for-me message - config/delete-message-for-me-undo-time-limit-ms]) + constants/delete-message-for-me-undo-time-limit-ms]) :label (i18n/label :t/delete-for-me) :icon :i/delete-context20 :id :delete-for-me} diff --git a/src/status_im/ui2/screens/chat/view.cljs b/src/status_im/ui2/screens/chat/view.cljs index 3b7cdcf9f9..d5745c01c3 100644 --- a/src/status_im/ui2/screens/chat/view.cljs +++ b/src/status_im/ui2/screens/chat/view.cljs @@ -8,7 +8,7 @@ [quo2.components.buttons.button :as quo2.button] [quo2.foundations.colors :as colors] [status-im.ui.components.react :as react] - [status-im.navigation.state :as navigation.state] + [status-im2.navigation.state :as navigation.state] [status-im.ui2.screens.chat.messages.view :as messages] [status-im.utils.handlers :refer [evt]] [status-im.ui.components.icons.icons :as icons] diff --git a/src/status_im/utils/config.cljs b/src/status_im/utils/config.cljs index f3b4c16893..561832f9fe 100644 --- a/src/status_im/utils/config.cljs +++ b/src/status_im/utils/config.cljs @@ -3,7 +3,8 @@ [clojure.string :as string] [status-im.ethereum.core :as ethereum] [status-im.ethereum.ens :as ens])) - +;;TODO (14/11/22 flexsurfer) this namespace has been moved to the status-im2 namespace, we keep this only for old (status 1.0) code, +;; can be removed with old code later (def config (memoize (fn [] @@ -15,9 +16,6 @@ (defn enabled? [v] (= "1" v)) -;; NOTE(oskarth): Feature flag deprecation lifecycles. We want to make sure -;; flags stay up to date and are removed once behavior introduced is stable. - (goog-define POKT_TOKEN "3ef2018191814b7e1009b8d9") (goog-define OPENSEA_API_KEY "") @@ -151,5 +149,3 @@ ;; TODO: Remove this (highly) temporary flag once the new Activity Center is ;; usable enough to replace the old one **in the new UI**. (def new-activity-center-enabled? false) - -(def delete-message-for-me-undo-time-limit-ms 4000) diff --git a/src/status_im/utils/core.cljc b/src/status_im/utils/core.cljc index 4a3d877690..9575e6294b 100644 --- a/src/status_im/utils/core.cljc +++ b/src/status_im/utils/core.cljc @@ -1,5 +1,4 @@ -(ns status-im.utils.core - (:require [clojure.string :as string])) +(ns status-im.utils.core) (defn truncate-str-memo "Given string and max threshold, trims the string to threshold length with `...` @@ -20,12 +19,6 @@ (def truncate-str (memoize truncate-str-memo)) -(defn clean-text [s] - (-> s - (string/replace #"\n" "") - (string/replace #"\r" "") - (string/trim))) - (defn first-index "Returns first index in coll where predicate on coll element is truthy" [pred coll] @@ -35,31 +28,6 @@ idx))) first)) -(defn hash-tag? [s] - (= \# (first s))) - -(defn update-if-present - "Like regular `clojure.core/update` but returns original map if update key is not present" - [m k f & args] - (if (contains? m k) - (apply update m k f args) - m)) - -(defn map-values - "Efficiently apply function to all map values" - [f m] - (into {} - (map (fn [[k v]] - [k (f v)])) - m)) - -(defn deep-merge - "Recursively merge maps" - [& maps] - (if (every? map? maps) - (apply merge-with deep-merge maps) - (last maps))) - (defn index-by "Given a collection and a unique key function, returns a map that indexes the collection. Similar to group-by except that the map values are single objects (depends on key uniqueness)." diff --git a/src/status_im/utils/db.cljs b/src/status_im/utils/db.cljs index c23bbc6708..b81a3e1704 100644 --- a/src/status_im/utils/db.cljs +++ b/src/status_im/utils/db.cljs @@ -1,9 +1,4 @@ -(ns status-im.utils.db - (:require [cljs.spec.alpha :as spec])) +(ns status-im.utils.db) (defn valid-public-key? [s] - (boolean (re-matches #"0x04[0-9a-f]{128}" s))) - -(spec/def :global/not-empty-string (spec/and string? not-empty)) -(spec/def :global/public-key (spec/and :global/not-empty-string valid-public-key?)) - + (and (string? s) (not-empty s) (boolean (re-matches #"0x04[0-9a-f]{128}" s)))) \ No newline at end of file diff --git a/src/status_im/utils/dimensions.cljs b/src/status_im/utils/dimensions.cljs index 2c135d9484..c85cc90f81 100644 --- a/src/status_im/utils/dimensions.cljs +++ b/src/status_im/utils/dimensions.cljs @@ -2,13 +2,10 @@ (:require [re-frame.core :as re-frame] [status-im.ui.components.react :as react])) -(declare window) - (defn add-event-listener [] (.addEventListener ^js react/dimensions "change" - #(do - (re-frame/dispatch [:update-window-dimensions %])))) + #(re-frame/dispatch-sync [:update-window-dimensions %]))) (defn window ([] diff --git a/src/status_im/utils/logging/core.cljs b/src/status_im/utils/logging/core.cljs index 7ba8d7ffde..cd433e321d 100644 --- a/src/status_im/utils/logging/core.cljs +++ b/src/status_im/utils/logging/core.cljs @@ -1,5 +1,5 @@ (ns status-im.utils.logging.core - (:require ["react-native-mail" :default react-native-mail] + (:require [react-native.mail :as react-native-mail] [clojure.string :as string] [goog.string :as gstring] [re-frame.core :as re-frame] @@ -9,54 +9,22 @@ [status-im.transport.utils :as transport.utils] [status-im.ui.components.react :as react] [status-im.utils.build :as build] - [status-im.utils.config :as config] [status-im.utils.datetime :as datetime] [status-im.utils.fx :as fx] [status-im.utils.platform :as platform] [status-im.utils.types :as types] - [taoensso.timbre :as log])) + [status-im2.setup.log :as log])) (def report-email "error-reports@status.im") -(def max-log-entries 1000) -(def logs-queue (atom #queue[])) -(defn add-log-entry [entry] - (swap! logs-queue conj entry) - (when (>= (count @logs-queue) max-log-entries) - (swap! logs-queue pop))) - -(defn init-logs [level] - (when-not (string/blank? level) - (log/set-level! (-> level - string/lower-case - keyword)) - (log/merge-config! - {:output-fn (fn [& data] - (let [res (apply log/default-output-fn data)] - (add-log-entry res) - res))}))) - -(defn get-js-logs [] - (string/join "\n" @logs-queue)) (re-frame/reg-fx :logs/archive-logs (fn [[db-json callback-handler]] (status/send-logs db-json - (get-js-logs) + (string/join "\n" (log/get-logs-queue)) #(re-frame/dispatch [callback-handler %])))) -(re-frame/reg-fx - :logs/set-level - (fn [level] - (init-logs level))) - -(fx/defn set-log-level - [{:keys [db]} log-level] - (let [log-level (or log-level config/log-level)] - {:db (assoc-in db [:multiaccount :log-level] log-level) - :logs/set-level log-level})) - (defn email-body "logs attached" [{:keys [:web3-node-version :mailserver/current-id @@ -188,9 +156,8 @@ (re-frame/reg-fx :email/send - ;; https://github.com/chirag04/react-native-mail#example (fn [[opts callback]] - (.mail react-native-mail (clj->js opts) callback))) + (react-native-mail/mail (clj->js opts) callback))) (re-frame/reg-fx ::share-archive diff --git a/src/status_im/utils/number.cljs b/src/status_im/utils/number.cljs deleted file mode 100644 index b160f3b7c2..0000000000 --- a/src/status_im/utils/number.cljs +++ /dev/null @@ -1,75 +0,0 @@ -(ns status-im.utils.number - (:require [goog.string :as gstring] - [goog.string.format])) - -(defn naive-round - "Quickly and naively round number `n` up to `decimal-places`. - - Example usage: use it to avoid re-renders caused by floating-point number - changes in Reagent atoms. Such numbers can be rounded up to a certain number - of `decimal-places` in order to avoid re-rendering due to tiny fractional - changes. - - Don't use this function for arbitrary-precision arithmetic." - [n decimal-places] - (let [scale (Math/pow 10 decimal-places)] - (/ (Math/round (* n scale)) - scale))) - -(defn- caught-invalid-number [] - (throw (js/Error "Invalid Number"))) - -(defn- with-precision [precision input-number] - (gstring/format (str "%." precision "f") input-number)) - -(defn- is-bad-number [number-string] - (nil? (re-find #"^\d+(\.\d{1,9})?$" number-string))) - -(defn- with-precision-division [numerator-num denominator-num precision] - (->> (/ numerator-num denominator-num) - (with-precision precision))) - -(defn- number->formatted-number [number-string precision] - (let [parsed-number (js/parseInt number-string 10) - numeric-value (if (or (neg? number-string) - (is-bad-number (str number-string))) - (caught-invalid-number) - parsed-number) - million 1000000 - billion 1000000000 - >=-and-< #(and - (>= %1 %2) - (< %1 %3)) - unit (cond - (>=-and-< parsed-number billion js/Number.MAX_SAFE_INTEGER) "b" - (>=-and-< parsed-number million billion) "m" - :else - "k") - denominator (cond - (= unit "m") million - (= unit "b") billion - :else 1000)] - (if (js/isNaN numeric-value) - (caught-invalid-number) - (if (>= numeric-value 1000) - (str (with-precision-division numeric-value denominator precision) - unit) - (str numeric-value))))) - -(defn format-number - "Returns the thousands in a number in kilo format - - Arguments: - - number-string (or string int) The input of value of the number - - Examples: - [1000 0] -> 1k - [1001 0] -> 1k - [10000 0] -> 10k - [5000 0] -> 5k - [5000 0] -> 5k - [5000000 0] -> 5m - [5000 0] -> 5k" - [number-string precision] - (number->formatted-number number-string precision)) diff --git a/src/status_im/utils/number_test.cljs b/src/status_im/utils/number_test.cljs deleted file mode 100644 index c50480d725..0000000000 --- a/src/status_im/utils/number_test.cljs +++ /dev/null @@ -1,27 +0,0 @@ -(ns status-im.utils.number-test - (:require [cljs.test :refer-macros [deftest testing are]] - [status-im.utils.number :as number])) - -(deftest format-number-test - (testing "Positive cases" - (are [input-number precision expected] (= (number/format-number input-number precision) expected) - "100" 0 "100" - "1000" 0 "1k" - "10000" 0 "10k" - "11000" 1 "11.0k" - "11000" 0 "11k" - "11010" 3 "11.010k" - "5200000" 3 "5.200m" - "1000000000" 0 "1b" - "1110000000" 2 "1.11b" - "9000000" 0 "9m")) - (testing "Negative cases" - (are [input-number precision] (thrown-with-msg? js/Error #"Invalid Number" (number/format-number input-number precision)) - js/undefined 0 - nil 0 - "-1" 0 - "" 0 - js/NaN 0 - "1e3" 0 - "10,2" 0 - "6hello" 0))) diff --git a/src/status_im/utils/theme.cljs b/src/status_im/utils/theme.cljs deleted file mode 100644 index 5c686021f8..0000000000 --- a/src/status_im/utils/theme.cljs +++ /dev/null @@ -1,16 +0,0 @@ -(ns status-im.utils.theme - (:require ["react-native" :refer (Appearance)] - [oops.core :refer [ocall]])) - -(def initial-mode (atom (ocall Appearance "getColorScheme"))) - -;; Note - don't use value returned by change listener -;; https://github.com/facebook/react-native/issues/28525 -(defn add-mode-change-listener [callback] - (ocall Appearance "addChangeListener" #(let [mode (ocall Appearance "getColorScheme")] - (when-not (= mode @initial-mode) - (reset! initial-mode mode) - (callback (keyword mode)))))) - -(defn is-dark-mode [] - (= @initial-mode "dark")) diff --git a/src/status_im/utils/universal_links/core.cljs b/src/status_im/utils/universal_links/core.cljs index 46648d7925..ae7cf61ee5 100644 --- a/src/status_im/utils/universal_links/core.cljs +++ b/src/status_im/utils/universal_links/core.cljs @@ -10,7 +10,7 @@ [status-im.ethereum.core :as ethereum] [status-im.ui.components.react :as react] [status-im.add-new.db :as new-chat.db] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [taoensso.timbre :as log] [status-im.wallet.choose-recipient.core :as choose-recipient] diff --git a/src/status_im/utils/utils.cljs b/src/status_im/utils/utils.cljs index 8edc331bd4..9983820ee8 100644 --- a/src/status_im/utils/utils.cljs +++ b/src/status_im/utils/utils.cljs @@ -2,12 +2,14 @@ (:require [clojure.string :as string] [goog.string :as gstring] [status-im.i18n.i18n :as i18n] - [re-frame.core :as re-frame] [status-im.ethereum.eip55 :as eip55] [status-im.ethereum.core :as ethereum] ["react-native" :as react-native] - ["react-native-background-timer" :default background-timer])) + ["react-native-background-timer" :default background-timer] + [re-frame.core :as re-frame])) +;;TODO (14/11/22 flexsurfer) .-Alert usage code has been moved to the status-im2 namespace, we keep this only for old (status 1.0) code, +;; can be removed with old code later (defn show-popup ([title content] (show-popup title content nil)) @@ -23,14 +25,6 @@ (when on-dismiss (clj->js {:cancelable false}))))) -(defn vibrate [] - #_(.vibrate (.-Vibration react-native))) - -(re-frame/reg-fx - :utils/show-popup - (fn [{:keys [title content on-dismiss]}] - (show-popup title content on-dismiss))) - (defn show-confirmation [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text extra-options]}] @@ -51,17 +45,6 @@ (or extra-options nil))) #js {:cancelable false})) -(re-frame/reg-fx - :utils/show-confirmation - (fn [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text extra-options]}] - (show-confirmation {:title title - :content content - :confirm-button-text confirm-button-text - :cancel-button-text cancel-button-text - :on-accept on-accept - :on-cancel on-cancel - :extra-options extra-options}))) - (defn show-question ([title content on-accept] (show-question title content on-accept nil)) @@ -77,6 +60,36 @@ :onPress on-accept :accessibility-label :yes-button}))))) +;;TODO (14/11/22 flexsurfer) background-timer usage code has been moved to the status-im2 namespace, we keep this only for old (status 1.0) code, +;; can be removed with old code later + +(defn set-timeout [cb ms] + (.setTimeout background-timer cb ms)) + +(defn clear-timeout [id] + (.clearTimeout background-timer id)) + +(defn set-interval [cb ms] + (.setInterval background-timer cb ms)) + +(defn clear-interval [id] + (.clearInterval background-timer id)) + +(re-frame/reg-fx + :utils/dispatch-later + (fn [params] + (doseq [{:keys [ms dispatch]} params] + (when (and ms dispatch) + (set-timeout #(re-frame/dispatch dispatch) ms))))) + +(re-frame/reg-fx + ::clear-timeouts + (fn [ids] + (doseq [id ids] + (when id + (clear-timeout id))))) + +;;TODO (14/11/22 flexsurfer) haven't moved yet (defn get-shortened-address "Takes first and last 4 digits from address including leading 0x and adds unicode ellipsis in between" @@ -88,36 +101,6 @@ (when address (get-shortened-address (eip55/address->checksum (ethereum/normalized-hex address))))) -;; background-timer - -(defn set-timeout [cb ms] - (.setTimeout background-timer cb ms)) - -;; same as re-frame dispatch-later but using background timer for long -;; running timeouts -(re-frame/reg-fx - :utils/dispatch-later - (fn [params] - (doseq [{:keys [ms dispatch]} params] - (when (and ms dispatch) - (set-timeout #(re-frame/dispatch dispatch) ms))))) - -(defn clear-timeout [id] - (.clearTimeout background-timer id)) - -(re-frame/reg-fx - ::clear-timeouts - (fn [ids] - (doseq [id ids] - (when id - (clear-timeout id))))) - -(defn set-interval [cb ms] - (.setInterval background-timer cb ms)) - -(defn clear-interval [id] - (.clearInterval background-timer id)) - (defn format-decimals [amount places] (let [decimal-part (get (string/split (str amount) ".") 1)] (if (> (count decimal-part) places) diff --git a/src/status_im/utils/utils_test.cljs b/src/status_im/utils/utils_test.cljs index 99799baec8..ae0ffe216d 100644 --- a/src/status_im/utils/utils_test.cljs +++ b/src/status_im/utils/utils_test.cljs @@ -9,38 +9,12 @@ (is (= (u/truncate-str "Long string" 11) "Long string")) ; threshold is the same as string length (is (= (u/truncate-str "Long string" 20) "Long string"))) ; threshold is more then string length -(deftest clean-text-test - (is (= (u/clean-text "Hello! \n\r") "Hello!") - (= (u/clean-text "Hello!") "Hello!"))) - (deftest first-index-test (is (= 2 (u/first-index (partial = :test) '(:a :b :test :c :test)))) (is (= nil (u/first-index (partial = :test) '(:a :b :c))))) -(deftest hash-tag?-test - (is (u/hash-tag? "#clojure")) - (is (not (u/hash-tag? "clojure"))) - (is (not (u/hash-tag? "clo#jure"))) - (is (not (u/hash-tag? "clojure#")))) - -(deftest update-if-present-test - (is (= {:a 1} (u/update-if-present {:a 0} :a inc))) - (is (= {:a 2} (u/update-if-present {:a 0} :a + 2))) - (is (= {:a 0} (u/update-if-present {:a 0} :b inc)))) - -(deftest map-values-test - (is (= {} (u/map-values inc {}))) - (is (= {:a 1} (u/map-values inc {:a 0}))) - (is (= {:a 1 :b 2} (u/map-values inc {:a 0 :b 1})))) - -(deftest deep-merge-test - (is (= {} (u/deep-merge {} {}))) - (is (= {:a 1 :b 2} (u/deep-merge {:a 1} {:b 2}))) - (is (= {:a {:b 1 :c 2}} (u/deep-merge {:a {:b 1 :c 1}} {:a {:c 2}}))) - (is (= {:a {:b {:c 2}} :d 1} (u/deep-merge {:a {:b {:c 1}} :d 1} {:a {:b {:c 2}}})))) - (deftest format-decimals-test (is (= "1" (uu/format-decimals 1 5))) (is (= "1.1" (uu/format-decimals 1.1 5))) diff --git a/src/status_im/waku/core.cljs b/src/status_im/waku/core.cljs index 628b860c68..4fef210f8c 100644 --- a/src/status_im/waku/core.cljs +++ b/src/status_im/waku/core.cljs @@ -4,7 +4,7 @@ [status-im.i18n.i18n :as i18n] [status-im.multiaccounts.update.core :as multiaccounts.update] [status-im.node.core :as node] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx])) (fx/defn switch-waku-bloom-filter-mode diff --git a/src/status_im/wallet/accounts/core.cljs b/src/status_im/wallet/accounts/core.cljs index 31f6108682..eb27fc7d37 100644 --- a/src/status_im/wallet/accounts/core.cljs +++ b/src/status_im/wallet/accounts/core.cljs @@ -10,7 +10,7 @@ [status-im.native-module.core :as status] [quo.design-system.colors :as colors] [status-im.ui.components.list-selection :as list-selection] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.fx :as fx] [status-im.utils.types :as types] [status-im.wallet.core :as wallet] diff --git a/src/status_im/wallet/choose_recipient/core.cljs b/src/status_im/wallet/choose_recipient/core.cljs index 1d34f19766..db0b77be72 100644 --- a/src/status_im/wallet/choose_recipient/core.cljs +++ b/src/status_im/wallet/choose_recipient/core.cljs @@ -6,7 +6,7 @@ [status-im.ethereum.eip681 :as eip681] [status-im.ethereum.ens :as ens] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.qr-scanner.core :as qr-scaner] [status-im.router.core :as router] [status-im.utils.fx :as fx] diff --git a/src/status_im/wallet/core.cljs b/src/status_im/wallet/core.cljs index 78187309f3..7122ae2415 100644 --- a/src/status_im/wallet/core.cljs +++ b/src/status_im/wallet/core.cljs @@ -8,7 +8,7 @@ [status-im.ethereum.json-rpc :as json-rpc] [status-im.ethereum.tokens :as tokens] [status-im.i18n.i18n :as i18n] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.utils.core :as utils.core] [status-im.utils.fx :as fx] [status-im.utils.money :as money] diff --git a/src/status_im/wallet/custom_tokens/core.cljs b/src/status_im/wallet/custom_tokens/core.cljs index db67c1d523..4845d0c92b 100644 --- a/src/status_im/wallet/custom_tokens/core.cljs +++ b/src/status_im/wallet/custom_tokens/core.cljs @@ -8,7 +8,7 @@ [status-im.ui.components.react :as react] [status-im.utils.fx :as fx] [status-im.wallet.core :as wallet] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.wallet.prices :as prices])) (re-frame/reg-fx diff --git a/src/status_im/wallet/recipient/core.cljs b/src/status_im/wallet/recipient/core.cljs index b0d62be6d2..a860353172 100644 --- a/src/status_im/wallet/recipient/core.cljs +++ b/src/status_im/wallet/recipient/core.cljs @@ -10,7 +10,7 @@ [status-im.ethereum.eip55 :as eip55] [status-im.i18n.i18n :as i18n] [status-im.ethereum.stateofus :as stateofus] - [status-im.navigation :as navigation] + [status-im2.navigation.events :as navigation] [status-im.ethereum.json-rpc :as json-rpc])) ;;NOTE we want to handle only last resolve diff --git a/src/status_im/wallet/swap/core.cljs b/src/status_im/wallet/swap/core.cljs index 4a1675455d..ea2214d9f5 100644 --- a/src/status_im/wallet/swap/core.cljs +++ b/src/status_im/wallet/swap/core.cljs @@ -1,7 +1,7 @@ (ns status-im.wallet.swap.core (:require [status-im.utils.fx :as fx] [re-frame.db :as re-frame.db] - [status-im.navigation :as navigation])) + [status-im2.navigation.events :as navigation])) (fx/defn open-asset-selector-modal "source? true signinfies we are selecting the source asset. false implies selection of sink asset" diff --git a/src/status_im2/common/alert/events.cljs b/src/status_im2/common/alert/events.cljs new file mode 100644 index 0000000000..d74b116c26 --- /dev/null +++ b/src/status_im2/common/alert/events.cljs @@ -0,0 +1,68 @@ +(ns status-im2.common.alert.events + (:require [re-frame.core :as re-frame] + [react-native.core :as rn] + [i18n.i18n :as i18n])) + +(defn show-popup + ([title content] + (show-popup title content nil)) + ([title content on-dismiss] + (rn/alert + title + content + (vector (merge {:text "OK" + :style "cancel" + :accessibility-label :cancel-button} + (when on-dismiss {:onPress on-dismiss}))) + (when on-dismiss + {:cancelable false})))) + +(re-frame/reg-fx + :utils/show-popup + (fn [{:keys [title content on-dismiss]}] + (show-popup title content on-dismiss))) + +(defn show-confirmation + [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text + extra-options]}] + (rn/alert + title + content + ;; Styles are only relevant on iOS. On Android first button is 'neutral' and second is 'positive' + (concat + (vector (merge {:text (or cancel-button-text (i18n/label :t/cancel)) + :style "cancel" + :accessibility-label :cancel-button} + (when on-cancel {:onPress on-cancel})) + {:text (or confirm-button-text (i18n/label :t/ok)) + :onPress on-accept + :style "default" + :accessibility-label :confirm-button}) + (or extra-options nil)) + {:cancelable false})) + +(re-frame/reg-fx + :utils/show-confirmation + (fn [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text extra-options]}] + (show-confirmation {:title title + :content content + :confirm-button-text confirm-button-text + :cancel-button-text cancel-button-text + :on-accept on-accept + :on-cancel on-cancel + :extra-options extra-options}))) + +(defn show-question + ([title content on-accept] + (show-question title content on-accept nil)) + ([title content on-accept on-cancel] + (rn/alert + title + content + (vector (merge {:text (i18n/label :t/no) + :accessibility-label :no-button} + (when on-cancel {:onPress on-cancel})) + {:text (i18n/label :t/yes) + :onPress on-accept + :accessibility-label :yes-button}) + nil))) diff --git a/src/status_im2/common/theme/core.cljs b/src/status_im2/common/theme/core.cljs new file mode 100644 index 0000000000..bce41e19aa --- /dev/null +++ b/src/status_im2/common/theme/core.cljs @@ -0,0 +1,15 @@ +(ns status-im2.common.theme.core + (:require [react-native.core :as rn])) + +(def initial-mode (atom (rn/get-color-scheme))) + +;; Note - don't use value returned by change listener +;; https://github.com/facebook/react-native/issues/28525 +(defn add-mode-change-listener [callback] + (rn/appearance-add-change-listener #(let [mode (rn/get-color-scheme)] + (when-not (= mode @initial-mode) + (reset! initial-mode mode) + (callback (keyword mode)))))) + +(defn dark-mode? [] + (= @initial-mode "dark")) diff --git a/src/status_im2/common/timer/events.cljs b/src/status_im2/common/timer/events.cljs new file mode 100644 index 0000000000..eab6abe05a --- /dev/null +++ b/src/status_im2/common/timer/events.cljs @@ -0,0 +1,17 @@ +(ns status-im2.common.timer.events + (:require [re-frame.core :as re-frame] + [react-native.background-timer :as background-timer])) + +(re-frame/reg-fx + :background-timer/dispatch-later + (fn [params] + (doseq [{:keys [ms dispatch]} params] + (when (and ms dispatch) + (background-timer/set-timeout #(re-frame/dispatch dispatch) ms))))) + +(re-frame/reg-fx + :background-timer/clear-timeouts + (fn [ids] + (doseq [id ids] + (when id + (background-timer/clear-timeout id))))) diff --git a/src/status_im2/navigation/core.cljs b/src/status_im2/navigation/core.cljs new file mode 100644 index 0000000000..a73c0af3b0 --- /dev/null +++ b/src/status_im2/navigation/core.cljs @@ -0,0 +1,328 @@ +(ns status-im2.navigation.core + (:require + [react-native.core :as rn] + [react-native.gesture :as gesture] + [react-native.navigation :as navigation] + [react-native.platform :as platform] + [re-frame.core :as re-frame] + [taoensso.timbre :as log] + + [status-im2.navigation.roots :as roots] + [status-im2.navigation.state :as state] + + ;; TODO (14/11/22 flexsurfer) move to status-im2 namespace + [status-im.multiaccounts.login.core :as login-core] + [status-im2.navigation.view :as views] + [status-im.utils.fx :as fx] + [quo2.foundations.colors :as colors])) + +;; REGISTER COMPONENT (LAZY) +(defn reg-comp [key] + (log/debug "reg-comp" key) + (if-let [comp (get views/components (keyword key))] + (navigation/register-component key (fn [] (views/component comp)) nil) + (let [screen (views/screen key)] + (navigation/register-component key (fn [] (gesture/gesture-handler-root-hoc screen)) (fn [] screen))))) + +(defn dismiss-all-modals [] + (log/debug "dissmiss-all-modals") + (when @state/curr-modal + (reset! state/curr-modal false) + (reset! state/dissmissing true) + (doseq [modal @state/modals] + (navigation/dismiss-modal (name modal))) + (reset! state/modals []))) + +;; PUSH SCREEN TO THE CURRENT STACK +(defn navigate [comp] + (log/debug "NAVIGATE" comp) + (let [{:keys [options]} (get views/screens comp)] + (navigation/push + (name @state/root-comp-id) + {:component {:id comp + :name comp + :options (merge options + (roots/status-bar-options) + (roots/merge-top-bar (roots/topbar-options) options))}}) + ;;if we push the screen from modal, we want to dismiss all modals + (dismiss-all-modals))) + +;; OPEN MODAL +(defn update-modal-topbar-options [options] + (log/debug "update-modal-topbar-options" options) + (merge options + ;; TODO fix colors and icons from quo2 later if needed + #_(roots/merge-top-bar {:elevation 0 + :noBorder true + :title {:color quo.colors/black} + :background {:color quo.colors/white} + :leftButtonColor quo.colors/black + :leftButtons {:id "dismiss-modal" + :icon (icons/icon-source :main-icons/close)}} + options))) + +(defn open-modal [comp] + (log/debug "open-modal" comp) + (let [{:keys [options]} (get views/screens comp)] + (if @state/dissmissing + (reset! state/dissmissing comp) + (do + (reset! state/curr-modal true) + (swap! state/modals conj comp) + (navigation/show-modal + {:stack {:children + [{:component + {:name comp + :id comp + :options (update-modal-topbar-options + (merge (roots/status-bar-options) + (roots/default-root) + options))}}]}}))))) + +(re-frame/reg-fx :open-modal-fx open-modal) + +;; DISSMISS MODAL +(defn dissmissModal [] + (log/debug "dissmissModal") + (reset! state/dissmissing true) + (navigation/dismiss-modal (name (last @state/modals)))) + +(defn button-pressed-listener [id] + (if (= "dismiss-modal" id) + (do + (when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])] + (re-frame/dispatch event)) + (dissmissModal)) + (when-let [handler (get-in views/screens [(keyword id) :right-handler])] + (handler)))) + +(defn set-view-id [view-id] + (log/debug "set-view-id" view-id) + (when-let [{:keys [on-focus]} (get views/screens view-id)] + (re-frame/dispatch [:set-view-id view-id]) + (re-frame/dispatch [:screens/on-will-focus view-id]) + (when on-focus + (re-frame/dispatch on-focus)))) + +(defn modal-dismissed-listener [] + (if (> (count @state/modals) 1) + (let [new-modals (butlast @state/modals)] + (reset! state/modals (vec new-modals)) + (set-view-id (last new-modals))) + (do + (reset! state/modals []) + (reset! state/curr-modal false) + (set-view-id @state/pushed-screen-id))) + + (let [comp @state/dissmissing] + (reset! state/dissmissing false) + (when (keyword? comp) + (open-modal comp)))) + +;; SCREEN DID APPEAR +(defn component-did-appear-listener [view-id] + (log/debug "screen-appear-reg" view-id) + (when (get views/screens view-id) + (when (and (not= view-id :bottom-sheet) + (not= view-id :popover) + (not= view-id :visibility-status-popover)) + (set-view-id view-id) + (when-not @state/curr-modal + (reset! state/pushed-screen-id view-id))))) + +;; SCREEN DID DISAPPEAR +(defn component-did-disappear-listener [_] + #_(when-not (#{:popover :bottom-sheet :signing-sheet :visibility-status-popover :wallet-connect-sheet + :wallet-connect-success-sheet :wallet-connect-app-management-sheet} + view-id) + ;; TODO what to do ? + (doseq [[_ {:keys [ref value]}] @quo.text-input/text-input-refs] + (.setNativeProps ^js ref (clj->js {:text value}))) + (doseq [[^js text-input default-value] @react/text-input-refs] + (.setNativeProps text-input (clj->js {:text default-value}))))) + +;; APP LAUNCHED +(defn app-launched-listener [] + (reset! state/curr-modal false) + (reset! state/dissmissing false) + (if (or (= @state/root-id :multiaccounts) + (= @state/root-id :multiaccounts-keycard)) + (re-frame/dispatch-sync [::set-multiaccount-root]) + (when @state/root-id + (reset! state/root-comp-id @state/root-id) + (navigation/set-root (get (roots/roots) @state/root-id)) + (re-frame/dispatch [::login-core/check-last-chat]))) + (rn/hide-splash-screen)) + +;; SET ROOT +(re-frame/reg-fx + :init-root-fx + (fn [new-root-id] + (log/debug :init-root-fx new-root-id) + (reset! state/root-comp-id new-root-id) + (reset! state/root-id @state/root-comp-id) + (navigation/set-root (get (roots/roots) new-root-id)))) + +(re-frame/reg-fx + :init-root-with-component-fx + (fn [[new-root-id new-root-comp-id]] + (log/debug :init-root-with-component-fx new-root-id new-root-comp-id) + (reset! state/root-comp-id new-root-comp-id) + (reset! state/root-id @state/root-comp-id) + (navigation/set-root (get (roots/roots) new-root-id)))) + +(fx/defn set-multiaccount-root + {:events [::set-multiaccount-root]} + [{:keys [db]}] + (log/debug :set-multiaccounts-root) + (let [key-uid (get-in db [:multiaccounts/login :key-uid]) + keycard-account? (boolean (get-in db [:multiaccounts/multiaccounts + key-uid + :keycard-pairing]))] + {:init-root-fx (if keycard-account? :multiaccounts-keycard :multiaccounts)})) + +(defn get-screen-component [comp] + (log/debug :get-screen-component comp) + (let [{:keys [options]} (get views/screens comp)] + {:component {:id comp + :name comp + :options (merge options + (roots/status-bar-options) + (roots/merge-top-bar (roots/topbar-options) options))}})) + +;; SET STACK ROOT +(re-frame/reg-fx + :set-stack-root-fx + (fn [[stack comp]] + (log/debug :set-stack-root-fx stack comp) + (navigation/set-stack-root + (name stack) + (if (vector? comp) + (mapv get-screen-component comp) + (get-screen-component comp))))) + +;; OVERLAY (Popover and bottom sheets) +(def dissmiss-overlay navigation/dissmiss-overlay) + +(defn show-overlay [comp] + (dissmiss-overlay comp) + (navigation/show-overlay + {:component {:name comp + :id comp + :options (merge (cond-> (roots/status-bar-options) + (and platform/android? (not (colors/dark?))) + (assoc-in [:statusBar :backgroundColor] "#99999A")) + {:layout {:componentBackgroundColor (if platform/android? + colors/neutral-80-opa-20 ;; TODO adjust color + "transparent")} + :overlay {:interceptTouchOutside true}})}})) + +;; POPOVER +(re-frame/reg-fx :show-popover (fn [] (show-overlay "popover"))) +(re-frame/reg-fx :hide-popover (fn [] (dissmiss-overlay "popover"))) + +;; VISIBILITY STATUS POPOVER +(re-frame/reg-fx :show-visibility-status-popover + (fn [] (show-overlay "visibility-status-popover"))) +(re-frame/reg-fx :hide-visibility-status-popover + (fn [] (dissmiss-overlay "visibility-status-popover"))) + +;; BOTTOM SHEETS +(re-frame/reg-fx :show-bottom-sheet (fn [] (show-overlay "bottom-sheet"))) +(re-frame/reg-fx :hide-bottom-sheet (fn [] (dissmiss-overlay "bottom-sheet"))) + +;; WALLET CONNECT +(re-frame/reg-fx :show-wallet-connect-sheet (fn [] (show-overlay "wallet-connect-sheet"))) +(re-frame/reg-fx :hide-wallet-connect-sheet (fn [] (dissmiss-overlay "wallet-connect-sheet"))) +(re-frame/reg-fx :show-wallet-connect-success-sheet (fn [] (show-overlay "wallet-connect-success-sheet"))) +(re-frame/reg-fx :hide-wallet-connect-success-sheet (fn [] (dissmiss-overlay "wallet-connect-success-sheet"))) +(re-frame/reg-fx :show-wallet-connect-app-management-sheet (fn [] (show-overlay "wallet-connect-app-management-sheet"))) +(re-frame/reg-fx :hide-wallet-connect-app-management-sheet (fn [] (dissmiss-overlay "wallet-connect-app-management-sheet"))) + +;; SIGNING +(re-frame/reg-fx :show-signing-sheet (fn [] (show-overlay "signing-sheet"))) +(re-frame/reg-fx :hide-signing-sheet (fn [] (dissmiss-overlay "signing-sheet"))) + +;; Select account +(re-frame/reg-fx :show-select-acc-sheet (fn [] (show-overlay "select-acc-sheet"))) +(re-frame/reg-fx :hide-select-acc-sheet (fn [] (dissmiss-overlay "select-acc-sheet"))) + +(defonce + _ + [(navigation/set-default-options {:layout {:orientation "portrait"}}) + (navigation/set-lazy-component-registrator reg-comp) + (navigation/reg-button-pressed-listener button-pressed-listener) + (navigation/reg-modal-dismissed-listener modal-dismissed-listener) + (navigation/reg-component-did-appear-listener component-did-appear-listener) + (navigation/reg-component-did-disappear-listener component-did-disappear-listener) + (navigation/reg-app-launched-listener app-launched-listener) + + (navigation/register-component + "popover" + (fn [] (gesture/gesture-handler-root-hoc views/popover-comp)) + (fn [] views/popover-comp)) + + (navigation/register-component + "visibility-status-popover" + (fn [] (gesture/gesture-handler-root-hoc views/visibility-status-popover-comp)) + (fn [] views/visibility-status-popover-comp)) + + (navigation/register-component + "bottom-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/sheet-comp)) + (fn [] views/sheet-comp)) + + (navigation/register-component + "wallet-connect-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-comp)) + (fn [] views/wallet-connect-comp)) + + (navigation/register-component + "wallet-connect-success-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-success-comp)) + (fn [] views/wallet-connect-success-comp)) + + (navigation/register-component + "wallet-connect-app-management-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-app-management-comp)) + (fn [] views/wallet-connect-app-management-comp)) + + (navigation/register-component + "signing-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/signing-comp)) + (fn [] views/signing-comp)) + + (navigation/register-component + "select-acc-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/select-acc-comp)) + (fn [] views/select-acc-comp))]) + +;; NAVIGATION + +(re-frame/reg-fx + :navigate-to-fx + (fn [key] + (log/debug :navigate-to-fx key) + (navigate key))) + +(re-frame/reg-fx + :navigate-back-fx + (fn [] + (log/debug :navigate-back-fx) + (if @state/curr-modal + (dissmissModal) + (navigation/pop (name @state/root-comp-id))))) + +(re-frame/reg-fx + :navigate-replace-fx + (fn [view-id] + (log/debug :navigate-replace-fx view-id) + (navigation/pop (name @state/root-comp-id)) + (navigate view-id))) + +;; NAVIGATION 2 + +(re-frame/reg-fx + :change-root-status-bar-style-fx + (fn [style] + (navigation/merge-options "shell-stack" {:statusBar {:style style}}))) diff --git a/src/status_im/navigation.cljs b/src/status_im2/navigation/events.cljs similarity index 60% rename from src/status_im/navigation.cljs rename to src/status_im2/navigation/events.cljs index ed3a47a061..77892ff72f 100644 --- a/src/status_im/navigation.cljs +++ b/src/status_im2/navigation/events.cljs @@ -1,5 +1,6 @@ -(ns status-im.navigation - (:require [status-im.utils.fx :as fx])) +(ns status-im2.navigation.events + (:require [status-im.utils.fx :as fx] + [status-im2.setup.hot-reload :as hot-reload])) (defn- all-screens-params [db view screen-params] (cond-> db @@ -99,3 +100,42 @@ (assoc db :wallet-connect/showing-app-management-sheet? false) (dissoc :wallet-connect/session-managed)) :hide-wallet-connect-app-management-sheet nil}) + +;; NAVIGATION 2 +(fx/defn reload-new-ui + {:events [:reload-new-ui]} + [_] + (hot-reload/reload) + {:new-ui/reset-bottom-tabs nil + :dispatch [:init-root :shell-stack]}) + +(defn navigate-from-shell-stack [go-to-view-id id db now] + {:navigate-to-fx go-to-view-id + :db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id + :id id + :clock now})}) + +(defn navigate-from-switcher [go-to-view-id id db from-home? now] + (merge (if from-home? + {:navigate-to-fx go-to-view-id} + {:set-stack-root-fx [go-to-view-id id]}) + {:db (assoc-in db [:navigation2/navigation2-stacks id] {:type go-to-view-id + :id id + :clock now})})) + +(fx/defn navigate-to-nav2 + {:events [:navigate-to-nav2]} + [{:keys [db now]} go-to-view-id id _ from-switcher?] + (let [view-id (:view-id db) + from-home? (= view-id :chat-stack)] + (if from-switcher? + (navigate-from-switcher go-to-view-id id db from-home? now) + (if from-home? + (navigate-from-shell-stack go-to-view-id id db now) + ;; TODO(parvesh) - new stacks created from other screens should be stacked on current stack, instead of creating new entry + (navigate-from-shell-stack go-to-view-id id db now))))) + +(fx/defn change-root-status-bar-style + {:events [:change-root-status-bar-style]} + [_ style] + {:change-root-status-bar-style-fx style}) diff --git a/src/status_im2/navigation/roots.cljs b/src/status_im2/navigation/roots.cljs new file mode 100644 index 0000000000..938ab31c69 --- /dev/null +++ b/src/status_im2/navigation/roots.cljs @@ -0,0 +1,144 @@ +(ns status-im2.navigation.roots + (:require [status-im2.navigation.view :as views] + [quo2.foundations.colors :as colors] + [react-native.platform :as platform])) + +(defn status-bar-options [] + (if platform/android? + {:navigationBar {:backgroundColor colors/white} + :statusBar {:backgroundColor colors/white + :style (if (colors/dark?) :light :dark)}} + {:statusBar {:style (if (colors/dark?) :light :dark)}})) + +(defn topbar-options [] + {:noBorder true + :scrollEdgeAppearance {:active false + :noBorder true} + :elevation 0 + :title {:color colors/neutral-100} + :rightButtonColor colors/neutral-100 + :background {:color colors/white} + ;; TODO adjust colors and icons with quo2 + ;;:backButton + #_{:icon (icons/icon-source :main-icons/arrow-left) + :color colors/neutral-100}}) + +(defn default-root [] + {:layout {:componentBackgroundColor colors/white + :orientation "portrait" + :backgroundColor colors/white}}) + +(defn merge-top-bar [root-options options] + (let [options (:topBar options)] + {:topBar + (merge root-options + options + (when (or (:title root-options) (:title options)) + {:title (merge (:title root-options) (:title options))}) + (when (or (:background root-options) (:background options)) + {:background (merge (:background root-options) (:background options))}) + (when (or (:backButton root-options) (:backButton options)) + {:backButton (merge (:backButton root-options) (:backButton options))}) + (when (or (:leftButtons root-options) (:leftButtons options)) + {:leftButtons (merge (:leftButtons root-options) (:leftButtons options))}) + (when (or (:rightButtons root-options) (:rightButtons options)) + {:rightButtons (merge (:rightButtons root-options) (:rightButtons options))}))})) + +(defn get-screen-options [screen] + (merge (get-in views/screens [screen :options]) + (status-bar-options) + (merge-top-bar (topbar-options) + (get-in views/screens [screen :options])))) + +;;TODO problem here is that we have two places for screens, here and in screens ns, and we have handler in navigate +(defn old-roots [] + ;;TABS + {;;INTRO (onboarding carousel) + :intro + {:root {:stack {:children [{:component {:name :intro + :id :intro + :options (status-bar-options)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (assoc (topbar-options) :visible false)})}}} + + ;; ONBOARDING + :onboarding + {:root {:stack {:id :onboarding + :children [{:component {:name :get-your-keys + :id :get-your-keys + :options (status-bar-options)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (assoc (topbar-options) :elevation 0 :noBorder true :animate false)})}}} + + ;;PROGRESS + :progress + {:root {:stack {:children [{:component {:name :progress + :id :progress + :options (status-bar-options)}}] + :options (merge (default-root) + {:topBar (assoc (topbar-options) :visible false)})}}} + + ;;LOGIN + :multiaccounts + {:root {:stack {:id :multiaccounts-stack + :children [{:component {:name :multiaccounts + :id :multiaccounts + :options (get-screen-options :multiaccounts)}} + {:component {:name :login + :id :login + :options (get-screen-options :login)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (topbar-options)})}}} + + :multiaccounts-keycard + {:root {:stack {:id :multiaccounts-stack + :children [{:component {:name :multiaccounts + :id :multiaccounts + :options (get-screen-options :multiaccounts)}} + {:component {:name :keycard-login-pin + :id :keycard-login-pin + :options (get-screen-options :keycard-login-pin)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (topbar-options)})}}} + + ;;WELCOME + :welcome + {:root {:stack {:children [{:component {:name :welcome + :id :welcome + :options (status-bar-options)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (assoc (topbar-options) :visible false)})}}} + + ;;NOTIFICATIONS + :onboarding-notification + {:root {:stack {:children [{:component {:name :onboarding-notification + :id :onboarding-notification + :options (status-bar-options)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (assoc (topbar-options) :visible false)})}}} + + ;; TERMS OF SERVICE + :tos + {:root {:stack {:children [{:component {:name :force-accept-tos + :id :force-accept-tos + :options (get-screen-options :force-accept-tos)}}] + :options (merge (default-root) + (status-bar-options) + {:topBar (assoc (topbar-options) :visible false)})}}}}) + +(defn roots [] + ;;TABS + (merge (old-roots) + {:shell-stack + {:root + {:stack {:id :shell-stack + :children [{:component {:name :shell-stack + :id :shell-stack + :options (merge (status-bar-options) + {:topBar {:visible false}})}}]}}}})) diff --git a/src/status_im2/navigation/screens.cljs b/src/status_im2/navigation/screens.cljs new file mode 100644 index 0000000000..e9f4ed5dfd --- /dev/null +++ b/src/status_im2/navigation/screens.cljs @@ -0,0 +1,26 @@ +(ns status-im2.navigation.screens + (:require [status-im2.setup.config :as config] + [status-im.ui2.screens.quo2-preview.main :as quo2.preview] + [status-im.ui2.screens.communities.discover-communities :as discover-communities] + + ;; TODO (14/11/22 flexsurfer) move to status-im2 namespace + [status-im.switcher.shell-stack :as shell-stack] + [status-im.ui.screens.screens :as old-screens])) + +(def components + []) + +(defn screens [] + (concat [{:name :shell-stack + :insets {:top false} + :component shell-stack/shell-stack} + + {:name :discover-communities + ;;TODO animated-header scroll behaviours + :options {:topBar {:visible false}} + :component discover-communities/communities}] + (old-screens/screens) + (when config/quo-preview-enabled? + quo2.preview/screens) + (when config/quo-preview-enabled? + quo2.preview/main-screens))) diff --git a/src/status_im/navigation/state.cljs b/src/status_im2/navigation/state.cljs similarity index 70% rename from src/status_im/navigation/state.cljs rename to src/status_im2/navigation/state.cljs index fb552445db..705737dcd9 100644 --- a/src/status_im/navigation/state.cljs +++ b/src/status_im2/navigation/state.cljs @@ -1,8 +1,8 @@ -(ns status-im.navigation.state) +(ns status-im2.navigation.state) (defonce root-comp-id (atom nil)) (defonce root-id (atom nil)) (defonce pushed-screen-id (atom nil)) (defonce curr-modal (atom nil)) (defonce modals (atom [])) -(defonce dissmissing (atom false)) \ No newline at end of file +(defonce dissmissing (atom false)) diff --git a/src/status_im/ui/screens/views.cljs b/src/status_im2/navigation/view.cljs similarity index 74% rename from src/status_im/ui/screens/views.cljs rename to src/status_im2/navigation/view.cljs index ec837d3a34..dd73e85cd4 100644 --- a/src/status_im/ui/screens/views.cljs +++ b/src/status_im2/navigation/view.cljs @@ -1,20 +1,22 @@ -(ns status-im.ui.screens.views - (:require [status-im.ui.components.react :as react] - [reagent.core :as reagent] - [status-im.reloader :as reloader] - [status-im.ui.screens.screens :as screens] +(ns status-im2.navigation.view + (:require [reagent.core :as reagent] + [status-im2.setup.hot-reload :as reloader] [oops.core :refer [oget]] + [re-frame.core :as re-frame] + [react-native.core :as rn] + [react-native.platform :as platform] + [react-native.safe-area :as safe-area] + [status-im2.navigation.screens :as screens] + [status-im2.setup.config :as config] + + ;; TODO (14/11/22 flexsurfer) move to status-im2 namespace [status-im.ui.screens.popover.views :as popover] [status-im.ui.screens.profile.visibility-status.views :as visibility-status-views] [status-im.ui.screens.bottom-sheets.views :as bottom-sheets] [status-im.ui.screens.signing.views :as signing] [status-im.ui.screens.wallet.send.views :as wallet.send.views] - [re-frame.core :as re-frame] - [quo.design-system.colors :as colors] - [status-im.utils.config :as config] - [status-im.keycard.test-menu :as keycard.test-menu] - [status-im.utils.platform :as platform] - [status-im.ui.screens.wallet-connect.session-proposal.views :as wallet-connect])) + [status-im.ui.screens.wallet-connect.session-proposal.views :as wallet-connect] + [status-im.keycard.test-menu :as keycard.test-menu])) (defn get-screens [] (reduce @@ -35,11 +37,11 @@ (defn wrapped-screen-style [{:keys [insets style]} insets-obj] (merge - {:flex 1 - :background-color colors/white} + {:flex 1} + ;:background-color colors/white} ;; TODO ajust color (when platform/android? - {:border-bottom-width 1 - :border-bottom-color colors/gray-lighter}) + {:border-bottom-width 1}) + ;:border-bottom-color colors/gray-lighter}) ;; TODO ajust color style (when (get insets :bottom) {:padding-bottom (+ (oget insets-obj "bottom") @@ -52,8 +54,9 @@ (defn inactive [] (when @(re-frame/subscribe [:hide-screen?]) - [react/view {:position :absolute :flex 1 :top 0 :bottom 0 :left 0 :right 0 :background-color colors/white - :z-index 999999999999999999}])) + [rn/view {:position :absolute :flex 1 :top 0 :bottom 0 :left 0 :right 0 + ;:background-color :white ;; TODO ajust color + :z-index 999999999999999999}])) (defn screen [key] (reagent.core/reactify-component @@ -64,13 +67,13 @@ screens) (keyword key))] ^{:key (str "root" key @reloader/cnt)} - [react/safe-area-provider - [react/safe-area-consumer + [safe-area/safe-area-provider + [safe-area/safe-area-consumer (fn [safe-insets] (reagent/as-element - [react/view {:style (wrapped-screen-style - {:insets insets} - safe-insets)} + [rn/view {:style (wrapped-screen-style + {:insets insets} + safe-insets)} [inactive] [component]]))] (when js/goog.DEBUG @@ -79,14 +82,14 @@ (defn component [comp] (reagent/reactify-component (fn [] - [react/view {:width 500 :height 44} + [rn/view {:width 500 :height 44} [comp]]))) (def popover-comp (reagent/reactify-component (fn [] ^{:key (str "popover" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [popover/popover] (when js/goog.DEBUG @@ -96,7 +99,7 @@ (reagent/reactify-component (fn [] ^{:key (str "visibility-status-popover" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [visibility-status-views/visibility-status-popover] (when js/goog.DEBUG @@ -106,7 +109,7 @@ (reagent/reactify-component (fn [] ^{:key (str "seet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [bottom-sheets/bottom-sheet] (when js/goog.DEBUG @@ -118,7 +121,7 @@ (reagent/reactify-component (fn [] ^{:key (str "signing-sheet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [signing/signing] (when js/goog.DEBUG @@ -128,7 +131,7 @@ (reagent/reactify-component (fn [] ^{:key (str "select-acc-sheet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [wallet.send.views/select-account] (when js/goog.DEBUG @@ -138,7 +141,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-sheet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [wallet-connect/wallet-connect-proposal-sheet] (when js/goog.DEBUG @@ -148,7 +151,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-success-sheet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [wallet-connect/wallet-connect-success-sheet-view] (when js/goog.DEBUG @@ -158,7 +161,7 @@ (reagent/reactify-component (fn [] ^{:key (str "wallet-connect-app-management-sheet" @reloader/cnt)} - [react/safe-area-provider + [safe-area/safe-area-provider [inactive] [wallet-connect/wallet-connect-app-management-sheet-view] (when js/goog.DEBUG diff --git a/src/status_im2/setup/config.cljs b/src/status_im2/setup/config.cljs new file mode 100644 index 0000000000..cd419608c1 --- /dev/null +++ b/src/status_im2/setup/config.cljs @@ -0,0 +1,144 @@ +(ns status-im2.setup.config + (:require [clojure.string :as string] + [react-native.config :as react-native-config] + + ;; TODO (14/11/22 flexsurfer move to status-im2 namespace + [status-im.ethereum.core :as ethereum] + [status-im.ethereum.ens :as ens])) + +(def get-config react-native-config/get-config) + +(defn enabled? [v] (= "1" v)) + +(goog-define POKT_TOKEN "3ef2018191814b7e1009b8d9") +(goog-define OPENSEA_API_KEY "") + +(def mainnet-rpc-url (str "https://eth-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN)) +(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN)) +(def opensea-api-key OPENSEA_API_KEY) +(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1"))) +(def mailserver-confirmations-enabled? (enabled? (get-config :MAILSERVER_CONFIRMATIONS_ENABLED))) +(def pairing-popup-disabled? (enabled? (get-config :PAIRING_POPUP_DISABLED "0"))) +(def cached-webviews-enabled? (enabled? (get-config :CACHED_WEBVIEWS_ENABLED 0))) +(def snoopy-enabled? (enabled? (get-config :SNOOPY 0))) +(def dev-build? (enabled? (get-config :DEV_BUILD 0))) +(def max-message-delivery-attempts (js/parseInt (get-config :MAX_MESSAGE_DELIVERY_ATTEMPTS "6"))) +(def max-images-batch (js/parseInt (get-config :MAX_IMAGES_BATCH "1"))) +;; NOTE: only disabled in releases +(def local-notifications? (enabled? (get-config :LOCAL_NOTIFICATIONS "1"))) +(def blank-preview? (enabled? (get-config :BLANK_PREVIEW "1"))) +(def group-chat-enabled? (enabled? (get-config :GROUP_CHATS_ENABLED "0"))) +(def tooltip-events? (enabled? (get-config :TOOLTIP_EVENTS "0"))) +(def commands-enabled? (enabled? (get-config :COMMANDS_ENABLED "0"))) +(def keycard-test-menu-enabled? (enabled? (get-config :KEYCARD_TEST_MENU "1"))) +(def qr-test-menu-enabled? (enabled? (get-config :QR_READ_TEST_MENU "0"))) +(def quo-preview-enabled? (enabled? (get-config :ENABLE_QUO_PREVIEW "0"))) +(def communities-enabled? (enabled? (get-config :COMMUNITIES_ENABLED "0"))) +(def database-management-enabled? (enabled? (get-config :DATABASE_MANAGEMENT_ENABLED "0"))) +(def debug-webview? (enabled? (get-config :DEBUG_WEBVIEW "0"))) +(def delete-message-enabled? (enabled? (get-config :DELETE_MESSAGE_ENABLED "0"))) +(def collectibles-enabled? (enabled? (get-config :COLLECTIBLES_ENABLED "1"))) +(def test-stateofus? (enabled? (get-config :TEST_STATEOFUS "0"))) +(def two-minutes-syncing? (enabled? (get-config :TWO_MINUTES_SYNCING "0"))) +(def swap-enabled? (enabled? (get-config :SWAP_ENABLED "0"))) +(def stickers-test-enabled? (enabled? (get-config :STICKERS_TEST_ENABLED "0"))) + +;; CONFIG VALUES +(def log-level (string/upper-case (get-config :LOG_LEVEL ""))) +(def fleet (get-config :FLEET "eth.staging")) +(def apn-topic (get-config :APN_TOPIC "im.status.ethereum")) +(def default-network (get-config :DEFAULT_NETWORK "goerli_rpc")) +(def max-installations 2) +; currently not supported in status-go +(def enable-remove-profile-picture? false) + +(def verify-transaction-chain-id (js/parseInt (get-config :VERIFY_TRANSACTION_CHAIN_ID "1"))) +(def verify-transaction-url (if (= :mainnet (ethereum/chain-id->chain-keyword verify-transaction-chain-id)) + mainnet-rpc-url + goerli-rpc-url)) + +(def verify-ens-chain-id (js/parseInt (get-config :VERIFY_ENS_CHAIN_ID "1"))) +(def verify-ens-url (if (= :mainnet (ethereum/chain-id->chain-keyword verify-ens-chain-id)) + mainnet-rpc-url + goerli-rpc-url)) +(def verify-ens-contract-address (get-config :VERIFY_ENS_CONTRACT_ADDRESS ((ethereum/chain-id->chain-keyword verify-ens-chain-id) ens/ens-registries))) + +(def default-multiaccount + {:preview-privacy? blank-preview? + :wallet/visible-tokens {:mainnet #{:SNT}} + :currency :usd + :appearance 0 + :profile-pictures-show-to 1 + :profile-pictures-visibility 1 + :log-level log-level + :webview-allow-permission-requests? false + :opensea-enabled? false + :link-previews-enabled-sites #{} + :link-preview-request-enabled true}) + +(defn default-visible-tokens [chain] + (get-in default-multiaccount [:wallet/visible-tokens chain])) + +(def mainnet-networks + [{:id "mainnet_rpc", + :chain-explorer-link "https://etherscan.io/address/", + :name "Mainnet with upstream RPC", + :config {:NetworkId (ethereum/chain-keyword->chain-id :mainnet) + :DataDir "/ethereum/mainnet_rpc" + :UpstreamConfig {:Enabled true + :URL mainnet-rpc-url}}}]) + +(def sidechain-networks + [{:id "xdai_rpc", + :name "xDai Chain", + :chain-explorer-link "https://blockscout.com/xdai/mainnet/address/", + :config {:NetworkId (ethereum/chain-keyword->chain-id :xdai) + :DataDir "/ethereum/xdai_rpc" + :UpstreamConfig {:Enabled true + :URL "https://gnosischain-rpc.gateway.pokt.network"}}} + {:id "bsc_rpc", + :chain-explorer-link "https://bscscan.com/address/", + :name "BSC Network", + :config {:NetworkId (ethereum/chain-keyword->chain-id :bsc) + :DataDir "/ethereum/bsc_rpc" + :UpstreamConfig {:Enabled true + :URL "https://bsc-dataseed.binance.org"}}}]) + +(def testnet-networks + [{:id "goerli_rpc", + :chain-explorer-link "https://goerli.etherscan.io/address/", + :name "Goerli with upstream RPC", + :config {:NetworkId (ethereum/chain-keyword->chain-id :goerli) + :DataDir "/ethereum/goerli_rpc" + :UpstreamConfig {:Enabled true + :URL goerli-rpc-url}}} + {:id "bsc_testnet_rpc", + :chain-explorer-link "https://testnet.bscscan.com/address/", + :name "BSC testnet", + :config {:NetworkId (ethereum/chain-keyword->chain-id :bsc-testnet) + :DataDir "/ethereum/bsc_testnet_rpc" + :UpstreamConfig {:Enabled true + :URL "https://data-seed-prebsc-1-s1.binance.org:8545/"}}}]) + +(def default-networks + (concat testnet-networks mainnet-networks sidechain-networks)) + +(def default-networks-by-id + (into {} + (map (fn [{:keys [id] :as network}] + [id network]) + default-networks))) + +(def default-wallet-connect-metadata {:name "Status Wallet" + :description "Status is a secure messaging app, crypto wallet, and Web3 browser built with state of the art technology." + :url "#" + :icons ["https://statusnetwork.com/img/press-kit-status-logo.svg"]}) + +(def wallet-connect-project-id "87815d72a81d739d2a7ce15c2cfdefb3") + +;;TODO for development only should be removed in status 2.0 +(def new-ui-enabled? true) + +;; TODO: Remove this (highly) temporary flag once the new Activity Center is +;; usable enough to replace the old one **in the new UI**. +(def new-activity-center-enabled? false) diff --git a/src/status_im2/setup/core.cljs b/src/status_im2/setup/core.cljs new file mode 100644 index 0000000000..a13b08869c --- /dev/null +++ b/src/status_im2/setup/core.cljs @@ -0,0 +1,54 @@ +(ns status-im2.setup.core + (:require [re-frame.core :as re-frame] + [re-frame.interop :as interop] + [reagent.impl.batching :as batching] + [react-native.core :as rn] + [react-native.platform :as platform] + [react-native.shake :as react-native-shake] + [react-native.languages :as react-native-languages] + + [i18n.i18n :as i18n] + + status-im2.setup.events + status-im2.subs.root + status-im2.navigation.core + + [status-im2.setup.dev :as dev] + [status-im2.setup.global-error :as global-error] + [status-im2.setup.i18n-resources :as i18n-resources] + [status-im2.setup.config :as config] + [status-im2.setup.log :as log] + + status-im.events + + ;; TODO (14/11/22 flexsurfer move to status-im2 namespace + [status-im.native-module.core :as status] + [status-im.notifications.local :as notifications] + [status-im.switcher.animation :as animation] + [status-im.async-storage.core :as async-storage] + [status-im.utils.universal-links.core :as utils.universal-links])) + +;;;; re-frame RN setup +(set! interop/next-tick js/setTimeout) +(set! batching/fake-raf #(js/setTimeout % 0)) + +(defn init [] + (log/setup config/log-level) + (global-error/register-handler) + (when platform/android? + (status/set-soft-input-mode status/adjust-resize)) + (notifications/listen-notifications) + (.addEventListener rn/app-state "change" #(re-frame/dispatch [:app-state-change %])) + (i18n/init (name i18n-resources/default-device-language) (clj->js i18n-resources/translations-by-locale)) + (react-native-languages/add-change-listener #(fn [lang] + (i18n/set-language lang) + (i18n-resources/load-language lang))) + (react-native-shake/add-shake-listener #(re-frame/dispatch [:shake-event])) + (utils.universal-links/initialize) + + ;; TODO(parvesh) - Remove while moving functionality to status-go + (async-storage/get-item :selected-stack-id #(animation/selected-stack-id-loaded %)) + + (dev/setup) + + (re-frame/dispatch-sync [:setup/app-started])) diff --git a/src/status_im/db.cljs b/src/status_im2/setup/db.cljs similarity index 88% rename from src/status_im/db.cljs rename to src/status_im2/setup/db.cljs index 047d3c68f6..15ffb9dc0f 100644 --- a/src/status_im/db.cljs +++ b/src/status_im2/setup/db.cljs @@ -1,7 +1,9 @@ -(ns status-im.db - (:require [status-im.utils.dimensions :as dimensions] - [status-im.fleet.core :as fleet] - [status-im.wallet.db :as wallet.db])) +(ns status-im2.setup.db + (:require + [react-native.core :as rn] + ;; TODO (14/11/22 flexsurfer move to status-im2 namespace + [status-im.fleet.core :as fleet] + [status-im.wallet.db :as wallet.db])) ;; initial state of app-db (def app-db {:contacts/contacts {} @@ -30,7 +32,7 @@ :chats-home-list #{} :home-items-show-number 20 :tooltips {} - :dimensions/window (dimensions/window) + :dimensions/window (rn/get-window) :registry {} :visibility-status-updates {} :stickers/packs-pending #{} diff --git a/src/status_im2/setup/dev.cljs b/src/status_im2/setup/dev.cljs new file mode 100644 index 0000000000..0cd34c34f5 --- /dev/null +++ b/src/status_im2/setup/dev.cljs @@ -0,0 +1,13 @@ +(ns status-im2.setup.dev + (:require [react-native.platform :as platform] + ["react-native" :refer (DevSettings LogBox)])) + +(.ignoreAllLogs LogBox) + +(defn setup [] + (when (and js/goog.DEBUG platform/ios? DevSettings) + ;;on Android this method doesn't work + (when-let [nm (.-_nativeModule DevSettings)] + ;;there is a bug in RN, so we have to enable it first and then disable + (.setHotLoadingEnabled ^js nm true) + (js/setTimeout #(.setHotLoadingEnabled ^js nm false) 1000)))) diff --git a/src/status_im/init/core.cljs b/src/status_im2/setup/events.cljs similarity index 63% rename from src/status_im/init/core.cljs rename to src/status_im2/setup/events.cljs index 162fa94df2..c22f2cb5fd 100644 --- a/src/status_im/init/core.cljs +++ b/src/status_im2/setup/events.cljs @@ -1,32 +1,29 @@ -(ns status-im.init.core +(ns status-im2.setup.events (:require [clojure.string :as string] [re-frame.core :as re-frame] + [status-im2.setup.db :as db] + [status-im2.common.theme.core :as theme] + [quo2.theme :as quo2.theme] + ;; TODO (14/11/22 flexsurfer move to status-im2 namespace [status-im.multiaccounts.login.core :as multiaccounts.login] [status-im.native-module.core :as status] - [status-im.network.net-info :as network] - [status-im.db :refer [app-db]] [status-im.utils.fx :as fx] - [status-im.theme.core :as theme] - [status-im.utils.theme :as utils.theme] [status-im.utils.keychain.core :as keychain] - [status-im.navigation :as navigation])) + [status-im2.navigation.events :as navigation])) -(fx/defn initialize-app-db - "Initialize db to initial state" - [{{:keys [keycard supported-biometric-auth app-active-since goto-key-storage?] - :network/keys [type] :keycard/keys [banner-hidden]} :db - now :now}] - {:db (assoc app-db - :network/type type - :keycard/banner-hidden banner-hidden - :keycard (dissoc keycard :secrets :pin :application-info) - :supported-biometric-auth supported-biometric-auth - :app-active-since (or app-active-since now) - :goto-key-storage? goto-key-storage? - :multiaccounts/loading true)}) +(re-frame/reg-fx + :setup/open-multiaccounts + (fn [callback] + (status/open-accounts callback))) + +(re-frame/reg-fx + :setup/init-theme + (fn [] + (theme/add-mode-change-listener #(re-frame/dispatch [:system-theme-mode-changed %])) + (quo2.theme/set-theme (if (theme/dark-mode?) :dark :light)))) (fx/defn initialize-views - {:events [::initialize-view]} + {:events [:setup/initialize-view]} [cofx] (let [{{:multiaccounts/keys [multiaccounts]} :db} cofx] (if (and (seq multiaccounts)) @@ -41,7 +38,7 @@ (navigation/init-root cofx :intro)))) (fx/defn initialize-multiaccounts - {:events [::initialize-multiaccounts]} + {:events [:setup/initialize-multiaccounts]} [{:keys [db] :as cofx} all-multiaccounts {:keys [logout?]}] (let [multiaccounts (reduce (fn [acc {:keys [key-uid keycard-pairing] :as multiaccount}] @@ -52,38 +49,38 @@ {} all-multiaccounts)] (fx/merge cofx - {:db (-> db - (assoc :multiaccounts/multiaccounts multiaccounts) - (assoc :multiaccounts/logout? logout?) - (assoc :multiaccounts/loading false)) - :dispatch-n [[::initialize-view] + {:db (-> db + (assoc :multiaccounts/multiaccounts multiaccounts) + (assoc :multiaccounts/logout? logout?) + (assoc :multiaccounts/loading false)) + :dispatch-n [[:setup/initialize-view] [:get-opted-in-to-new-terms-of-service] [:load-information-box-states]]}))) +(fx/defn initialize-app-db + "Initialize db to initial state" + [{{:keys [keycard supported-biometric-auth goto-key-storage?] + :network/keys [type] :keycard/keys [banner-hidden]} :db}] + {:db (assoc db/app-db + :network/type type + :keycard/banner-hidden banner-hidden + :keycard (dissoc keycard :secrets :pin :application-info) + :supported-biometric-auth supported-biometric-auth + :goto-key-storage? goto-key-storage? + :multiaccounts/loading true)}) + (fx/defn start-app - {:events [:init/app-started]} + {:events [:setup/app-started]} [cofx] (fx/merge cofx - {:get-supported-biometric-auth nil - ::init-theme nil - ::open-multiaccounts #(do - (re-frame/dispatch [::initialize-multiaccounts % {:logout? false}]) - (re-frame/dispatch [:get-keycard-banner-preference])) - :ui/listen-to-window-dimensions-change nil - ::network/listen-to-network-info nil + {:setup/init-theme nil + :get-supported-biometric-auth nil + :network/listen-to-network-info nil :keycard/register-card-events nil :keycard/check-nfc-support nil :keycard/check-nfc-enabled nil - :keycard/retrieve-pairings nil} + :keycard/retrieve-pairings nil + :setup/open-multiaccounts #(do + (re-frame/dispatch [:setup/initialize-multiaccounts % {:logout? false}]) + (re-frame/dispatch [:get-keycard-banner-preference]))} (initialize-app-db))) - -(re-frame/reg-fx - ::open-multiaccounts - (fn [callback] - (status/open-accounts callback))) - -(re-frame/reg-fx - ::init-theme - (fn [] - (utils.theme/add-mode-change-listener #(re-frame/dispatch [:system-theme-mode-changed %])) - (theme/change-theme (if (utils.theme/is-dark-mode) :dark :light)))) diff --git a/src/status_im/utils/error_handler.cljs b/src/status_im2/setup/global_error.cljs similarity index 90% rename from src/status_im/utils/error_handler.cljs rename to src/status_im2/setup/global_error.cljs index a80dd10d60..8a457da0cb 100644 --- a/src/status_im/utils/error_handler.cljs +++ b/src/status_im2/setup/global_error.cljs @@ -1,8 +1,8 @@ -(ns status-im.utils.error-handler +(ns status-im2.setup.global-error (:require [clojure.string :as string] - [status-im.utils.utils :as utils] - [status-im.i18n.i18n :as i18n] - [re-frame.core :as re-frame])) + [i18n.i18n :as i18n] + [re-frame.core :as re-frame] + [status-im2.common.alert.events :as alert])) ;; Error handling code based on https://gist.github.com/pesterhazy/e6846be1b6712a9038537022d131ce46 @@ -43,7 +43,7 @@ (defonce !error-handler-set? (atom false)) -(defn register-exception-handler! +(defn register-handler "Improve error messages printed to console. When js/goog.DEBUG is false, show a popup with an error summary; else rely on default `red` screen." [] @@ -56,7 +56,7 @@ (handle-error e isFatal) (if js/goog.DEBUG (some-> orig-handler (.call nil e isFatal)) - (utils/show-confirmation + (alert/show-confirmation {:title "Error" :content (.-message e) :confirm-button-text (i18n/label :t/send-logs) diff --git a/src/status_im/reloader.cljs b/src/status_im2/setup/hot_reload.cljs similarity index 55% rename from src/status_im/reloader.cljs rename to src/status_im2/setup/hot_reload.cljs index 9fa8c18260..3778cc4add 100644 --- a/src/status_im/reloader.cljs +++ b/src/status_im2/setup/hot_reload.cljs @@ -1,12 +1,9 @@ -(ns status-im.reloader +(ns status-im2.setup.hot-reload (:require [reagent.core :as reagent] - [status-im.ui.components.react :as react] - [status-im.react-native.resources :as resources] - [quo.design-system.colors :as colors] + [react-native.core :as rn] [re-frame.core :as re-frame])) (def cnt (reagent/atom 0)) -(defonce cnt-prev (reagent/atom 0)) (defonce warning? (reagent/atom false)) (defonce visible (reagent/atom false)) (defonce timeout (reagent/atom false)) @@ -50,17 +47,9 @@ (defn reload-view [_] (fn [] (when @visible - [react/view {:pointerEvents :none - :style {:position :absolute :top 0 :left 0 :right 0 :bottom 0 - :justify-content :center :align-items :center}} - [react/image {:source (resources/get-image :status-logo) - :resize-mode :center - :style (merge {:width 64 - :height 64} - (when @warning? - {:opacity 0.8 - :borderWidth 2 - :border-color :red - :background-color "rgba(255,0,0,0.5))"}))}] - [react/text {:style {:margin-top 10 :color (if @warning? :red colors/black)}} + [rn/view {:pointerEvents :none + :style {:position :absolute :top 0 :left 0 :right 0 :bottom 0 + :justify-content :center :align-items :center}} + [rn/view {:width 64 :height 64 :background-color :blue}] + [rn/text {:style {:margin-top 10 :color (if @warning? :red :black)}} @label]]))) diff --git a/src/status_im2/setup/i18n_resources.cljs b/src/status_im2/setup/i18n_resources.cljs new file mode 100644 index 0000000000..40625f4741 --- /dev/null +++ b/src/status_im2/setup/i18n_resources.cljs @@ -0,0 +1,71 @@ +(ns status-im2.setup.i18n-resources + (:require [clojure.string :as string] + [react-native.languages :as react-native-languages] + [i18n.i18n :as i18n])) + +(def default-device-language (react-native-languages/get-lang-keyword)) + +(def languages #{:ar :bn :de :el :en :es :es_419 :es_AR :fil :fr :hi :id :in :it :ja :ko :ms :nl :pl :pt :pt_BR :ru :tr :vi :zh :zh_Hant :zh_TW}) + +(defonce loaded-languages + (atom + (conj #{:en} default-device-language))) + +(defn valid-language [lang] + (if (contains? languages lang) + (keyword lang) + (let [parts (string/split (name lang) #"[\-\_]") + short-lang (keyword (str (first parts) "_" (second parts))) + shortest-lang (keyword (first parts))] + (if (and (> (count parts) 2) (contains? languages short-lang)) + short-lang + (when (contains? languages shortest-lang) + shortest-lang))))) + +(defn require-translation [lang-key] + (when-let [lang (valid-language (keyword lang-key))] + (case lang + :ar (js/require "../translations/ar.json") + :bn (js/require "../translations/bn.json") + :de (js/require "../translations/de.json") + :el (js/require "../translations/el.json") + :en (js/require "../translations/en.json") + :es (js/require "../translations/es.json") + :es_419 (js/require "../translations/es_419.json") + :es_AR (js/require "../translations/es_AR.json") + :fil (js/require "../translations/fil.json") + :fr (js/require "../translations/fr.json") + :hi (js/require "../translations/hi.json") + :id (js/require "../translations/id.json") + :in (js/require "../translations/id.json") + :it (js/require "../translations/it.json") + :ja (js/require "../translations/ja.json") + :ko (js/require "../translations/ko.json") + :ms (js/require "../translations/ms.json") + :nl (js/require "../translations/nl.json") + :pl (js/require "../translations/pl.json") + :pt (js/require "../translations/pt.json") + :pt_BR (js/require "../translations/pt_BR.json") + :ru (js/require "../translations/ru.json") + :tr (js/require "../translations/tr.json") + :vi (js/require "../translations/vi.json") + :zh (js/require "../translations/zh.json") + :zh_Hant (js/require "../translations/zh_hant.json") + :zh_TW (js/require "../translations/zh_TW.json")))) + +;; translations +(def translations-by-locale + (cond-> {:en (require-translation :en)} + (not= :en default-device-language) + (assoc default-device-language + (require-translation (-> (name default-device-language) + (string/replace "-" "_") + keyword))))) + +(defn load-language [lang] + (when-let [lang-key (valid-language (keyword lang))] + (when-not (contains? @loaded-languages lang-key) + (aset (i18n/get-translations) + lang + (require-translation lang-key)) + (swap! loaded-languages conj lang-key)))) diff --git a/src/status_im2/setup/i18n_test.cljs b/src/status_im2/setup/i18n_test.cljs new file mode 100644 index 0000000000..4bdff45c71 --- /dev/null +++ b/src/status_im2/setup/i18n_test.cljs @@ -0,0 +1,1096 @@ +(ns status-im2.setup.i18n-test + (:require [cljs.test :refer-macros [deftest is]] + [i18n.i18n :as i18n] + [status-im2.setup.i18n-resources :as i18n-resources] + [clojure.set :as set] + [cljs.spec.alpha :as spec] + [clojure.string :as string])) + +;; english as source of truth +(def labels (set (keys (js->clj (:en i18n-resources/translations-by-locale) + :keywordize-keys true)))) + +(spec/def ::label labels) +(spec/def ::labels (spec/coll-of ::label :kind set? :into #{})) + +(defn labels-for-all-locales [] + (->> i18n-resources/translations-by-locale + (mapcat #(-> % val (js->clj :keywordize-keys true) keys)) + set)) + +;; checkpoints + +;; Checkpoints specify milestones for locales. +;; +;; With milestones we can ensure that expected supported languages +;; are actually supported, and visualize the translation state for +;; the rest of locales according to these milestones. +;; +;; Checkpoints are defined by indicating the labels that need to be present +;; in a locale to achieve that checkpoint. +;; +;; We need to define the checkpoint that needs to be achieved for +;; a locale to be considered supported. This is why as we develop +;; we add translations, so we need to be defining a new target +;; for supported languages to achieve. +;; +;; Checkpoints are only used in dev and test. In dev when we want to +;; manually check the state of checkpoints for locales, and in test +;; to automatically check supported locales against the target checkpoint. + +(spec/def ::checkpoint.id keyword?) +(spec/def ::checkpoint-defs (spec/map-of ::checkpoint.id ::labels)) + +;; We define here the labels for the first specified checkpoint. +(def checkpoint-1-0-0-rc1-labels + #{:You + :about-app + :about-key-storage-content + :about-key-storage-title + :about-names-content + :about-names-title + :access-key + :account-added + :account-color + :account-name + :account-settings + :accounts + :active-online + :active-unknown + :add + :add-a-watch-account + :add-account + :add-account-description + :add-account-incorrect-password + :add-an-account + :add-bootnode + :add-contact + :add-custom-token + :add-mailserver + :add-members + :add-network + :add-to-contacts + :address + :advanced + :advanced-settings + :agree-by-continuing + :all + :allow + :allowing-authorizes-this-dapp + :already-have-asset + :amount + :are-you-sure-description + :are-you-sure? + :ask-in-status + :at + :authorize + :available + :available-participants + :back + :back-up-seed-phrase + :back-up-your-seed-phrase + :backup-recovery-phrase + :balance + :begin-set-up + :biometric-auth-android-sensor-desc + :biometric-auth-android-sensor-error-desc + :biometric-auth-android-title + :biometric-auth-confirm-logout + :biometric-auth-confirm-message + :biometric-auth-confirm-title + :biometric-auth-confirm-try-again + :biometric-auth-error + :biometric-auth-login-error-title + :biometric-auth-login-ios-fallback-label + :biometric-auth-reason-login + :biometric-auth-reason-verify + :blank-keycard-text + :blank-keycard-title + :block + :block-contact + :block-contact-details + :blocked-users + :bootnode-address + :bootnode-details + :bootnode-format + :bootnodes + :bootnodes-enabled + :bootnodes-settings + :browsed-websites + :browser + :browser-not-secure + :browser-secure + :browsers + :browsing-cancel + :browsing-open-in-android-web-browser + :browsing-open-in-ios-web-browser + :browsing-open-in-status + :browsing-site-blocked-description1 + :browsing-site-blocked-description2 + :browsing-site-blocked-go-back + :browsing-site-blocked-title + :browsing-title + :camera-access-error + :can-not-add-yourself + :cancel + :cancel-keycard-setup + :cannot-read-card + :cannot-use-default-pin + :card-is-blank + :card-reseted + :card-unpaired + :change-fleet + :change-log-level + :change-logging-enabled + :change-passcode + :change-password + :change-pin + :changed-amount-warning + :changed-asset-warning + :chaos-mode + :chaos-unicorn-day + :chaos-unicorn-day-details + :chat + :chat-key + :chat-name + :chat-settings + :chats + :check-your-recovery-phrase + :choose-authentication-method + :clear + :clear-history + :clear-history-action + :clear-history-confirmation + :clear-history-confirmation-content + :clear-history-title + :close-app-button + :close-app-content + :close-app-title + :command-button-send + :complete-hardwallet-setup + :completed + :confirm + :confirmations + :confirmations-helper-text + :connect + :connect-mailserver-content + :connected + :connecting + :connecting-requires-login + :connection-with-the-card-lost + :connection-with-the-card-lost-setup-text + :connection-with-the-card-lost-text + :contact-code + :contact-s + :contacts + :continue + :contract-address + :contract-interaction + :copy-info + :copy-qr + :copy-to-clipboard + :copy-transaction-hash + :cost-fee + :counter-9-plus + :create + :create-a-pin + :create-group-chat + :create-multiaccount + :create-new-key + :create-pin + :create-pin-description + :created-group-chat-description + :cryptokitty-name + :currency + :currency-display-name-aed + :currency-display-name-afn + :currency-display-name-ars + :currency-display-name-aud + :currency-display-name-bbd + :currency-display-name-bdt + :currency-display-name-bgn + :currency-display-name-bhd + :currency-display-name-bnd + :currency-display-name-bob + :currency-display-name-brl + :currency-display-name-btn + :currency-display-name-cad + :currency-display-name-chf + :currency-display-name-clp + :currency-display-name-cny + :currency-display-name-cop + :currency-display-name-crc + :currency-display-name-czk + :currency-display-name-dkk + :currency-display-name-dop + :currency-display-name-egp + :currency-display-name-etb + :currency-display-name-eur + :currency-display-name-gbp + :currency-display-name-gel + :currency-display-name-ghs + :currency-display-name-hkd + :currency-display-name-hrk + :currency-display-name-huf + :currency-display-name-idr + :currency-display-name-ils + :currency-display-name-inr + :currency-display-name-isk + :currency-display-name-jmd + :currency-display-name-jpy + :currency-display-name-kes + :currency-display-name-krw + :currency-display-name-kwd + :currency-display-name-kzt + :currency-display-name-lkr + :currency-display-name-mad + :currency-display-name-mdl + :currency-display-name-mur + :currency-display-name-mwk + :currency-display-name-mxn + :currency-display-name-myr + :currency-display-name-mzn + :currency-display-name-nad + :currency-display-name-ngn + :currency-display-name-nok + :currency-display-name-npr + :currency-display-name-nzd + :currency-display-name-omr + :currency-display-name-pen + :currency-display-name-pgk + :currency-display-name-php + :currency-display-name-pkr + :currency-display-name-pln + :currency-display-name-pyg + :currency-display-name-qar + :currency-display-name-ron + :currency-display-name-rsd + :currency-display-name-rub + :currency-display-name-sar + :currency-display-name-sek + :currency-display-name-sgd + :currency-display-name-thb + :currency-display-name-try + :currency-display-name-ttd + :currency-display-name-twd + :currency-display-name-tzs + :currency-display-name-uah + :currency-display-name-ugx + :currency-display-name-usd + :currency-display-name-uyu + :currency-display-name-vef + :currency-display-name-vnd + :currency-display-name-zar + :current-network + :current-pin + :current-pin-description + :custom + :custom-networks + :dapp + :dapp-would-like-to-connect-wallet + :dapps + :dapps-permissions + :data + :datetime-ago + :datetime-ago-format + :datetime-day + :datetime-hour + :datetime-minute + :datetime-second + :datetime-today + :datetime-yesterday + :decimals + :decryption-failed-content + :default + :delete + :delete-and-leave-group + :delete-bootnode + :delete-bootnode-are-you-sure + :delete-bootnode-title + :delete-chat + :delete-chat-confirmation + :delete-confirmation + :delete-mailserver + :delete-mailserver-are-you-sure + :delete-mailserver-title + :delete-message + :delete-my-account + :delete-network-confirmation + :delete-network-error + :delete-network-title + :deny + :description + :dev-mode + :dev-mode-settings + :device-syncing + :devices + :disable + :disabled + :disconnected + :discover + :dismiss + :done + :edit + :edit-profile + :empty-chat-description + :empty-chat-description-one-to-one + :empty-chat-description-public + :empty-chat-description-public-share-this + :enable + :encrypt-with-password + :ens-10-SNT + :ens-add-username + :ens-agree-to + :ens-chat-settings + :ens-custom-domain + :ens-custom-username-hints + :ens-custom-username-taken + :ens-deposit + :ens-displayed-with + :ens-get-name + :ens-got-it + :ens-locked + :ens-network-restriction + :ens-no-usernames + :ens-powered-by + :ens-primary-username + :ens-register + :ens-registration-failed + :ens-registration-failed-title + :ens-release-username + :ens-remove-hints + :ens-remove-username + :ens-saved + :ens-saved-title + :ens-show-username + :ens-terms-header + :ens-terms-point-1 + :ens-terms-point-10 + :ens-terms-point-2 + :ens-terms-point-3 + :ens-terms-point-4 + :ens-terms-point-5 + :ens-terms-point-6 + :ens-terms-point-7 + :ens-terms-point-8 + :ens-terms-point-9 + :ens-terms-registration + :ens-test-message + :ens-transaction-pending + :ens-understand + :ens-username + :ens-username-connected + :ens-username-hints + :ens-username-invalid + :ens-username-owned + :ens-username-available + :ens-username-taken + :ens-usernames + :ens-usernames-details + :wallet-address + :ens-want-custom-domain + :ens-want-domain + :ens-welcome-hints + :ens-welcome-point-customize + :ens-welcome-point-customize-title + :ens-welcome-point-simplify + :ens-welcome-point-simplify-title + :ens-welcome-point-receive + :ens-welcome-point-receive-title + :ens-welcome-point-register + :ens-welcome-point-register-title + :ens-welcome-point-verify + :ens-welcome-point-verify-title + :ens-your-username + :ens-your-usernames + :ens-your-your-name + :enter-12-words + :enter-contact-code + :enter-pair-code + :enter-pair-code-description + :enter-password + :enter-pin + :enter-puk-code + :enter-puk-code-description + :enter-seed-phrase + :enter-url + :enter-word + :enter-your-code + :enter-your-password + :error + :error-unable-to-get-balance + :error-unable-to-get-prices + :error-unable-to-get-token-balance + :errors + :eth + :ethereum-node-started-incorrectly-description + :ethereum-node-started-incorrectly-title + :etherscan-lookup + :export-account + :failed + :faq + :fetch-messages + :find + :finish + :finishing-card-setup + :fleet + :fleet-settings + :from + :gas-limit + :gas-price + :gas-used + :generate-a-key + :generate-a-new-account + :generate-a-new-key + :generate-account + :generate-new-key + :generating-codes-for-pairing + :generating-keys + :generating-mnemonic + :get-started + :get-status-at + :get-stickers + :go-to-settings + :got-it + :group-chat + :group-chat-admin + :group-chat-admin-added + :group-chat-created + :group-chat-decline-invitation + :group-chat-member-added + :group-chat-member-joined + :group-chat-member-removed + :group-chat-members-count + :group-chat-name-changed + :group-chat-no-contacts + :group-info + :gwei + :hash + :help + :help-capitalized + :help-center + :hide-content-when-switching-apps + :history + :history-nodes + :hold-card + :home + :hooks + :identifier + :image-remove-current + :image-source-gallery + :image-source-make-photo + :image-source-title + :in-contacts + :incoming + :incorrect-code + :initialization + :install + :intro-message1 + :intro-privacy-policy-note1 + :intro-privacy-policy-note2 + :intro-text + :intro-text1 + :intro-text2 + :intro-text3 + :intro-title1 + :intro-title2 + :intro-title3 + :intro-wizard-text1 + :intro-wizard-text2 + :intro-wizard-text3 + :intro-wizard-text4 + :intro-wizard-text6 + :intro-wizard-title-alt4 + :intro-wizard-title-alt5 + :intro-wizard-title1 + :intro-wizard-title2 + :intro-wizard-title3 + :intro-wizard-title4 + :intro-wizard-title5 + :intro-wizard-title6 + :invalid-address-qr-code + :invalid-format + :invalid-key-confirm + :invalid-key-content + :invalid-number + :invalid-pairing-password + :invalid-range + :invite-friends + :invited + :join-group-chat + :join-group-chat-description + :joined-group-chat-description + :key + :keycard + :keycard-applet-install-instructions + :keycard-blocked + :keycard-cancel-setup-text + :keycard-cancel-setup-title + :keycard-desc + :keycard-has-multiaccount-on-it + :keycard-onboarding-finishing-header + :keycard-onboarding-intro-header + :keycard-onboarding-intro-text + :keycard-onboarding-pairing-header + :keycard-onboarding-preparing-header + :keycard-onboarding-puk-code-header + :keycard-onboarding-recovery-phrase-description + :keycard-onboarding-recovery-phrase-header + :keycard-onboarding-recovery-phrase-text + :keycard-onboarding-start-header + :keycard-onboarding-start-step1 + :keycard-onboarding-start-step1-text + :keycard-onboarding-start-step2 + :keycard-onboarding-start-step2-text + :keycard-onboarding-start-step3 + :keycard-onboarding-start-step3-text + :keycard-onboarding-start-text + :keycard-recovery-intro-button-text + :keycard-recovery-intro-header + :keycard-recovery-intro-text + :keycard-recovery-no-key-header + :keycard-recovery-no-key-text + :keycard-recovery-phrase-confirm-header + :keycard-recovery-phrase-confirmation-text + :keycard-recovery-phrase-confirmation-title + :keycard-recovery-success-header + :keycard-unauthorized-operation + :language + :learn-more + :learn-more-about-keycard + :leave + :leave-group + :left + :les-ulc + :linked-on + :load-messages-before + :load-more-messages + :loading + :log-level + :log-level-settings + :logging + :logging-enabled + :login-pin-description + :logout + :logout-app-content + :logout-are-you-sure + :logout-title + :mailserver-address + :mailserver-automatic + :mailserver-connection-error + :mailserver-details + :mailserver-error-content + :mailserver-error-title + :mailserver-format + :mailserver-pick-another + :mailserver-reconnect + :mailserver-request-error-content + :mailserver-request-error-status + :mailserver-request-error-title + :mailserver-request-retry + :mailserver-retry + :main-currency + :main-networks + :main-wallet + :mainnet-network + :make-admin + :members + :members-active + :members-active-none + :members-title + :message + :message-not-sent + :message-options-cancel + :message-reply + :data-syncing + :messages + :might-break + :migrations-failed-content + :mobile-network-ask-me + :mobile-network-continue-syncing + :mobile-network-continue-syncing-details + :mobile-network-go-to-settings + :mobile-network-settings + :mobile-network-sheet-configure + :mobile-network-sheet-offline + :mobile-network-sheet-offline-details + :mobile-network-sheet-remember-choice + :mobile-network-sheet-settings + :mobile-network-start-syncing + :mobile-network-stop-syncing + :mobile-network-stop-syncing-details + :mobile-network-use-mobile + :mobile-network-use-mobile-data + :mobile-network-use-wifi + :mobile-syncing-sheet-details + :mobile-syncing-sheet-title + :more + :multiaccounts-recover-enter-phrase-text + :multiaccounts-recover-enter-phrase-title + :name + :name-of-token + :need-help + :network + :network-chain + :network-details + :network-fee + :network-id + :network-invalid-network-id + :network-invalid-status-code + :network-invalid-url + :network-settings + :new + :new-chat + :new-contact + :new-contract + :new-group + :new-group-chat + :new-network + :new-pin-description + :new-public-group-chat + :next + :no + :no-collectibles + :no-contacts + :no-keycard-applet-on-card + :no-messages + :no-pairing-slots-available + :no-result + :no-tokens-found + :node-info + :node-version + :nonce + :none + :not-applicable + :not-keycard-text + :not-keycard-title + :notifications + :notify + :off + :offline + :ok + :ok-continue + :ok-got-it + :okay + :on + :open + :open-dapp + :open-dapp-store + :open-nfc-settings + :open-on-block-explorer + :optional + :outgoing + :pair + :pair-card + :pair-code + :pair-code-explanation + :pair-this-card + :pair-this-device + :pair-this-device-description + :paired-devices + :pairing + :pairing-card + :pairing-go-to-installation + :pairing-maximum-number-reached-content + :pairing-maximum-number-reached-title + :pairing-new-installation-detected-content + :pairing-new-installation-detected-title + :pairing-no-info + :pairing-please-set-a-name + :passphrase + :password + :password-description + :password-placeholder2 + :password_error1 + :paste + :paste-json + :pay-to-chat + :peers + :pending + :pending-confirmation + :permissions + :phone-e164 + :photos-access-error + :pin-changed + :pin-code + :pin-mismatch + :preview-privacy + :privacy + :privacy-and-security + :privacy-policy + :processing + :product-information + :profile + :public-chat + :public-chats + :public-group-status + :public-group-topic + :public-key + :puk-and-pairing-codes-displayed + :puk-code + :puk-code-explanation + :puk-mismatch + :quiet-days + :quiet-hours + :re-encrypt-key + :receive + :receive-transaction + :recent + :recent-recipients + :recently-used-stickers + :recipient + :recipient-code + :recover + :recover-key + :recover-keycard-multiaccount-not-supported + :recover-with-keycard + :recovering-key + :recovery-confirm-phrase + :recovery-phrase + :recovery-success-text + :recovery-typo-dialog-description + :recovery-typo-dialog-title + :remember-me + :remind-me-later + :remove + :remove-from-chat + :remove-network + :remove-token + :removed + :repeat-pin + :report-bug-email-template + :request-transaction + :required-field + :resend-message + :reset-card + :reset-card-description + :retry + :revoke-access + :rpc-url + :save + :save-password + :save-password-unavailable + :save-password-unavailable-android + :scan-qr + :scan-qr-code + :search + :secret-keys-confirmation-text + :secret-keys-confirmation-title + :security + :see-details + :see-it-again + :select-chat + :selected + :send-logs + :send-logs-to + :send-message + :send-request + :send-request-amount + :send-request-amount-max-decimals + :send-request-unknown-token + :send-sending-to + :send-transaction + :sending + :sent-at + :set-a-topic + :set-currency + :set-dapp-access-permissions + :settings + :share + :share-address + :share-chat + :share-contact-code + :share-dapp-text + :share-link + :share-my-profile + :share-profile + :share-profile-link + :share-public-chat-text + :sharing-copied-to-clipboard + :sharing-copy-to-clipboard + :sharing-share + :show-less + :show-more + :show-qr + :sign-in + :sign-message + :sign-out + :sign-with + :sign-with-password + :sign-you-in + :signing + :signing-a-message + :signing-phrase + :something-went-wrong + :soon + :specify-address + :specify-name + :specify-network-id + :specify-rpc-url + :start-chat + :start-conversation + :start-group-chat + :start-new-chat + :status + :status-confirmed + :status-keycard + :status-hardwallet + :status-not-sent-click + :status-not-sent-tap + :status-pending + :status-sent + :status-tx-not-found + :step-i-of-n + :sticker-market + :submit + :submit-bug + :success + :symbol + :sync-all-devices + :sync-in-progress + :sync-settings + :sync-synced + :syncing-devices + :tag-was-lost + :test-networks + :text-input-disabled + :this-device + :this-device-desc + :this-is-you-signing + :this-will-take-few-seconds + :three-words-description + :three-words-description-2 + :to + :to-block + :to-encrypt-enter-password + :to-see-this-message + :token-auto-validate-decimals-error + :token-auto-validate-name-error + :token-auto-validate-symbol-error + :token-details + :topic-name-error + :transaction + :transaction-description + :transaction-details + :transaction-failed + :transaction-history + :transaction-request + :transaction-sent + :transactions + :transactions-filter-select-all + :transactions-filter-title + :type + :transactions-history + :transactions-history-empty + :transactions-sign + :tribute-required-by-multiaccount + :tribute-state-paid + :tribute-state-pending + :tribute-state-required + :tribute-to-talk + :tribute-to-talk-add-friends + :tribute-to-talk-are-you-friends + :tribute-to-talk-ask-to-be-added + :tribute-to-talk-contact-received-your-tribute + :tribute-to-talk-desc + :tribute-to-talk-disabled + :tribute-to-talk-disabled-note + :tribute-to-talk-enabled + :tribute-to-talk-finish-desc + :tribute-to-talk-learn-more-1 + :tribute-to-talk-learn-more-2 + :tribute-to-talk-learn-more-3 + :tribute-to-talk-paywall-learn-more-1 + :tribute-to-talk-paywall-learn-more-2 + :tribute-to-talk-paywall-learn-more-3 + :tribute-to-talk-pending + :tribute-to-talk-pending-note + :tribute-to-talk-removing-note + :tribute-to-talk-set-snt-amount + :tribute-to-talk-signing + :tribute-to-talk-transaction-failed-note + :tribute-to-talk-tribute-received1 + :tribute-to-talk-tribute-received2 + :tribute-to-talk-you-require-snt + :try-again + :turn-nfc-on + :type-a-message + :ulc-enabled + :unable-to-read-this-code + :unblock-contact + :unknown-status-go-error + :unlock + :unpair-card + :unpair-card-confirmation + :unpaired-keycard-text + :unpaired-keycard-title + :update + :url + :usd-currency + :use-valid-contact-code + :validation-amount-invalid-number + :validation-amount-is-too-precise + :version + :view-cryptokitties + :view-cryptostrikers + :view-etheremon + :view-gitcoin + :view-profile + :view-signing + :view-superrare + :waiting-for-wifi + :waiting-for-wifi-change + :waiting-to-sign + :wallet + :wallet-asset + :wallet-assets + :wallet-backup-recovery-title + :wallet-choose-recipient + :wallet-collectibles + :wallet-insufficient-funds + :wallet-insufficient-gas + :wallet-invalid-address + :wallet-invalid-address-checksum + :wallet-invalid-chain-id + :wallet-manage-assets + :wallet-request + :wallet-send + :wallet-send-min-wei + :wallet-settings + :wallet-total-value + :wallet-transaction-total-fee + :wants-to-access-profile + :warning + :warning-message + :web-view-error + :welcome-screen-text + :welcome-to-status + :welcome-to-status-description + :word-n + :word-n-description + :words-n + :write-down-and-store-securely + :wrong-address + :wrong-card + :wrong-card-text + :wrong-contract + :wrong-keycard-text + :wrong-keycard-title + :wrong-password + :wrong-word + :yes + :you + :you-already-have-an-asset + :you-are-all-set + :you-are-all-set-description + :you-can-change-account + :you-dont-have-stickers + :your-contact-code + :your-data-belongs-to-you + :your-data-belongs-to-you-description + :your-recovery-phrase + :your-recovery-phrase-description}) + +;; NOTE: the rest checkpoints are based on the previous one, defined +;; like this: +;; (def checkpoint-2-labels (set/union checkpoint-1-labels #{:foo :bar}) +;; (def checkpoint-3-labels (set/union checkpoint-2-labels #{:baz}) + +;; NOTE: This defines the scope of each checkpoint. To support a checkpoint, +;; change the var `checkpoint-to-consider-locale-supported` a few lines +;; below. +(def checkpoints-def (spec/assert ::checkpoint-defs + {::checkpoint-1-0-0-rc1 checkpoint-1-0-0-rc1-labels})) +(def checkpoints (set (keys checkpoints-def))) + +(spec/def ::checkpoint checkpoints) + +(def checkpoint-to-consider-locale-supported ::checkpoint-1-0-0-rc1) + +(defn checkpoint->labels [checkpoint] + (get checkpoints-def checkpoint)) + +(defn checkpoint-val-to-compare [c] + (-> c name (string/replace #"^.*\|" "") js/parseInt)) + +(defn >checkpoints [& cs] + (apply > (map checkpoint-val-to-compare cs))) + +;; locales + +(def locales (set (keys i18n-resources/translations-by-locale))) + +(spec/def ::locale locales) +(spec/def ::locales (spec/coll-of ::locale :kind set? :into #{})) + +(defn locale->labels [locale] + (-> i18n-resources/translations-by-locale (get locale) (js->clj :keywordize-keys true) keys set)) + +(defn locale->checkpoint [locale] + (let [locale-labels (locale->labels locale) + checkpoint (->> checkpoints-def + (filter (fn [[_ checkpoint-labels]] + (set/subset? checkpoint-labels locale-labels))) + ffirst)] + checkpoint)) + +(defn locale-is-supported-based-on-translations? [locale] + (let [c (locale->checkpoint locale)] + (and c (or (= c checkpoint-to-consider-locale-supported) + (>checkpoints checkpoint-to-consider-locale-supported c))))) + +(defn actual-supported-locales [] + (->> locales + (filter locale-is-supported-based-on-translations?) + set)) + +;; NOTE: Add new locale keywords here to indicate support for them. +#_(def supported-locales (spec/assert ::locales #{:fr + :zh + :zh-hans + :zh-hans-cn + :zh-hans-mo + :zh-hant + :zh-hant-sg + :zh-hant-hk + :zh-hant-tw + :zh-hant-mo + :zh-hant-cn + :sr-RS_#Cyrl + :el + :en + :de + :lt + :sr-RS_#Latn + :sr + :sv + :ja + :uk})) +(def supported-locales (spec/assert ::locales #{:en})) + +(spec/def ::supported-locale supported-locales) +(spec/def ::supported-locales (spec/coll-of ::supported-locale :kind set? :into #{})) + +(deftest label-options + (is (not (nil? (:key (i18n/label-options {:key nil})))))) + +(deftest locales-only-have-existing-tran-ids + (is (spec/valid? ::labels (labels-for-all-locales)) + (->> locales + (remove #(spec/valid? ::labels (locale->labels %))) + (map (fn [l] + (str "Extra translations in locale " l "\n" + (set/difference (locale->labels l) labels) + "\n\n"))) + (apply str)))) + +(deftest supported-locales-are-actually-supported + (is (set/subset? supported-locales (actual-supported-locales)) + (->> supported-locales + (remove locale-is-supported-based-on-translations?) + (map (fn [l] + (str "Missing translations in supported locale " l "\n" + (set/difference (checkpoint->labels checkpoint-to-consider-locale-supported) + (locale->labels l)) + "\n\n"))) + (apply str)))) diff --git a/src/status_im2/setup/log.cljs b/src/status_im2/setup/log.cljs new file mode 100644 index 0000000000..251bddf20d --- /dev/null +++ b/src/status_im2/setup/log.cljs @@ -0,0 +1,39 @@ +(ns status-im2.setup.log + (:require [taoensso.timbre :as log] + [clojure.string :as string] + [re-frame.core :as re-frame] + [status-im2.setup.config :as config] + ;; TODO (14/11/22 flexsurfer move to status-im2 namespace + [status-im.utils.fx :as fx])) + +(def logs-queue (atom #queue[])) +(def max-log-entries 1000) + +(defn get-logs-queue [] @logs-queue) + +(defn add-log-entry [entry] + (swap! logs-queue conj entry) + (when (>= (count @logs-queue) max-log-entries) + (swap! logs-queue pop))) + +(defn setup [level] + (when-not (string/blank? level) + (log/set-level! (-> level + string/lower-case + keyword)) + (log/merge-config! + {:output-fn (fn [& data] + (let [res (apply log/default-output-fn data)] + (add-log-entry res) + res))}))) + +(re-frame/reg-fx + :logs/set-level + (fn [level] + (setup level))) + +(fx/defn set-log-level + [{:keys [db]} log-level] + (let [log-level (or log-level config/log-level)] + {:db (assoc-in db [:multiaccount :log-level] log-level) + :logs/set-level log-level})) diff --git a/src/status_im/subs/activity_center.cljs b/src/status_im2/subs/activity_center.cljs similarity index 98% rename from src/status_im/subs/activity_center.cljs rename to src/status_im2/subs/activity_center.cljs index 3dc0c88093..8a3ce0fb52 100644 --- a/src/status_im/subs/activity_center.cljs +++ b/src/status_im2/subs/activity_center.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.activity-center +(ns status-im2.subs.activity-center (:require [re-frame.core :as re-frame] [status-im.utils.datetime :as datetime] [status-im.multiaccounts.core :as multiaccounts] diff --git a/src/status_im/subs/bootnodes.cljs b/src/status_im2/subs/bootnodes.cljs similarity index 93% rename from src/status_im/subs/bootnodes.cljs rename to src/status_im2/subs/bootnodes.cljs index f5e3d77132..32c4a637b6 100644 --- a/src/status_im/subs/bootnodes.cljs +++ b/src/status_im2/subs/bootnodes.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.bootnodes +(ns status-im2.subs.bootnodes (:require [re-frame.core :as re-frame])) (re-frame/reg-sub diff --git a/src/status_im/subs/browser.cljs b/src/status_im2/subs/browser.cljs similarity index 89% rename from src/status_im/subs/browser.cljs rename to src/status_im2/subs/browser.cljs index 707c46a345..7c20ac16d8 100644 --- a/src/status_im/subs/browser.cljs +++ b/src/status_im2/subs/browser.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.browser +(ns status-im2.subs.browser (:require [re-frame.core :as re-frame] [status-im.browser.core :as browser])) diff --git a/src/status_im/subs/chat/chats.cljs b/src/status_im2/subs/chat/chats.cljs similarity index 99% rename from src/status_im/subs/chat/chats.cljs rename to src/status_im2/subs/chat/chats.cljs index bc391486dd..f381f8afac 100644 --- a/src/status_im/subs/chat/chats.cljs +++ b/src/status_im2/subs/chat/chats.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.chat.chats +(ns status-im2.subs.chat.chats (:require [re-frame.core :as re-frame] [clojure.string :as string] [status-im.constants :as constants] diff --git a/src/status_im/subs/chat/messages.cljs b/src/status_im2/subs/chat/messages.cljs similarity index 99% rename from src/status_im/subs/chat/messages.cljs rename to src/status_im2/subs/chat/messages.cljs index 1bfa22f1a7..297bc8f158 100644 --- a/src/status_im/subs/chat/messages.cljs +++ b/src/status_im2/subs/chat/messages.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.chat.messages +(ns status-im2.subs.chat.messages (:require [re-frame.core :as re-frame] [status-im.chat.models.reactions :as models.reactions] [status-im.chat.models.message-list :as models.message-list] diff --git a/src/status_im/subs/communities.cljs b/src/status_im2/subs/communities.cljs similarity index 99% rename from src/status_im/subs/communities.cljs rename to src/status_im2/subs/communities.cljs index 7435538809..073687fe6f 100644 --- a/src/status_im/subs/communities.cljs +++ b/src/status_im2/subs/communities.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.communities +(ns status-im2.subs.communities (:require [re-frame.core :as re-frame] [clojure.string :as string] [status-im.multiaccounts.core :as multiaccounts] diff --git a/src/status_im/subs/contact.cljs b/src/status_im2/subs/contact.cljs similarity index 99% rename from src/status_im/subs/contact.cljs rename to src/status_im2/subs/contact.cljs index 8da21b79bc..10fcfee2a4 100644 --- a/src/status_im/subs/contact.cljs +++ b/src/status_im2/subs/contact.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.contact +(ns status-im2.subs.contact (:require [re-frame.core :as re-frame] [status-im.contact.db :as contact.db] [status-im.utils.image-server :as image-server] diff --git a/src/status_im/subs/ens.cljs b/src/status_im2/subs/ens.cljs similarity index 99% rename from src/status_im/subs/ens.cljs rename to src/status_im2/subs/ens.cljs index bfd239ec7d..6754dcf184 100644 --- a/src/status_im/subs/ens.cljs +++ b/src/status_im2/subs/ens.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.ens +(ns status-im2.subs.ens (:require [re-frame.core :as re-frame] [status-im.ens.core :as ens] [status-im.ethereum.core :as ethereum] diff --git a/src/status_im/subs/general.cljs b/src/status_im2/subs/general.cljs similarity index 99% rename from src/status_im/subs/general.cljs rename to src/status_im2/subs/general.cljs index 7b69da8a9d..a616309c22 100644 --- a/src/status_im/subs/general.cljs +++ b/src/status_im2/subs/general.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.general +(ns status-im2.subs.general (:require [re-frame.core :as re-frame] [status-im.utils.build :as build] [status-im.multiaccounts.model :as multiaccounts.model] diff --git a/src/status_im/subs/home.cljs b/src/status_im2/subs/home.cljs similarity index 98% rename from src/status_im/subs/home.cljs rename to src/status_im2/subs/home.cljs index b3eba3fe90..0584c7b8cc 100644 --- a/src/status_im/subs/home.cljs +++ b/src/status_im2/subs/home.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.home +(ns status-im2.subs.home (:require [re-frame.core :as re-frame] [status-im.utils.config :as config])) diff --git a/src/status_im/subs/keycard.cljs b/src/status_im2/subs/keycard.cljs similarity index 99% rename from src/status_im/subs/keycard.cljs rename to src/status_im2/subs/keycard.cljs index 058922dde2..e1a7c701a2 100644 --- a/src/status_im/subs/keycard.cljs +++ b/src/status_im2/subs/keycard.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.keycard +(ns status-im2.subs.keycard (:require [re-frame.core :as re-frame] [status-im.keycard.common :as common] [status-im.utils.datetime :as utils.datetime] diff --git a/src/status_im/subs/mailservers.cljs b/src/status_im2/subs/mailservers.cljs similarity index 98% rename from src/status_im/subs/mailservers.cljs rename to src/status_im2/subs/mailservers.cljs index 80b53a7549..fcb2cd2006 100644 --- a/src/status_im/subs/mailservers.cljs +++ b/src/status_im2/subs/mailservers.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.mailservers +(ns status-im2.subs.mailservers (:require [re-frame.core :as re-frame] [status-im.mailserver.core :as mailserver] [status-im.fleet.core :as fleet])) diff --git a/src/status_im/subs/multiaccount.cljs b/src/status_im2/subs/multiaccount.cljs similarity index 98% rename from src/status_im/subs/multiaccount.cljs rename to src/status_im2/subs/multiaccount.cljs index 0c3ee54f55..d7531d91c4 100644 --- a/src/status_im/subs/multiaccount.cljs +++ b/src/status_im2/subs/multiaccount.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.multiaccount +(ns status-im2.subs.multiaccount (:require [re-frame.core :as re-frame] [status-im.multiaccounts.core :as multiaccounts] [status-im.ethereum.core :as ethereum] diff --git a/src/status_im/subs/networks.cljs b/src/status_im2/subs/networks.cljs similarity index 97% rename from src/status_im/subs/networks.cljs rename to src/status_im2/subs/networks.cljs index 8eb00389ea..7a37aeab60 100644 --- a/src/status_im/subs/networks.cljs +++ b/src/status_im2/subs/networks.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.networks +(ns status-im2.subs.networks (:require [status-im.ethereum.core :as ethereum] [re-frame.core :as re-frame] [status-im.utils.config :as config])) diff --git a/src/status_im/subs/onboarding.cljs b/src/status_im2/subs/onboarding.cljs similarity index 97% rename from src/status_im/subs/onboarding.cljs rename to src/status_im2/subs/onboarding.cljs index b66a845fea..146d16dc5a 100644 --- a/src/status_im/subs/onboarding.cljs +++ b/src/status_im2/subs/onboarding.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.onboarding +(ns status-im2.subs.onboarding (:require [re-frame.core :as re-frame] [status-im.constants :as constants] [status-im.multiaccounts.recover.core :as recover])) diff --git a/src/status_im/subs/pairing.cljs b/src/status_im2/subs/pairing.cljs similarity index 86% rename from src/status_im/subs/pairing.cljs rename to src/status_im2/subs/pairing.cljs index a72a07f82b..8ada59472e 100644 --- a/src/status_im/subs/pairing.cljs +++ b/src/status_im2/subs/pairing.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.pairing +(ns status-im2.subs.pairing (:require [re-frame.core :as re-frame] [status-im.pairing.core :as pairing])) diff --git a/src/status_im/subs/root.cljs b/src/status_im2/subs/root.cljs similarity index 92% rename from src/status_im/subs/root.cljs rename to src/status_im2/subs/root.cljs index 7da6876928..74f398adae 100644 --- a/src/status_im/subs/root.cljs +++ b/src/status_im2/subs/root.cljs @@ -1,26 +1,26 @@ -(ns status-im.subs.root +(ns status-im2.subs.root (:require [re-frame.core :as re-frame] - status-im.subs.activity-center - status-im.subs.bootnodes - status-im.subs.browser - status-im.subs.communities - status-im.subs.contact - status-im.subs.chat.chats - status-im.subs.chat.messages - status-im.subs.ens - status-im.subs.general - status-im.subs.home - status-im.subs.keycard - status-im.subs.mailservers - status-im.subs.multiaccount - status-im.subs.networks - status-im.subs.onboarding - status-im.subs.pairing - status-im.subs.search - status-im.subs.stickers - status-im.subs.wallet.signing - status-im.subs.wallet.transactions - status-im.subs.wallet.wallet)) + status-im2.subs.activity-center + status-im2.subs.bootnodes + status-im2.subs.browser + status-im2.subs.communities + status-im2.subs.contact + status-im2.subs.chat.chats + status-im2.subs.chat.messages + status-im2.subs.ens + status-im2.subs.general + status-im2.subs.home + status-im2.subs.keycard + status-im2.subs.mailservers + status-im2.subs.multiaccount + status-im2.subs.networks + status-im2.subs.onboarding + status-im2.subs.pairing + status-im2.subs.search + status-im2.subs.stickers + status-im2.subs.wallet.signing + status-im2.subs.wallet.transactions + status-im2.subs.wallet.wallet)) (defn reg-root-key-sub [sub-name db-key] (re-frame/reg-sub sub-name (fn [db] (get db db-key)))) @@ -57,7 +57,6 @@ (reg-root-key-sub :get-pairing-installations :pairing/installations) (reg-root-key-sub :tooltips :tooltips) (reg-root-key-sub :supported-biometric-auth :supported-biometric-auth) -(reg-root-key-sub :app-active-since :app-active-since) (reg-root-key-sub :connectivity/ui-status-properties :connectivity/ui-status-properties) (reg-root-key-sub :logged-in-since :logged-in-since) (reg-root-key-sub :link-previews-whitelist :link-previews-whitelist) diff --git a/src/status_im/subs/search.cljs b/src/status_im2/subs/search.cljs similarity index 98% rename from src/status_im/subs/search.cljs rename to src/status_im2/subs/search.cljs index db521756c3..9f972cfb1f 100644 --- a/src/status_im/subs/search.cljs +++ b/src/status_im2/subs/search.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.search +(ns status-im2.subs.search (:require [clojure.string :as string]) (:require [clojure.string :as string] [status-im.utils.gfycat.core :as gfycat] diff --git a/src/status_im/subs/stickers.cljs b/src/status_im2/subs/stickers.cljs similarity index 91% rename from src/status_im/subs/stickers.cljs rename to src/status_im2/subs/stickers.cljs index c48365d8d7..8c116504c0 100644 --- a/src/status_im/subs/stickers.cljs +++ b/src/status_im2/subs/stickers.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.stickers +(ns status-im2.subs.stickers (:require [re-frame.core :as re-frame] [status-im.constants :as constants])) diff --git a/src/status_im/subs/subs_test.cljs b/src/status_im2/subs/subs_test.cljs similarity index 89% rename from src/status_im/subs/subs_test.cljs rename to src/status_im2/subs/subs_test.cljs index dcca8cb9c5..6773feaf50 100644 --- a/src/status_im/subs/subs_test.cljs +++ b/src/status_im2/subs/subs_test.cljs @@ -1,9 +1,9 @@ -(ns status-im.subs.subs-test +(ns status-im2.subs.subs-test (:require [cljs.test :refer [deftest is testing]] - [status-im.subs.wallet.transactions :as wallet.transactions] - [status-im.subs.onboarding :as onboarding] + [status-im2.subs.wallet.transactions :as wallet.transactions] + [status-im2.subs.onboarding :as onboarding] [status-im.utils.money :as money] - [status-im.subs.wallet.wallet :as wallet])) + [status-im2.subs.wallet.wallet :as wallet])) (def transactions [{:timestamp "1505912551000"} {:timestamp "1505764322000"} diff --git a/src/status_im/subs/wallet/signing.cljs b/src/status_im2/subs/wallet/signing.cljs similarity index 98% rename from src/status_im/subs/wallet/signing.cljs rename to src/status_im2/subs/wallet/signing.cljs index 92e8d90ac3..558a5af7ab 100644 --- a/src/status_im/subs/wallet/signing.cljs +++ b/src/status_im2/subs/wallet/signing.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.wallet.signing +(ns status-im2.subs.wallet.signing (:require [re-frame.core :as re-frame] [status-im.ethereum.core :as ethereum] [status-im.utils.money :as money] diff --git a/src/status_im/subs/wallet/transactions.cljs b/src/status_im2/subs/wallet/transactions.cljs similarity index 99% rename from src/status_im/subs/wallet/transactions.cljs rename to src/status_im2/subs/wallet/transactions.cljs index 8a639873d6..f664f72a45 100644 --- a/src/status_im/subs/wallet/transactions.cljs +++ b/src/status_im2/subs/wallet/transactions.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.wallet.transactions +(ns status-im2.subs.wallet.transactions (:require [re-frame.core :as re-frame] [status-im.utils.money :as money] [status-im.i18n.i18n :as i18n] diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im2/subs/wallet/wallet.cljs similarity index 98% rename from src/status_im/subs/wallet/wallet.cljs rename to src/status_im2/subs/wallet/wallet.cljs index a17df09304..c11899de5c 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im2/subs/wallet/wallet.cljs @@ -1,4 +1,4 @@ -(ns status-im.subs.wallet.wallet +(ns status-im2.subs.wallet.wallet (:require [re-frame.core :as re-frame] [status-im.ethereum.core :as ethereum] [status-im.utils.money :as money] diff --git a/src/utils.cljs b/src/utils.cljs index 8dd37a9633..2bd371a747 100644 --- a/src/utils.cljs +++ b/src/utils.cljs @@ -1,7 +1,5 @@ (ns utils - (:require [clojure.string :as string] - [goog.string :as gstring] - [goog.string.format])) + (:require [goog.string.format])) (defn naive-round "Quickly and naively round number `n` up to `decimal-places`. @@ -17,63 +15,6 @@ (/ (Math/round (* n scale)) scale))) -(defn- caught-invalid-number [] - (throw (js/Error "Invalid Number"))) - -(defn- with-precision [precision input-number] - (gstring/format (str "%." precision "f") input-number)) - -(defn- is-bad-number [number-string] - (nil? (re-find #"^\d+(\.\d{1,9})?$" number-string))) - -(defn- with-precision-division [numerator-num denominator-num precision] - (->> (/ numerator-num denominator-num) - (with-precision precision))) - -(defn- number->formatted-number [number-string precision] - (let [parsed-number (js/parseInt number-string 10) - numeric-value (if (or (neg? number-string) - (is-bad-number (str number-string))) - (caught-invalid-number) - parsed-number) - million 1000000 - billion 1000000000 - >=-and-< #(and - (>= %1 %2) - (< %1 %3)) - unit (cond - (>=-and-< parsed-number billion js/Number.MAX_SAFE_INTEGER) "b" - (>=-and-< parsed-number million billion) "m" - :else - "k") - denominator (cond - (= unit "m") million - (= unit "b") billion - :else 1000)] - (if (js/isNaN numeric-value) - (caught-invalid-number) - (if (>= numeric-value 1000) - (str (with-precision-division numeric-value denominator precision) - unit) - (str numeric-value))))) - -(defn format-number - "Returns the thousands in a number in kilo format - - Arguments: - - number-string (or string int) The input of value of the number - - Examples: - [1000 0] -> 1k - [1001 0] -> 1k - [10000 0] -> 10k - [5000 0] -> 5k - [5000 0] -> 5k - [5000000 0] -> 5m - [5000 0] -> 5k" - [number-string precision] - (number->formatted-number number-string precision)) (defn truncate-str-memo "Given string and max threshold, trims the string to threshold length with `...` appended to end or in the middle if length of the string exceeds max threshold, @@ -93,12 +34,6 @@ (def truncate-str (memoize truncate-str-memo)) -(defn clean-text [s] - (-> s - (string/replace #"\n" "") - (string/replace #"\r" "") - (string/trim))) - (defn first-index "Returns first index in coll where predicate on coll element is truthy" [pred coll] @@ -108,31 +43,6 @@ idx))) first)) -(defn hash-tag? [s] - (= \# (first s))) - -(defn update-if-present - "Like regular `clojure.core/update` but returns original map if update key is not present" - [m k f & args] - (if (contains? m k) - (apply update m k f args) - m)) - -(defn map-values - "Efficiently apply function to all map values" - [f m] - (into {} - (map (fn [[k v]] - [k (f v)])) - m)) - -(defn deep-merge - "Recursively merge maps" - [& maps] - (if (every? map? maps) - (apply merge-with deep-merge maps) - (last maps))) - (defn index-by "Given a collection and a unique key function, returns a map that indexes the collection. Similar to group-by except that the map values are single objects (depends on key uniqueness)."