Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9b18a29f9 |
@@ -0,0 +1,185 @@
|
|||||||
|
status-im.utils.build/warning-handler
|
||||||
|
status-im.utils.build/get-current-sha
|
||||||
|
status-im2.constants/spacing-char
|
||||||
|
status-im2.constants/arg-wrapping-char
|
||||||
|
status-im.ios.core/init
|
||||||
|
status-im.ui.components.camera/aspects
|
||||||
|
status-im.ui.components.camera/capture-targets
|
||||||
|
status-im.ui.components.camera/set-torch
|
||||||
|
status-im.ui.components.camera/request-access-ios
|
||||||
|
status-im.chat.models.message-content/stylings
|
||||||
|
status-im.chat.models.message-content/actions
|
||||||
|
status-im.chat.models.message-content/blank-string
|
||||||
|
status-im.chat.models.message-content/sorted-ranges
|
||||||
|
status-im.ethereum.mnemonic/words->passphrase
|
||||||
|
native-module.core/listener
|
||||||
|
native-module.core/multiaccount-reset
|
||||||
|
native-module.core/extract-group-membership-signatures
|
||||||
|
native-module.core/sign-group-membership
|
||||||
|
native-module.core/update-mailservers
|
||||||
|
status-im.ethereum.abi-spec/bytes-to-hex
|
||||||
|
status-im.android.core/init
|
||||||
|
status-im.chat.models.message/transport-keys
|
||||||
|
status-im.utils.datetime/week
|
||||||
|
status-im.utils.datetime/time-ago
|
||||||
|
status-im.utils.datetime/format-date
|
||||||
|
status-im.utils.datetime/get-ordinal-date
|
||||||
|
reagent.dom/render
|
||||||
|
reagent.dom/unmount-component-at-node
|
||||||
|
reagent.dom/dom-node
|
||||||
|
reagent.dom/force-update-all
|
||||||
|
status-im.multiaccounts.create.core/get-new-key-code
|
||||||
|
status-im.ethereum.decode/string
|
||||||
|
status-im.ui.screens.network.views/mainnet?
|
||||||
|
status-im.data-store.chats/event->string
|
||||||
|
status-im.mailserver.constants/seven-days
|
||||||
|
status-im.mailserver.constants/connection-timeout
|
||||||
|
status-im.hardwallet.card/install-applet
|
||||||
|
status-im.hardwallet.card/install-cash-applet
|
||||||
|
status-im.multiaccount.login.data-test/all-contacts
|
||||||
|
status-im.multiaccount.login.data-test/multiaccounts
|
||||||
|
status-im.multiaccount.login.data-test/get-chats
|
||||||
|
status-im.multiaccount.login.data-test/transport
|
||||||
|
status-im.multiaccount.login.data-test/topics
|
||||||
|
status-im.utils.utils/clear-timeout
|
||||||
|
status-im.utils.handlers/logged-in
|
||||||
|
status-im.multiaccounts.model/credentials
|
||||||
|
status-im.multiaccounts.login.core/contract-fleet?
|
||||||
|
status-im.multiaccounts.login.core/fetch-nodes
|
||||||
|
status-im2.config/rpc-networks-only?
|
||||||
|
status-im2.config/waku-enabled?
|
||||||
|
status-im.utils.pairing/has-paired-installations?
|
||||||
|
status-im.tribute-to-talk.core-test/user-cofx
|
||||||
|
mocks.js-dependencies/action-button
|
||||||
|
mocks.js-dependencies/camera
|
||||||
|
mocks.js-dependencies/dismiss-keyboard
|
||||||
|
mocks.js-dependencies/emoji-picker
|
||||||
|
mocks.js-dependencies/i18n
|
||||||
|
mocks.js-dependencies/qr-code
|
||||||
|
mocks.js-dependencies/svg
|
||||||
|
mocks.js-dependencies/icons
|
||||||
|
mocks.js-dependencies/webview
|
||||||
|
mocks.js-dependencies/desktop-linking
|
||||||
|
mocks.js-dependencies/desktop-shortcuts
|
||||||
|
mocks.js-dependencies/snoopy
|
||||||
|
mocks.js-dependencies/snoopy-filter
|
||||||
|
mocks.js-dependencies/snoopy-bars
|
||||||
|
mocks.js-dependencies/snoopy-buffer
|
||||||
|
mocks.js-dependencies/desktop-menu
|
||||||
|
mocks.js-dependencies/desktop-config
|
||||||
|
mocks.js-dependencies/react-native-navigation-twopane
|
||||||
|
mocks.js-dependencies/react-native-screens
|
||||||
|
mocks.js-dependencies/react-native-shake
|
||||||
|
mocks.js-dependencies/back-handler
|
||||||
|
mocks.js-dependencies/react
|
||||||
|
mocks.js-dependencies/react-navigation-native
|
||||||
|
mocks.js-dependencies/react-navigation-stack
|
||||||
|
mocks.js-dependencies/react-navigation-bottom-tabs
|
||||||
|
mocks.js-dependencies/react-native-haptic-feedback
|
||||||
|
mocks.js-dependencies/mock
|
||||||
|
quo.previews.main/init
|
||||||
|
status-im.chat.models.message-list-test/descending-range
|
||||||
|
status-im.chat.models.message-list-test/random-range
|
||||||
|
status-im.ethereum.eip165/supports?
|
||||||
|
status-im.utils.hex/valid-hex?
|
||||||
|
status-im.multiaccounts.core/chat-send?
|
||||||
|
status-im.hardwallet.simulated-keycard/install-cash-applet
|
||||||
|
status-im.hardwallet.simulated-keycard/sign-typed-data
|
||||||
|
status-im.utils.core/safe-read-message-content
|
||||||
|
status-im.ui.components.react/native-modules
|
||||||
|
status-im.ui.components.react/progress-bar
|
||||||
|
react-native.fs/move-file
|
||||||
|
react-native.fs/read-dir
|
||||||
|
react-native.fs/mkdir
|
||||||
|
react-native.fs/unlink
|
||||||
|
react-native.fs/file-exists?
|
||||||
|
status-im.ui.components.colors/white
|
||||||
|
status-im.ui.components.colors/black
|
||||||
|
status-im.ui.components.core/animated-header
|
||||||
|
status-im.ui.components.core/safe-area-provider
|
||||||
|
status-im.ui.components.core/safe-area-consumer
|
||||||
|
status-im.ui.components.core/safe-area-view
|
||||||
|
status-im.utils.universal-links.core/open!
|
||||||
|
status-im.transport.filters.core-test/member-2
|
||||||
|
status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
|
||||||
|
status-im.ethereum.ens/ttl
|
||||||
|
status-im.ethereum.ens/addr-hash
|
||||||
|
status-im.ethereum.ens/name-hash
|
||||||
|
status-im.ethereum.ens/ABI-hash
|
||||||
|
status-im.ethereum.ens/pubkey-hash
|
||||||
|
status-im.network.core/get-network
|
||||||
|
status-im2.constants/desktop-content-types
|
||||||
|
status-im2.constants/blocks-per-hour
|
||||||
|
status-im2.constants/one-earth-day
|
||||||
|
status-im2.constants/left-pane-min-width
|
||||||
|
status-im2.constants/system
|
||||||
|
status-im2.constants/contact-discovery
|
||||||
|
status-im2.constants/send-transaction-failed-parse-response
|
||||||
|
status-im2.constants/send-transaction-failed-parse-params
|
||||||
|
status-im2.constants/send-transaction-no-account-selected
|
||||||
|
status-im2.constants/send-transaction-invalid-tx-sender
|
||||||
|
status-im2.constants/web3-get-logs
|
||||||
|
status-im2.constants/web3-transaction-receipt
|
||||||
|
status-im2.constants/web3-new-filter
|
||||||
|
status-im2.constants/web3-new-pending-transaction-filter
|
||||||
|
status-im2.constants/web3-new-block-filter
|
||||||
|
status-im2.constants/web3-uninstall-filter
|
||||||
|
status-im2.constants/web3-get-filter-changes
|
||||||
|
status-im2.constants/web3-shh-post
|
||||||
|
status-im2.constants/web3-shh-new-identity
|
||||||
|
status-im2.constants/web3-shh-has-identity
|
||||||
|
status-im2.constants/web3-shh-new-group
|
||||||
|
status-im2.constants/web3-shh-add-to-group
|
||||||
|
status-im2.constants/web3-shh-new-filter
|
||||||
|
status-im2.constants/web3-shh-uninstall-filter
|
||||||
|
status-im2.constants/web3-shh-get-filter-changes
|
||||||
|
status-im2.constants/web3-shh-get-messages
|
||||||
|
status-im2.constants/status-create-address
|
||||||
|
status-im2.constants/event-transfer-hash
|
||||||
|
status-im2.constants/regx-rtl-characters
|
||||||
|
status-im2.constants/desktop-msg-chars-hard-limit
|
||||||
|
status-im2.constants/debug-metrics
|
||||||
|
status-im2.constants/scan-qr-code
|
||||||
|
status-im2.constants/ipfs-proto-code
|
||||||
|
status-im2.constants/swarm-proto-code
|
||||||
|
status-im.multiaccounts.update.publisher/publish-update!
|
||||||
|
status-im.utils.async/task-queue
|
||||||
|
status-im.utils.async/async-periodic-run!
|
||||||
|
status-im.desktop.core/app-root
|
||||||
|
status-im.desktop.core/init
|
||||||
|
status-im.chat.models-test/test-db
|
||||||
|
status-im.ui.components.spacing/padding-vertical
|
||||||
|
status-im.utils.money/percent-change
|
||||||
|
utils.debounce/clear-all
|
||||||
|
status-im.transport.db/create-chat
|
||||||
|
status-im.utils.priority-map/priority-map
|
||||||
|
status-im.utils.priority-map/priority-map-by
|
||||||
|
status-im.utils.priority-map/priority-map-keyfn
|
||||||
|
status-im.utils.priority-map/empty-message-map
|
||||||
|
status-im.wallet.choose-recipient.core/use-default-eth-gas
|
||||||
|
status-im.ui.components.animation/decay
|
||||||
|
status-im.ui.components.animation/remove-all-listeners
|
||||||
|
status-im.ui.components.animation/stop-animation
|
||||||
|
status-im.ui.components.animation/animated
|
||||||
|
status-im.ui.components.animation/add
|
||||||
|
status-im.ui.components.animation/subtract
|
||||||
|
status-im.ui.components.animation/get-layout
|
||||||
|
status-im.wallet.transactions-test/uri-query-data
|
||||||
|
status-im.utils.name/shortened-name
|
||||||
|
status-im.ui.components.button.haptic/trigger
|
||||||
|
status-im.contact.db/filter-dapps
|
||||||
|
status-im.contact.db/filter-group-contacts
|
||||||
|
status-im.contact.db/legacy-pending?
|
||||||
|
status-im.utils.transducers-test/preview-call-1
|
||||||
|
status-im.utils.transducers-test/preview-call-2
|
||||||
|
status-im.utils.types/to-string
|
||||||
|
status-im.chat.db/datemark?
|
||||||
|
status-im.chat.db/gap?
|
||||||
|
status-im.chat.db/map->sorted-seq
|
||||||
|
status-im.utils.snoopy/status-module-filter
|
||||||
|
status-im.utils.snoopy/websocket-filter
|
||||||
|
status-im.utils.snoopy/touches-filter
|
||||||
|
status-im.utils.snoopy/native-animation-filter
|
||||||
|
status-im.utils.snoopy/keyboard-observer-filter
|
||||||
|
status-im.utils.multihash/hex
|
||||||
|
status-im.utils.multihash/decode-array
|
||||||
@@ -1,84 +1,49 @@
|
|||||||
{:config-paths ["status-im"]
|
{:config-paths ["status-im"]
|
||||||
:output {:exclude-files ["src/user.cljs" "src/dev/user.cljs"]}
|
:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||||
:lint-as {legacy.status-im.utils.views/defview clojure.core/defn
|
status-im.utils.views/letsubs clojure.core/let
|
||||||
legacy.status-im.utils.views/letsubs clojure.core/let
|
reagent.core/with-let clojure.core/let
|
||||||
reagent.core/with-let clojure.core/let
|
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||||
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||||
utils.re-frame/defn clojure.core/defn
|
quo.react/with-deps-check clojure.core/fn
|
||||||
quo.react/with-deps-check clojure.core/fn
|
quo.previews.preview/list-comp clojure.core/for
|
||||||
quo.previews.preview/list-comp clojure.core/for
|
status-im.utils.styles/def clojure.core/def
|
||||||
legacy.status-im.utils.styles/def clojure.core/def
|
status-im.utils.styles/defn clojure.core/defn
|
||||||
legacy.status-im.utils.styles/defn clojure.core/defn
|
test-helpers.unit/deftest-sub clojure.core/defn
|
||||||
test-helpers.unit/deftest-sub clojure.core/defn
|
taoensso.tufte/defnp clojure.core/defn}
|
||||||
test-helpers.unit/deftest-event clojure.core/defn
|
:linters {:case-duplicate-test {:level :error}
|
||||||
|
|
||||||
taoensso.tufte/defnp clojure.core/defn}
|
|
||||||
:linters {:clojure-lsp/unused-public-var {:exclude-when-defined-by #{utils.re-frame/defn}
|
|
||||||
:exclude #{
|
|
||||||
;; even if we are not
|
|
||||||
;; using color now, we
|
|
||||||
;; will need it later
|
|
||||||
quo.foundations.colors
|
|
||||||
|
|
||||||
;; same for funcs from
|
|
||||||
;; native-module
|
|
||||||
native-module.core
|
|
||||||
|
|
||||||
;; some funcs used
|
|
||||||
;; temporarily during
|
|
||||||
;; development
|
|
||||||
test-helpers.component
|
|
||||||
test-helpers.unit
|
|
||||||
|
|
||||||
;; not sure if unused
|
|
||||||
;; functions here should
|
|
||||||
;; be removed:
|
|
||||||
keycard.keycard
|
|
||||||
react-native.fs}}
|
|
||||||
:case-duplicate-test {:level :error}
|
|
||||||
:case-quoted-test {:level :error}
|
:case-quoted-test {:level :error}
|
||||||
:case-symbol-test {:level :error}
|
:case-symbol-test {:level :error}
|
||||||
:clj-kondo-config {:level :error}
|
:clj-kondo-config {:level :error}
|
||||||
:cond-else {:level :error}
|
:cond-else {:level :error}
|
||||||
:condition-always-true {:level :error}
|
|
||||||
:conflicting-alias {:level :error}
|
|
||||||
:consistent-alias {:level :error
|
:consistent-alias {:level :error
|
||||||
:aliases {clojure.set set
|
:aliases {clojure.set set
|
||||||
clojure.string string
|
clojure.string string
|
||||||
clojure.walk walk
|
clojure.walk walk
|
||||||
malli.core malli
|
malli.core malli
|
||||||
malli.dev.pretty malli.pretty
|
malli.dev.pretty malli.pretty
|
||||||
malli.dev.virhe malli.virhe
|
malli.dev.virhe malli.virhe
|
||||||
malli.error malli.error
|
malli.error malli.error
|
||||||
malli.generator malli.generator
|
malli.generator malli.generator
|
||||||
malli.transform malli.transform
|
malli.transform malli.transform
|
||||||
malli.util malli.util
|
malli.util malli.util
|
||||||
promesa.core promesa
|
schema.core schema
|
||||||
schema.core schema
|
taoensso.timbre log}}
|
||||||
status-im.feature-flags ff
|
|
||||||
taoensso.timbre log}}
|
|
||||||
:deprecated-namespace {:level :warning}
|
:deprecated-namespace {:level :warning}
|
||||||
:docstring-blank {:level :error}
|
:docstring-blank {:level :error}
|
||||||
:equals-true {:level :error}
|
:equals-true {:level :error}
|
||||||
:inline-def {:level :error}
|
:inline-def {:level :error}
|
||||||
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
|
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||||
utils.re-frame/defn
|
|
||||||
utils.re-frame/merge]}
|
|
||||||
:loop-without-recur {:level :error}
|
:loop-without-recur {:level :error}
|
||||||
:minus-one {:level :error}
|
:minus-one {:level :error}
|
||||||
:misplaced-docstring {:level :error}
|
:misplaced-docstring {:level :error}
|
||||||
:missing-body-in-when {:level :error}
|
:missing-body-in-when {:level :error}
|
||||||
:missing-clause-in-try {:level :error}
|
:missing-clause-in-try {:level :error}
|
||||||
:missing-else-branch {:level :error}
|
:missing-else-branch {:level :error}
|
||||||
:multiple-async-in-deftest {:level :error}
|
|
||||||
:not-empty? {:level :error}
|
:not-empty? {:level :error}
|
||||||
:plus-one {:level :error}
|
:plus-one {:level :error}
|
||||||
:redundant-do {:level :error}
|
:redundant-do {:level :error}
|
||||||
:redundant-let {:level :error}
|
:redundant-let {:level :error}
|
||||||
:refer-all {:level :error}
|
:refer-all {:level :error}
|
||||||
;; ignore error in config itself saying that `:shadowed-fn-param` is unknown
|
|
||||||
#_{:clj-kondo/ignore [:clj-kondo-config]}
|
|
||||||
:shadowed-fn-param {:level :error}
|
|
||||||
:shadowed-var {:level :error
|
:shadowed-var {:level :error
|
||||||
;; We temporarily use :include to define an
|
;; We temporarily use :include to define an
|
||||||
;; allowlist of core Clojure vars. In the
|
;; allowlist of core Clojure vars. In the
|
||||||
@@ -86,11 +51,9 @@
|
|||||||
;; vars, we should be able to delete this
|
;; vars, we should be able to delete this
|
||||||
;; option and lint all vars.
|
;; option and lint all vars.
|
||||||
:exclude [type name]}
|
:exclude [type name]}
|
||||||
:self-requiring-namespace {:level :error}
|
|
||||||
:single-operand-comparison {:level :error}
|
:single-operand-comparison {:level :error}
|
||||||
:syntax {:level :error}
|
:syntax {:level :error}
|
||||||
:unbound-destructuring-default {:level :error}
|
:unbound-destructuring-default {:level :error}
|
||||||
:underscore-in-namespace {:level :error}
|
|
||||||
:uninitialized-var {:level :error}
|
:uninitialized-var {:level :error}
|
||||||
:unknown-require-option {:level :error}
|
:unknown-require-option {:level :error}
|
||||||
:unreachable-code {:level :error}
|
:unreachable-code {:level :error}
|
||||||
@@ -99,8 +62,7 @@
|
|||||||
;; https://github.com/borkdude/clj-kondo/issues/867
|
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||||
number
|
number
|
||||||
legacy.status-im.test-helpers/restore-app-db
|
status-im.test-helpers/restore-app-db]}
|
||||||
(cljs.test/is [match-strict?])]}
|
|
||||||
:unresolved-var {:level :error}
|
:unresolved-var {:level :error}
|
||||||
:unsorted-required-namespaces {:level :error}
|
:unsorted-required-namespaces {:level :error}
|
||||||
:unused-alias {:level :warning}
|
:unused-alias {:level :warning}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{:lint-as {promesa.core/-> clojure.core/->
|
|
||||||
promesa.core/->> clojure.core/->>
|
|
||||||
promesa.core/as-> clojure.core/as->
|
|
||||||
promesa.core/let clojure.core/let
|
|
||||||
promesa.core/plet clojure.core/let
|
|
||||||
promesa.core/loop clojure.core/loop
|
|
||||||
promesa.core/recur clojure.core/recur
|
|
||||||
promesa.core/with-redefs clojure.core/with-redefs
|
|
||||||
promesa.core/doseq clojure.core/doseq}}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{:lint-as
|
|
||||||
{rewrite-clj.zip/subedit-> clojure.core/->
|
|
||||||
rewrite-clj.zip/subedit->> clojure.core/->>
|
|
||||||
rewrite-clj.zip/edit-> clojure.core/->
|
|
||||||
rewrite-clj.zip/edit->> clojure.core/->>}}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
(ns cljs.test
|
|
||||||
(:require [clj-kondo.hooks-api :as hooks]))
|
|
||||||
|
|
||||||
(defn deftest
|
|
||||||
"Verify test name passed to `cljs.test/deftest` is suffixed with -test and not
|
|
||||||
prefixed with test-."
|
|
||||||
[{:keys [node]}]
|
|
||||||
(let [[_ test-name-node & _] (:children node)
|
|
||||||
test-name (str (hooks/sexpr test-name-node))]
|
|
||||||
(when (and (hooks/token-node? test-name-node)
|
|
||||||
(or (not (re-find #"^.*-test$" test-name))
|
|
||||||
(re-find #"^test-.*$" test-name)))
|
|
||||||
(hooks/reg-finding! (assoc (meta test-name-node)
|
|
||||||
:message "Test name should be suffixed with -test"
|
|
||||||
:type :status-im.linter/inconsistent-test-name)))))
|
|
||||||
|
|
||||||
(comment
|
|
||||||
;; Invalid
|
|
||||||
(deftest {:node (hooks/parse-string "(deftest foo-tes (println :hello))")})
|
|
||||||
(deftest {:node (hooks/parse-string "(deftest test-foo-test (println :hello))")})
|
|
||||||
)
|
|
||||||
@@ -1,11 +1,2 @@
|
|||||||
{:hooks
|
{:hooks {:analyze-call {utils.i18n/label utils.i18n/label}}
|
||||||
{:analyze-call
|
:linters {:status-im.linter/invalid-translation-keyword {:level :error}}}
|
||||||
{utils.i18n/label utils.i18n/label
|
|
||||||
test-helpers.component/get-all-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/get-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/query-all-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/query-by-translation-text utils.i18n/label
|
|
||||||
|
|
||||||
cljs.test/deftest cljs.test/deftest}}
|
|
||||||
:linters {:status-im.linter/invalid-translation-keyword {:level :error}
|
|
||||||
:status-im.linter/inconsistent-test-name {:level :error}}}
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{:hooks {:analyze-call {taoensso.encore/defalias taoensso.encore/defalias}}}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
(ns taoensso.encore
|
|
||||||
(:require
|
|
||||||
[clj-kondo.hooks-api :as hooks]))
|
|
||||||
|
|
||||||
(defn defalias [{:keys [node]}]
|
|
||||||
(let [[sym-raw src-raw] (rest (:children node))
|
|
||||||
src (if src-raw src-raw sym-raw)
|
|
||||||
sym (if src-raw
|
|
||||||
sym-raw
|
|
||||||
(symbol (name (hooks/sexpr src))))]
|
|
||||||
{:node (with-meta
|
|
||||||
(hooks/list-node
|
|
||||||
[(hooks/token-node 'def)
|
|
||||||
(hooks/token-node (hooks/sexpr sym))
|
|
||||||
(hooks/token-node (hooks/sexpr src))])
|
|
||||||
(meta src))}))
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
DEV_BUILD=1
|
DEV_BUILD=1
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=info
|
LOG_LEVEL=info
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
@@ -24,6 +26,7 @@ APN_TOPIC=im.status.ethereum.pr
|
|||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
|
COLLECTIBLES_ENABLED=1
|
||||||
COMMANDS_ENABLED=1
|
COMMANDS_ENABLED=1
|
||||||
TWO_MINUTES_SYNCING=1
|
TWO_MINUTES_SYNCING=1
|
||||||
SWAP_ENABLED=1
|
SWAP_ENABLED=1
|
||||||
@@ -31,10 +34,3 @@ STICKERS_TEST_ENABLED=1
|
|||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
SHOW_NOT_IMPLEMENTED_FEATURES=0
|
|
||||||
ENABLE_ALERT_BANNER=0
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=goerli_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
FLEET=status.staging
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||||
@@ -21,8 +22,8 @@ KEYCARD_TEST_MENU=1
|
|||||||
QR_READ_TEST_MENU=1
|
QR_READ_TEST_MENU=1
|
||||||
ENABLE_ROOT_ALERT=0
|
ENABLE_ROOT_ALERT=0
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||||
VERIFY_ENS_CHAIN_ID=11155111
|
VERIFY_ENS_CHAIN_ID=5
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
@@ -32,13 +33,3 @@ TWO_MINUTES_SYNCING=1
|
|||||||
STICKERS_TEST_ENABLED=1
|
STICKERS_TEST_ENABLED=1
|
||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
SHOW_NOT_IMPLEMENTED_FEATURES=1
|
|
||||||
DELETE_MESSAGE_FOR_ME_UNDO_TIME_LIMIT=10000
|
|
||||||
DELETE_MESSAGE_UNDO_TIME_LIMIT=10000
|
|
||||||
ENABLE_ALERT_BANNER=0
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
MOBILE_DATA_SYNCING_TOGGLE_ENABLE=0
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=goerli_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
@@ -20,8 +22,8 @@ KEYCARD_TEST_MENU=0
|
|||||||
ENABLE_ROOT_ALERT=1
|
ENABLE_ROOT_ALERT=1
|
||||||
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||||
VERIFY_ENS_CHAIN_ID=11155111
|
VERIFY_ENS_CHAIN_ID=5
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
BLANK_PREVIEW=0
|
BLANK_PREVIEW=0
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
@@ -33,9 +35,3 @@ ENABLE_QUO_PREVIEW=1
|
|||||||
STICKERS_TEST_ENABLED=1
|
STICKERS_TEST_ENABLED=1
|
||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
ENABLE_ALERT_BANNER=1
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=info
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
PFS_ENCRYPTION_ENABLED=1
|
PFS_ENCRYPTION_ENABLED=1
|
||||||
@@ -20,9 +22,3 @@ COMMUNITIES_ENABLED=1
|
|||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||||
TEST_NETWORKS_ENABLED=0
|
|
||||||
ENABLE_ALERT_BANNER=1
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=1
|
|
||||||
SENTRY_ENVIRONMENT=ci-nightly
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
DEBUG_WEBVIEW=0
|
DEBUG_WEBVIEW=0
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=0
|
ETHEREUM_DEV_CLUSTER=0
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=error
|
LOG_LEVEL=
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
PFS_ENCRYPTION_ENABLED=1
|
PFS_ENCRYPTION_ENABLED=1
|
||||||
@@ -16,10 +18,5 @@ PARTITIONED_TOPIC=0
|
|||||||
ENABLE_ROOT_ALERT=1
|
ENABLE_ROOT_ALERT=1
|
||||||
MAX_IMAGES_BATCH=1
|
MAX_IMAGES_BATCH=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
|
COLLECTIBLES_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||||
TEST_NETWORKS_ENABLED=0
|
|
||||||
STATUS_PROXY_STAGE_NAME=prod
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=0
|
|
||||||
SENTRY_ENABLED=1
|
|
||||||
SENTRY_ENVIRONMENT=production
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: Bug Report
|
name: MVPBug Report
|
||||||
about: Bug Report
|
about: MVPBug Report
|
||||||
title: ''
|
title: ''
|
||||||
type: 'Bug'
|
labels: 'E:Mobile Bug MVP'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,26 +1,39 @@
|
|||||||
|
[comment]: # (Please replace ... with your information. Remove < and >)
|
||||||
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
||||||
|
|
||||||
|
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
|
||||||
|
|
||||||
|
*otherwise*
|
||||||
|
|
||||||
fixes #...
|
fixes #...
|
||||||
|
|
||||||
## Summary
|
### Summary
|
||||||
|
|
||||||
[comment]: # (Summarise the problem and how the pull request solves it)
|
[comment]: # (Summarise the problem and how the pull request solves it)
|
||||||
...
|
...
|
||||||
|
|
||||||
## Review notes
|
<!-- (Optional, remove if no changes to documentation) -->
|
||||||
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
|
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
|
||||||
|
|
||||||
## Testing notes
|
### Review notes
|
||||||
[comment]: # (Optional)
|
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
|
||||||
|
|
||||||
### Platforms
|
### Testing notes
|
||||||
[comment]: # (Optional. Specify which platforms should be tested)
|
<!-- (Optional) -->
|
||||||
|
|
||||||
|
#### Platforms
|
||||||
|
<!-- (Optional. Specify which platforms should be tested) -->
|
||||||
|
|
||||||
- Android
|
- Android
|
||||||
- iOS
|
- iOS
|
||||||
|
- macOS
|
||||||
|
- Linux
|
||||||
|
- Windows
|
||||||
|
|
||||||
### Areas that may be impacted
|
#### Areas that maybe impacted
|
||||||
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
|
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
|
||||||
|
|
||||||
#### Functional
|
##### Functional
|
||||||
|
|
||||||
- 1-1 chats
|
- 1-1 chats
|
||||||
- public chats
|
- public chats
|
||||||
@@ -35,36 +48,25 @@ fixes #...
|
|||||||
- fleet
|
- fleet
|
||||||
- bootnodes
|
- bootnodes
|
||||||
|
|
||||||
#### Non-functional
|
##### Non-functional
|
||||||
|
|
||||||
- battery performance
|
- battery performance
|
||||||
- CPU performance / speed of the app
|
- CPU performance / speed of the app
|
||||||
- network consumption
|
- network consumption
|
||||||
|
|
||||||
## Steps to test
|
### Steps to test
|
||||||
[comment]: # (Specify exact steps to test if there are such)
|
<!-- (Specify exact steps to test if there are such) -->
|
||||||
|
|
||||||
- Open Status
|
- Open Status
|
||||||
- ...
|
- ...
|
||||||
- Step 3, etc.
|
- Step 3, etc.
|
||||||
|
|
||||||
|
<!-- (PRs will only be accepted if squashed into single commit.) -->
|
||||||
|
|
||||||
[comment]: # (Can be ready or wip)
|
### Before and after screenshots comparison
|
||||||
status: ready
|
|
||||||
|
|
||||||
|
| Figma (if available) | iOS (if available) | Android (if available)
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
|
||||||
|
|
||||||
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
|
status: ready <!-- Can be ready or wip -->
|
||||||
|
|
||||||
- Specify potentially impacted user flows in _Areas that may be impacted*.
|
|
||||||
- Ensure that _Steps to test_ is filled in.
|
|
||||||
|
|
||||||
### Risk
|
|
||||||
|
|
||||||
Described potential risks and worst case scenarios.
|
|
||||||
|
|
||||||
Tick **one**:
|
|
||||||
- [ ] Low risk: 2 devs MUST perform testing as specified above and attach their results as comments to this PR **before** merging.
|
|
||||||
- [ ] High risk: QA team MUST perform additional testing in the specified affected areas **before** merging.
|
|
||||||
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|||||||
@@ -83,9 +83,6 @@ shim.js
|
|||||||
figwheel_server.log
|
figwheel_server.log
|
||||||
.nrepl-port
|
.nrepl-port
|
||||||
|
|
||||||
# FlowStorm (Clojure debugger)
|
|
||||||
repl-client-debug
|
|
||||||
|
|
||||||
# Lein
|
# Lein
|
||||||
#
|
#
|
||||||
.lein-failures
|
.lein-failures
|
||||||
@@ -130,8 +127,6 @@ fastlane/README.md
|
|||||||
# Clj
|
# Clj
|
||||||
|
|
||||||
.cpcache/
|
.cpcache/
|
||||||
src/user.cljs
|
|
||||||
src/dev/user.cljs
|
|
||||||
|
|
||||||
# emacs
|
# emacs
|
||||||
.dir-locals.el
|
.dir-locals.el
|
||||||
@@ -200,5 +195,7 @@ test/appium/tests/users.py
|
|||||||
## git hooks
|
## git hooks
|
||||||
lefthook.yml
|
lefthook.yml
|
||||||
|
|
||||||
## build time logs
|
## clj-kondo
|
||||||
/logs/*.log
|
/.clj-kondo/taoensso/*
|
||||||
|
/.clj-kondo/babashka/*
|
||||||
|
/.clj-kondo/rewrite-clj/rewrite-clj/config.edn
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
[submodule "legal-docs"]
|
|
||||||
path = legal-docs
|
|
||||||
url = https://github.com/status-im/status-software-legal-documents.git
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"include": [
|
"include": [
|
||||||
"target/test/legacy/status_im/**"
|
"target/test/status_im/**"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"target/test/legacy/status_im/test/**",
|
"target/test/status_im/test/**",
|
||||||
"target/test/legacy/status_im/ui/**"
|
"target/test/status_im/ui/**"
|
||||||
],
|
],
|
||||||
"report-dir": "./coverage-report",
|
"report-dir": "./coverage-report",
|
||||||
"all": true,
|
"all": true,
|
||||||
@@ -14,4 +14,4 @@
|
|||||||
"exclude-after-remap": false,
|
"exclude-after-remap": false,
|
||||||
"extension": [".js"],
|
"extension": [".js"],
|
||||||
"reporter": ["lcovonly"]
|
"reporter": ["lcovonly"]
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
/*
|
*
|
||||||
|
|
||||||
# Format top-level js files.
|
|
||||||
!*.js
|
!*.js
|
||||||
|
!*/
|
||||||
# Ignore all except src/js/**/*.js
|
*.clj-kondo
|
||||||
!/src/
|
*.shadow-cljs
|
||||||
/src/*
|
modules
|
||||||
!/src/js
|
result
|
||||||
!/src/js/**/*.js
|
target
|
||||||
|
component-spec
|
||||||
# Ignore all except translations/en.json
|
/app
|
||||||
!/translations/
|
|
||||||
/translations/*
|
|
||||||
!/translations/en.json
|
|
||||||
|
|||||||
@@ -6,8 +6,4 @@ module.exports = {
|
|||||||
tabWidth: 2,
|
tabWidth: 2,
|
||||||
trailingComma: 'all',
|
trailingComma: 'all',
|
||||||
useTabs: false,
|
useTabs: false,
|
||||||
|
|
||||||
// JSON sorting
|
|
||||||
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
|
|
||||||
plugins: ['prettier-plugin-sort-json'],
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ignore_dirs": [
|
"ignore_dirs": [
|
||||||
"android/build",
|
"android/build",
|
||||||
"target",
|
"target"
|
||||||
".clj-kondo",
|
|
||||||
".shadow-cljs"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,54 @@
|
|||||||
;; -*- mode: clojure -*-
|
;; -*- mode: clojure -*-
|
||||||
;; vi: ft=clojure
|
;; vi: ft=clojure
|
||||||
{:width 105
|
{:width 105
|
||||||
:remove {:fn-force-nl #{:noarg1-body}}
|
:style [;; community style
|
||||||
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
||||||
|
:community
|
||||||
|
|
||||||
:style
|
;; no comma in map
|
||||||
[;; community style https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
:no-comma
|
||||||
:community
|
|
||||||
|
|
||||||
;; no comma in map
|
:custom-justify
|
||||||
:no-comma
|
|
||||||
|
|
||||||
:custom-justify
|
;; respect all newlines
|
||||||
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
|
||||||
|
:respect-nl
|
||||||
|
|
||||||
;; respect all newlines https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
|
;; respect blank line
|
||||||
:respect-nl
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
|
||||||
|
:respect-bl
|
||||||
;; respect blank line https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
|
|
||||||
:respect-bl
|
|
||||||
|
|
||||||
;; hang multiline left-hand-thing https://github.com/kkinnear/zprint/issues/273
|
|
||||||
:multi-lhs-hang]
|
|
||||||
|
|
||||||
|
;; hang multiline left-hand-thing
|
||||||
|
;; https://github.com/kkinnear/zprint/issues/273
|
||||||
|
:multi-lhs-hang]
|
||||||
:fn-map
|
:fn-map
|
||||||
{"reg-sub" :arg1-pair
|
{"reg-sub" :arg1-pair
|
||||||
"h/describe" :arg1-body
|
"h/describe" :arg1-body
|
||||||
"h/describe-skip" :arg1-body
|
"h/test" :arg1-body
|
||||||
"h/describe-only" :arg1-body
|
"global.describe" :arg1-body
|
||||||
"h/test" :arg1-body
|
"global.test" :arg1-body
|
||||||
"h/test-skip" :arg1-body
|
"list-comp" :binding
|
||||||
"h/test-only" :arg1-body
|
"defview" :arg1-body
|
||||||
"test/async" :arg1-body
|
"letsubs" :binding
|
||||||
"test/use-fixtures" :arg1-body
|
"with-let" "let"
|
||||||
"global.describe" :arg1-body
|
"reg-event-fx" :arg1-pair
|
||||||
"global.test" :arg1-body
|
"reg-fx" :arg1-pair
|
||||||
"list-comp" :binding
|
"testing" :arg1-body
|
||||||
"defview" :arg1-body
|
"deftest-sub" :arg1-body
|
||||||
"letsubs" :binding
|
"wait-for" :arg1-body
|
||||||
"with-let" "let"
|
"with-deps-check" :arg1-body
|
||||||
"reg-event-fx" :arg1-pair
|
"schema/=>" :arg1-body
|
||||||
"reg-fx" :arg1-pair
|
"->" [:noarg1-body
|
||||||
"testing" :arg1-body
|
{:list {:constant-pair? false :force-nl? false}
|
||||||
"deftest-sub" :arg1-body
|
:next-inner-restore [[:list :constant-pair?]]}]
|
||||||
"deftest-event" :arg1-body
|
"set!" "reset!"
|
||||||
"test-async" :arg1-body
|
"assoc-when" "assoc"
|
||||||
"wait-for" :arg1-body
|
"assoc-some" "assoc"
|
||||||
"with-deps-check" :arg1-body
|
"conj-when" "conj"
|
||||||
"schema/=>" :arg1-body
|
"conj-some" "conj"}
|
||||||
"->" [:noarg1-body
|
:remove {:fn-force-nl #{:noarg1-body}}
|
||||||
{:list {:constant-pair? false :force-nl? false}
|
|
||||||
:next-inner-restore [[:list :constant-pair?]]}]
|
|
||||||
"set!" "reset!"
|
|
||||||
"assoc-when" "assoc"
|
|
||||||
"assoc-some" "assoc"
|
|
||||||
"conj-when" "conj"
|
|
||||||
"conj-some" "conj"}
|
|
||||||
|
|
||||||
:style-map
|
:style-map
|
||||||
{:no-comma {:map {:comma? false}}
|
{:no-comma {:map {:comma? false}}
|
||||||
:custom-justify
|
:custom-justify
|
||||||
{:doc "Justify everything using pre-1.1.2 approach"
|
{:doc "Justify everything using pre-1.1.2 approach"
|
||||||
:binding {:justify? true :justify {:max-variance 1000}}
|
:binding {:justify? true :justify {:max-variance 1000}}
|
||||||
|
|||||||
@@ -32,19 +32,19 @@ ifndef BUILD_TAG
|
|||||||
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# We don't want to use /run/user/$UID because it runs out of space too easily.
|
# We don't want to use /run/user/$UID because it runs out of space too easilly.
|
||||||
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
|
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
|
||||||
# This has to be specified for both the Node.JS server process and the Qt process.
|
# This has to be specified for both the Node.JS server process and the Qt process.
|
||||||
export REACT_SERVER_PORT ?= 5001
|
export REACT_SERVER_PORT ?= 5001
|
||||||
# Default metro port used by scripts/run-android.sh.
|
|
||||||
export RCT_METRO_PORT ?= 8081
|
|
||||||
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
|
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
|
||||||
export NODE_OPTIONS += --openssl-legacy-provider
|
export NODE_OPTIONS += --openssl-legacy-provider
|
||||||
# The path can be anything, but home is usually safest.
|
# The path can be anything, but home is usually safest.
|
||||||
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||||
|
|
||||||
|
# Our custom config is located in nix/nix.conf
|
||||||
|
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
|
||||||
# Location of symlinks to derivations that should not be garbage collected
|
# Location of symlinks to derivations that should not be garbage collected
|
||||||
export _NIX_GCROOTS = ./.nix-gcroots
|
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
|
||||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
||||||
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
||||||
@@ -54,6 +54,12 @@ export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
|||||||
# Useful for Android release builds
|
# Useful for Android release builds
|
||||||
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
||||||
|
|
||||||
|
# MacOS root is read-only, read nix/README.md for details
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
export NIX_IGNORE_SYMLINK_STORE=1
|
||||||
|
endif
|
||||||
|
|
||||||
#----------------
|
#----------------
|
||||||
# Nix targets
|
# Nix targets
|
||||||
#----------------
|
#----------------
|
||||||
@@ -95,8 +101,6 @@ nix-purge: ##@nix Completely remove Nix setup, including /nix directory
|
|||||||
nix/scripts/purge.sh
|
nix/scripts/purge.sh
|
||||||
|
|
||||||
nix-update-gradle: export TARGET := gradle
|
nix-update-gradle: export TARGET := gradle
|
||||||
nix-update-gradle: export ORG_GRADLE_PROJECT_hermesEnabled := false
|
|
||||||
nix-update-gradle: export ORG_GRADLE_PROJECT_universalApk := false
|
|
||||||
nix-update-gradle: ##@nix Update maven nix expressions based on current gradle setup
|
nix-update-gradle: ##@nix Update maven nix expressions based on current gradle setup
|
||||||
nix/deps/gradle/generate.sh
|
nix/deps/gradle/generate.sh
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ _install-hooks: ##@prepare Create prepare-commit-msg git hook symlink
|
|||||||
|
|
||||||
# Remove directories and ignored files
|
# Remove directories and ignored files
|
||||||
clean: SHELL := /bin/sh
|
clean: SHELL := /bin/sh
|
||||||
clean: _fix-node-perms _tmpdir-rm ios-clean android-clean ##@prepare Remove all output folders
|
clean: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
|
||||||
git clean -dXf
|
git clean -dXf
|
||||||
|
|
||||||
# Remove directories, ignored and non-ignored files
|
# Remove directories, ignored and non-ignored files
|
||||||
@@ -156,12 +160,10 @@ pod-install: export TARGET := ios
|
|||||||
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
|
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
|
||||||
cd ios && pod install; cd --
|
cd ios && pod install; cd --
|
||||||
|
|
||||||
FLEETS_FILE := ./resources/config/fleets.json
|
|
||||||
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
||||||
curl -s https://fleets.status.im/ \
|
curl -s https://fleets.status.im/ \
|
||||||
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
||||||
> $(FLEETS_FILE)
|
> resources/config/fleets.json
|
||||||
echo >> $(FLEETS_FILE)
|
|
||||||
|
|
||||||
$(KEYSTORE_PATH): export TARGET := keytool
|
$(KEYSTORE_PATH): export TARGET := keytool
|
||||||
$(KEYSTORE_PATH):
|
$(KEYSTORE_PATH):
|
||||||
@@ -196,10 +198,6 @@ xcode-clean: XCODE_HOME := $(HOME)/Library/Developer/Xcode
|
|||||||
xcode-clean: ##@prepare Clean XCode derived data and archives
|
xcode-clean: ##@prepare Clean XCode derived data and archives
|
||||||
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
|
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
|
||||||
|
|
||||||
ios-simulator-cache-clean: SHELL := /bin/sh
|
|
||||||
ios-simulator-cache-clean: ##@prepare Clean iOS Simulator Caches
|
|
||||||
rm -rf ~/Library/Developer/CoreSimulator/Cache
|
|
||||||
|
|
||||||
#----------------
|
#----------------
|
||||||
# Release builds
|
# Release builds
|
||||||
#----------------
|
#----------------
|
||||||
@@ -214,14 +212,16 @@ build-fdroid: ##@build Build release for F-Droid
|
|||||||
|
|
||||||
build-android: export BUILD_ENV ?= prod
|
build-android: export BUILD_ENV ?= prod
|
||||||
build-android: export BUILD_TYPE ?= nightly
|
build-android: export BUILD_TYPE ?= nightly
|
||||||
build-android: export ORG_GRADLE_PROJECT_versionCode ?= $(TMP_BUILD_NUMBER)
|
build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
|
||||||
|
build-android: export ANDROID_ABI_SPLIT ?= false
|
||||||
|
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||||
build-android: ##@build Build unsigned Android APK
|
build-android: ##@build Build unsigned Android APK
|
||||||
@scripts/build-android.sh
|
@scripts/build-android.sh
|
||||||
|
|
||||||
release-android: export TARGET := keytool
|
release-android: export TARGET := keytool
|
||||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||||
release-android: keystore build-android ##@build Build signed Android APK
|
release-android: keystore build-android ##@build Build signed Android APK
|
||||||
@scripts/sign-android.sh result/app-arm64-v8a-release-unsigned.apk
|
@scripts/sign-android.sh result/app-release-unsigned.apk
|
||||||
|
|
||||||
release-ios: export TARGET := ios
|
release-ios: export TARGET := ios
|
||||||
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||||
@@ -265,38 +265,39 @@ run-clojure: ##@run Watch for and build Clojure changes for mobile
|
|||||||
|
|
||||||
run-metro: export TARGET := clojure
|
run-metro: export TARGET := clojure
|
||||||
run-metro: ##@run Start Metro to build React Native changes
|
run-metro: ##@run Start Metro to build React Native changes
|
||||||
@scripts/run-metro.sh
|
@scripts/start-react-native.sh
|
||||||
|
|
||||||
export RE_FRISK_PORT ?= 4567
|
|
||||||
|
|
||||||
run-re-frisk: export TARGET := clojure
|
run-re-frisk: export TARGET := clojure
|
||||||
run-re-frisk: ##@run Start re-frisk server
|
run-re-frisk: ##@run Start re-frisk server
|
||||||
yarn shadow-cljs run re-frisk-remote.core/start ${RE_FRISK_PORT}
|
yarn shadow-cljs run re-frisk-remote.core/start
|
||||||
|
|
||||||
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
||||||
run-android: export TARGET := android
|
run-android: export TARGET := android
|
||||||
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
|
# INFO: If it's empty (no devices attached, parsing issues, script error) - for Nix it's the same as not set.
|
||||||
# https://github.com/status-im/status-mobile/issues/18493
|
run-android: export ANDROID_ABI_INCLUDE ?= $(shell ./scripts/adb_devices_abis.sh)
|
||||||
run-android: export ORG_GRADLE_PROJECT_hermesEnabled := false
|
|
||||||
run-android: export ORG_GRADLE_PROJECT_universalApk := false
|
|
||||||
run-android: ##@run Build Android APK and start it on the device
|
run-android: ##@run Build Android APK and start it on the device
|
||||||
@scripts/run-android.sh
|
npx react-native run-android --appIdSuffix debug
|
||||||
|
|
||||||
SIMULATOR=iPhone 13
|
SIMULATOR=iPhone 13
|
||||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
|
||||||
run-ios: export TARGET := ios
|
run-ios: export TARGET := ios
|
||||||
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
|
||||||
run-ios: ##@run Build iOS app and start it in on the simulator
|
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||||
@scripts/run-ios.sh "${SIMULATOR}"
|
ifneq ("$(SIMULATOR)", "")
|
||||||
|
npx react-native run-ios --simulator="$(SIMULATOR)"
|
||||||
|
else
|
||||||
|
npx react-native run-ios
|
||||||
|
endif
|
||||||
|
|
||||||
show-ios-devices: ##@other shows connected ios device and its name
|
show-ios-devices: ##@other shows connected ios device and its name
|
||||||
xcrun xctrace list devices
|
xcrun xctrace list devices
|
||||||
|
|
||||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
|
||||||
run-ios-device: export TARGET := ios
|
run-ios-device: export TARGET := ios
|
||||||
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||||
run-ios-device: ##@run iOS app and start it on the first connected iPhone
|
run-ios-device: ##@run iOS app and start it on a connected device by its name
|
||||||
@scripts/run-ios-device.sh
|
ifndef DEVICE_NAME
|
||||||
|
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
|
||||||
|
endif
|
||||||
|
react-native run-ios --device "$(DEVICE_NAME)"
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# Tests
|
# Tests
|
||||||
@@ -304,7 +305,7 @@ run-ios-device: ##@run iOS app and start it on the first connected iPhone
|
|||||||
|
|
||||||
# Get all clojure files, including untracked, excluding removed
|
# Get all clojure files, including untracked, excluding removed
|
||||||
define find_all_clojure_files
|
define find_all_clojure_files
|
||||||
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -E '((\.clj-kondo\/status-im)|(src).*\.clj[sc]?$$)|((\.clj-kondo\/(status-im|config))|(src).*\.edn$$)|shadow-cljs\.edn')
|
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
lint: export TARGET := clojure
|
lint: export TARGET := clojure
|
||||||
@@ -318,7 +319,7 @@ lint: ##@test Run code style checks
|
|||||||
scripts/lint/translations.clj && \
|
scripts/lint/translations.clj && \
|
||||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||||
sh scripts/lint/trailing-newline.sh && \
|
sh scripts/lint/trailing-newline.sh && \
|
||||||
node_modules/.bin/prettier --check .
|
node_modules/.bin/prettier --write .
|
||||||
|
|
||||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||||
lint-fix: export TARGET := clojure
|
lint-fix: export TARGET := clojure
|
||||||
@@ -326,7 +327,7 @@ lint-fix: ##@test Run code style checks and fix issues
|
|||||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||||
clojure-lsp --ns-exclude-regex ".*/\.clj-kondo/.*|.*/src/status_im/core\.cljs|.*/src/test_helpers/component_tests_preload\.cljs$$" clean-ns && \
|
clojure-lsp --ns-exclude-regex ".*/src/status_im2/core\.cljs$$" clean-ns && \
|
||||||
sh scripts/lint/trailing-newline.sh --fix && \
|
sh scripts/lint/trailing-newline.sh --fix && \
|
||||||
node_modules/.bin/prettier --write .
|
node_modules/.bin/prettier --write .
|
||||||
|
|
||||||
@@ -334,89 +335,51 @@ shadow-server: export TARGET := clojure
|
|||||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||||
yarn shadow-cljs server
|
yarn shadow-cljs server
|
||||||
|
|
||||||
_test-clojure: export TARGET := clojure
|
test-watch: export TARGET := clojure
|
||||||
_test-clojure: export WATCH ?= false
|
test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||||
_test-clojure: status-go-library
|
yarn install
|
||||||
_test-clojure:
|
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
|
||||||
ifeq ($(WATCH), true)
|
|
||||||
yarn node-pre-gyp rebuild && \
|
test-watch-for-repl: export TARGET := clojure
|
||||||
yarn shadow-cljs compile mocks && \
|
test-watch-for-repl: ##@ Watch tests and support REPL connections
|
||||||
nodemon --exec "yarn shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
|
yarn install
|
||||||
else
|
rm -f target/test/test.js
|
||||||
yarn node-pre-gyp rebuild && \
|
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
||||||
|
'yarn shadow-cljs compile mocks && yarn shadow-cljs watch test --verbose' \
|
||||||
|
'until [ -f ./target/test/test.js ] ; do sleep 1 ; done ; node --require ./test-resources/override.js ./target/test/test.js --repl'
|
||||||
|
|
||||||
|
test: export TARGET := clojure
|
||||||
|
test: ##@test Run tests once in NodeJS
|
||||||
|
# Here we create the gyp bindings for nodejs
|
||||||
|
yarn install
|
||||||
yarn shadow-cljs compile mocks && \
|
yarn shadow-cljs compile mocks && \
|
||||||
yarn shadow-cljs compile test && \
|
yarn shadow-cljs compile test && \
|
||||||
node --require ./test-resources/override.js "$$SHADOW_OUTPUT_TO"
|
node --require ./test-resources/override.js target/test/test.js
|
||||||
endif
|
|
||||||
|
|
||||||
test: export SHADOW_OUTPUT_TO := target/test/test.js
|
android-test: jsbundle
|
||||||
test: export SHADOW_NS_REGEXP := .*-test$$
|
android-test: export TARGET := android
|
||||||
test: ##@test Run all Clojure tests
|
android-test:
|
||||||
test: _test-clojure
|
|
||||||
|
|
||||||
# Note: we need to override the :output-to and :ns-regexp options because
|
|
||||||
# shadow-cljs has a bug where it will not read from the env vars to expand the
|
|
||||||
# configuration when the shadow-cljs mobile target is already running.
|
|
||||||
test-watch-for-repl: export TARGET := default
|
|
||||||
test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js
|
|
||||||
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$
|
|
||||||
test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connections
|
|
||||||
rm -f "$$SHADOW_OUTPUT_TO" && \
|
|
||||||
yarn install && shadow-cljs compile mocks && \
|
|
||||||
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
|
||||||
"yarn shadow-cljs watch test --verbose --config-merge '{:output-to \"$(SHADOW_OUTPUT_TO)\" :ns-regexp \"$(SHADOW_NS_REGEXP)\"}'" \
|
|
||||||
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
|
|
||||||
|
|
||||||
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
|
|
||||||
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests\.contract-test).*-test$$
|
|
||||||
test-unit: ##@test Run unit tests
|
|
||||||
test-unit: _test-clojure
|
|
||||||
|
|
||||||
test-integration: export SHADOW_OUTPUT_TO := target/integration_test/test.js
|
|
||||||
test-integration: export SHADOW_NS_REGEXP := ^tests\.integration-test.*$$
|
|
||||||
test-integration: ##@test Run integration tests
|
|
||||||
test-integration: _test-clojure
|
|
||||||
|
|
||||||
test-contract: export SHADOW_OUTPUT_TO := target/contract_test/test.js
|
|
||||||
test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
|
|
||||||
test-contract: ##@test Run contract tests
|
|
||||||
test-contract: _test-clojure
|
|
||||||
|
|
||||||
test-android: jsbundle
|
|
||||||
test-android: export TARGET := android
|
|
||||||
test-android: ##@test Android Gradle test
|
|
||||||
cd android && ./gradlew test
|
cd android && ./gradlew test
|
||||||
|
|
||||||
test-component-watch: export TARGET := clojure
|
component-test-watch: export TARGET := clojure
|
||||||
test-component-watch: export COMPONENT_TEST := true
|
component-test-watch: export COMPONENT_TEST := true
|
||||||
test-component-watch: export BABEL_ENV := test
|
component-test-watch: export BABEL_ENV := test
|
||||||
test-component-watch: export JEST_USE_SILENT_REPORTER := false
|
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||||
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
|
@@scripts/check-metro-shadow-process.sh
|
||||||
@scripts/check-metro-shadow-process.sh
|
|
||||||
rm -rf ./component-spec
|
rm -rf ./component-spec
|
||||||
|
yarn install
|
||||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
|
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
|
||||||
|
|
||||||
test-component: export TARGET := clojure
|
component-test: export TARGET := clojure
|
||||||
test-component: export COMPONENT_TEST := true
|
component-test: export COMPONENT_TEST := true
|
||||||
test-component: export BABEL_ENV := test
|
component-test: export BABEL_ENV := test
|
||||||
test-component: export JEST_USE_SILENT_REPORTER := false
|
component-test: ##@test Run component tests once in NodeJS
|
||||||
test-component: ##@test Run component tests once in NodeJS
|
|
||||||
@scripts/check-metro-shadow-process.sh
|
@scripts/check-metro-shadow-process.sh
|
||||||
rm -rf ./component-spec
|
rm -rf ./component-spec
|
||||||
|
yarn install
|
||||||
yarn shadow-cljs compile component-test && \
|
yarn shadow-cljs compile component-test && \
|
||||||
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
|
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
|
||||||
|
|
||||||
# Reference: https://flow-storm.github.io/flow-storm-debugger/user_guide.html#_debugging_react_native_applications
|
|
||||||
run-flow-storm: export SHADOW_CLJS_BUILD_ID := :mobile
|
|
||||||
run-flow-storm: export TARGET := clojure
|
|
||||||
run-flow-storm: export GDK_DPI_SCALE := 1.0
|
|
||||||
run-flow-storm: ##@run Start FlowStorm debugger
|
|
||||||
clj -Sforce -Sdeps '{:deps {com.github.jpmonettas/flow-storm-dbg {:mvn/version "3.7.5"}}}' \
|
|
||||||
-X flow-storm.debugger.main/start-debugger \
|
|
||||||
:port 7888 \
|
|
||||||
:repl-type :shadow \
|
|
||||||
:build-id $(SHADOW_CLJS_BUILD_ID)
|
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# Other
|
# Other
|
||||||
#--------------
|
#--------------
|
||||||
@@ -427,48 +390,25 @@ geth-connect: ##@other Connect to Geth on the device
|
|||||||
build/bin/geth attach http://localhost:8545
|
build/bin/geth attach http://localhost:8545
|
||||||
|
|
||||||
ios-clean: SHELL := /bin/sh
|
ios-clean: SHELL := /bin/sh
|
||||||
ios-clean: ios-simulator-cache-clean
|
|
||||||
ios-clean: ##@prepare Clean iOS build artifacts
|
ios-clean: ##@prepare Clean iOS build artifacts
|
||||||
git clean -dxf -f target/ios
|
git clean -dxf -f target/ios
|
||||||
|
|
||||||
android-clean: SHELL := /bin/sh
|
android-clean: export TARGET := gradle
|
||||||
android-clean: ##@prepare Clean Gradle state
|
android-clean: ##@prepare Clean Gradle state
|
||||||
git clean -dxf -f ./android/app/build; \
|
git clean -dxf -f ./android/app/build; \
|
||||||
rm -rf android/.gradle \
|
[[ -d android/.gradle ]] && cd android && ./gradlew clean
|
||||||
rm -rf android/build \
|
|
||||||
rm -rf ~/.gradle
|
|
||||||
|
|
||||||
|
|
||||||
android-ports: export FLOWSTORM_PORT ?= 7722
|
|
||||||
android-ports: export TARGET := android-sdk
|
android-ports: export TARGET := android-sdk
|
||||||
android-ports: export RCT_METRO_PORT ?= 8081
|
|
||||||
android-ports: ##@other Add proxies to Android Device/Simulator
|
android-ports: ##@other Add proxies to Android Device/Simulator
|
||||||
adb reverse tcp:$(RCT_METRO_PORT) tcp:$(RCT_METRO_PORT) && \
|
adb reverse tcp:8081 tcp:8081 && \
|
||||||
adb reverse tcp:3449 tcp:3449 && \
|
adb reverse tcp:3449 tcp:3449 && \
|
||||||
adb reverse tcp:$(RE_FRISK_PORT) tcp:$(RE_FRISK_PORT) && \
|
adb reverse tcp:4567 tcp:4567 && \
|
||||||
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
|
|
||||||
adb forward tcp:5561 tcp:5561
|
adb forward tcp:5561 tcp:5561
|
||||||
|
|
||||||
android-devices: export TARGET := android-sdk
|
android-devices: export TARGET := android-sdk
|
||||||
android-devices: ##@other Invoke adb devices
|
android-devices: ##@other Invoke adb devices
|
||||||
adb devices
|
adb devices
|
||||||
|
|
||||||
android-pull-geth: export TARGET := android-sdk
|
|
||||||
android-pull-geth: export VERSION ?= debug
|
|
||||||
android-pull-geth:
|
|
||||||
adb pull "/storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log"
|
|
||||||
|
|
||||||
android-tail-geth: export TARGET := android-sdk
|
|
||||||
android-tail-geth: export VERSION ?= debug
|
|
||||||
android-tail-geth:
|
|
||||||
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
|
||||||
|
|
||||||
android-clean-geth: export TARGET := android-sdk
|
|
||||||
android-clean-geth: export VERSION ?= debug
|
|
||||||
android-clean-geth:
|
|
||||||
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
|
||||||
|
|
||||||
|
|
||||||
android-logcat: export TARGET := android-sdk
|
android-logcat: export TARGET := android-sdk
|
||||||
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
||||||
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
||||||
@@ -482,10 +422,6 @@ _list: SHELL := /bin/sh
|
|||||||
_list:
|
_list:
|
||||||
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
||||||
|
|
||||||
patch-file: export TARGET := default
|
|
||||||
patch-file: ##@other Generates patch file for npm deps
|
|
||||||
@scripts/patch-npm-lib.sh
|
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# REPLs
|
# REPLs
|
||||||
#--------------
|
#--------------
|
||||||
@@ -495,18 +431,3 @@ repl-clojure: ##@repl Start Clojure repl for mobile App
|
|||||||
yarn shadow-cljs cljs-repl mobile
|
yarn shadow-cljs cljs-repl mobile
|
||||||
|
|
||||||
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
|
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
|
||||||
|
|
||||||
#--------------
|
|
||||||
# Dev Automation Flows
|
|
||||||
#--------------
|
|
||||||
|
|
||||||
auto-login: export TARGET := default
|
|
||||||
auto-login: ##@auto runs flow for login or onboarding app on simulator/emulator
|
|
||||||
maestro test "maestro/create-account-or-login.yaml"
|
|
||||||
|
|
||||||
auto-custom: export TARGET := default
|
|
||||||
auto-custom: ##@auto runs any custom maestro automation flow on simulator/emulator
|
|
||||||
ifndef FLOW
|
|
||||||
$(error Usage: make automate FLOW=your-maestro-flow-file.yaml)
|
|
||||||
endif
|
|
||||||
maestro test "$(FLOW)"
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ project dependencies, coding guidelines and testing procedures.
|
|||||||
Check out our [coding guidelines](doc/new-guidelines.md).
|
Check out our [coding guidelines](doc/new-guidelines.md).
|
||||||
|
|
||||||
- **Community Management**
|
- **Community Management**
|
||||||
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.app/manifesto)
|
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about)
|
||||||
|
|
||||||
- **Specification / Documentation**
|
- **Specification / Documentation**
|
||||||
John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
|
John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
|
||||||
@@ -53,10 +53,10 @@ Status is a visual interface to make permanent changes on the Blockchain, it han
|
|||||||
|
|
||||||
- **Evangelism**
|
- **Evangelism**
|
||||||
Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
|
Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
|
||||||
|
|
||||||
## Give me Binaries!
|
## Give me Binaries!
|
||||||
|
|
||||||
You can get our Beta builds for both Android and iOS on our [website](https://status.app), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](doc/starting-guide.md).
|
You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](https://status.im/technical/build_status/).
|
||||||
|
|
||||||
## Core Contributors
|
## Core Contributors
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
apply plugin: "org.jetbrains.kotlin.android"
|
|
||||||
apply plugin: "com.facebook.react"
|
apply plugin: "com.facebook.react"
|
||||||
|
|
||||||
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||||
@@ -59,7 +58,7 @@ react {
|
|||||||
/**
|
/**
|
||||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
||||||
*/
|
*/
|
||||||
def enableProguardInReleaseBuilds = true
|
def enableProguardInReleaseBuilds = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The preferred build flavor of JavaScriptCore (JSC)
|
* The preferred build flavor of JavaScriptCore (JSC)
|
||||||
@@ -83,6 +82,7 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
|||||||
*/
|
*/
|
||||||
def enableHermes = hermesEnabled.toBoolean();
|
def enableHermes = hermesEnabled.toBoolean();
|
||||||
|
|
||||||
|
|
||||||
def getCommitHash = { ->
|
def getCommitHash = { ->
|
||||||
if (project.hasProperty("commitHash")) {
|
if (project.hasProperty("commitHash")) {
|
||||||
return project.commitHash
|
return project.commitHash
|
||||||
@@ -137,28 +137,11 @@ def getEnvOrConfig = { varName ->
|
|||||||
android {
|
android {
|
||||||
ndkVersion rootProject.ext.ndkVersion
|
ndkVersion rootProject.ext.ndkVersion
|
||||||
|
|
||||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
compileSdk rootProject.ext.compileSdkVersion
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
// Disable default lint checks to remove redundant lintVitalReportRelease task
|
|
||||||
lintOptions {
|
|
||||||
checkReleaseBuilds false
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
// This version must match cmakeVersions inside nix/pkgs/android-sdk/compose.nix
|
|
||||||
version "3.22.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_17
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_17
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace "im.status.ethereum"
|
namespace "im.status.ethereum"
|
||||||
@@ -210,12 +193,16 @@ android {
|
|||||||
doNotStrip '*/mips/*.so'
|
doNotStrip '*/mips/*.so'
|
||||||
doNotStrip '*/mips64/*.so'
|
doNotStrip '*/mips64/*.so'
|
||||||
}
|
}
|
||||||
|
dexOptions {
|
||||||
|
jumboMode true
|
||||||
|
javaMaxHeapSize "8g"
|
||||||
|
}
|
||||||
splits {
|
splits {
|
||||||
abi {
|
abi {
|
||||||
reset()
|
reset()
|
||||||
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
||||||
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||||
universalApk getEnvOrConfig('ORG_GRADLE_PROJECT_universalApk').toBoolean()
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
@@ -236,7 +223,6 @@ android {
|
|||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
minifyEnabled enableProguardInReleaseBuilds
|
||||||
shrinkResources enableProguardInReleaseBuilds
|
|
||||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
signingConfig null
|
signingConfig null
|
||||||
}
|
}
|
||||||
@@ -244,10 +230,10 @@ android {
|
|||||||
initWith release
|
initWith release
|
||||||
applicationIdSuffix ".pr"
|
applicationIdSuffix ".pr"
|
||||||
versionNameSuffix ".pr"
|
versionNameSuffix ".pr"
|
||||||
debuggable false
|
debuggable false
|
||||||
matchingFallbacks = ["release"]
|
matchingFallbacks = ["release"]
|
||||||
// necessary to make react-native-config's code generation work
|
// necessary to make react-native-config's code generation work
|
||||||
resValue "string", "build_config_package", "im.status.ethereum"
|
resValue "string", "build_config_package", "im.status.ethereum"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,29 +266,26 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// The version of react-native is set by the React Native Gradle Plugin
|
// The version of react-native is set by the React Native Gradle Plugin
|
||||||
implementation("com.facebook.react:react-android")
|
implementation("com.facebook.react:react-android")
|
||||||
implementation("androidx.core:core-splashscreen:1.0.0")
|
implementation "androidx.core:core-splashscreen:1.0.0"
|
||||||
|
|
||||||
if (enableHermes) {
|
if (hermesEnabled.toBoolean()) {
|
||||||
implementation("com.facebook.react:hermes-android")
|
implementation("com.facebook.react:hermes-android")
|
||||||
} else {
|
} else {
|
||||||
// https://github.com/status-im/status-mobile/issues/18493
|
implementation jscFlavor
|
||||||
// we don't use hermes for debug builds because it crashes too often
|
|
||||||
implementation(jscFlavor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// react-native-screens
|
// react-native-screens
|
||||||
implementation("androidx.appcompat:appcompat:1.1.0-rc01")
|
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02")
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||||
implementation("androidx.multidex:multidex:2.0.1") // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
|
implementation 'androidx.multidex:multidex:2.0.1' // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
|
||||||
implementation project(':react-native-blur')
|
implementation project(':react-native-blur')
|
||||||
implementation project(':react-native-status')
|
implementation project(':react-native-status')
|
||||||
implementation project(':react-native-status-keycard')
|
implementation project(':react-native-status-keycard')
|
||||||
implementation("com.github.status-im:function:0.0.1")
|
implementation 'com.github.status-im:function:0.0.1'
|
||||||
implementation("com.facebook.fresco:fresco:2.5.0")
|
implementation 'com.facebook.fresco:fresco:2.5.0'
|
||||||
implementation("com.facebook.fresco:animated-gif:2.5.0")
|
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||||
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
|
implementation "com.squareup.okhttp3:okhttp-tls:4.9.2"
|
||||||
implementation("com.google.prefab:cli:2.0.0")
|
implementation("com.google.prefab:cli:2.0.0")
|
||||||
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,6 @@
|
|||||||
-keep interface okhttp3.** { *; }
|
-keep interface okhttp3.** { *; }
|
||||||
-dontwarn okhttp3.**
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
# to fix : java.security.KeyStoreException: BKS not found
|
|
||||||
-keep class org.bouncycastle.** { *; }
|
|
||||||
|
|
||||||
# okio
|
# okio
|
||||||
|
|
||||||
-keep class sun.misc.Unsafe { *; }
|
-keep class sun.misc.Unsafe { *; }
|
||||||
@@ -78,13 +75,4 @@
|
|||||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||||
**[] $VALUES;
|
**[] $VALUES;
|
||||||
public *;
|
public *;
|
||||||
}
|
}
|
||||||
|
|
||||||
# react-native-config
|
|
||||||
# https://github.com/lugg/react-native-config?tab=readme-ov-file#problems-with-proguard
|
|
||||||
-keep class im.status.ethereum.BuildConfig {*;}
|
|
||||||
|
|
||||||
# react-native-navigation
|
|
||||||
# to fix : java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
|
|
||||||
# at com.reactnativenavigation.views.element.animators.PropertyAnimatorCreator.getChildClass(Unknown Source:13)
|
|
||||||
-keep class com.reactnativenavigation.** {*;}
|
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
|
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
|
||||||
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
|
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
|
||||||
|
|
||||||
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" />
|
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" >
|
||||||
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -2,16 +2,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
|
||||||
<queries>
|
|
||||||
<intent>
|
|
||||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
|
||||||
<data android:mimeType="*/*" />
|
|
||||||
</intent>
|
|
||||||
</queries>
|
|
||||||
|
|
||||||
<!-- non-dangerous permissions -->
|
<!-- non-dangerous permissions -->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.NFC"/>
|
<uses-permission android:name="android.permission.NFC"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
@@ -36,7 +28,6 @@
|
|||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:theme="@style/Theme.AppSplash"
|
android:theme="@style/Theme.AppSplash"
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
@@ -71,30 +62,8 @@
|
|||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<!-- Handles http and https URLs for status.app -->
|
|
||||||
<data android:scheme="http" android:host="status.app" />
|
<data android:scheme="http" android:host="status.app" />
|
||||||
<data android:scheme="https" android:host="status.app" />
|
<data android:scheme="https" android:host="status.app" />
|
||||||
<!-- Community paths -->
|
|
||||||
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Community channel paths -->
|
|
||||||
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- User paths -->
|
|
||||||
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Private chat paths -->
|
|
||||||
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Community request paths -->
|
|
||||||
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Group chat paths -->
|
|
||||||
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Wallet paths -->
|
|
||||||
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
@@ -105,13 +74,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
||||||
<service
|
<service android:name="im.status.ethereum.pushnotifications.ForegroundService"></service>
|
||||||
android:name="im.status.ethereum.pushnotifications.ForegroundService"
|
|
||||||
android:foregroundServiceType="specialUse">
|
|
||||||
<property
|
|
||||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
|
||||||
android:value="local notifications"/>
|
|
||||||
</service>
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.provider"
|
android:authorities="${applicationId}.provider"
|
||||||
|
|||||||
@@ -0,0 +1,268 @@
|
|||||||
|
package im.status.ethereum;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnCancelListener;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import com.facebook.react.ReactActivityDelegate;
|
||||||
|
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||||
|
import com.facebook.react.defaults.DefaultReactActivityDelegate;
|
||||||
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||||
|
|
||||||
|
import com.reactnativenavigation.NavigationActivity;
|
||||||
|
import com.facebook.react.modules.core.PermissionListener;
|
||||||
|
import androidx.core.splashscreen.SplashScreen;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
import im.status.ethereum.module.StatusThreadPoolExecutor;
|
||||||
|
import im.status.ethereum.MainApplication;
|
||||||
|
|
||||||
|
public class MainActivity extends NavigationActivity
|
||||||
|
implements ActivityCompat.OnRequestPermissionsResultCallback{
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable private PermissionListener mPermissionListener;
|
||||||
|
private boolean keepSplash = true;
|
||||||
|
private final int SPLASH_DELAY = 3200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
||||||
|
* rendering of the component.
|
||||||
|
*/
|
||||||
|
protected String getMainComponentName() {
|
||||||
|
return "StatusIm";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerUncaughtExceptionHandler(final Context context) {
|
||||||
|
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
|
@Override
|
||||||
|
public void uncaughtException(final Thread thread, final Throwable t) {
|
||||||
|
// High priority, so don't use StatusThreadPoolExecutor
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Looper.prepare();
|
||||||
|
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setTitle("Error")
|
||||||
|
.setMessage(t.toString())
|
||||||
|
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(final DialogInterface dialog, final int id) {
|
||||||
|
dialog.dismiss();
|
||||||
|
defaultUncaughtExceptionHandler.uncaughtException(thread, t);
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
|
||||||
|
Looper.loop();
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActivityManager getActivityManager() {
|
||||||
|
return (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActivityManager.MemoryInfo getAvailableMemory(final ActivityManager activityManager) {
|
||||||
|
final ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||||
|
activityManager.getMemoryInfo(memoryInfo);
|
||||||
|
return memoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void configureStatus() {
|
||||||
|
// Required because of crazy APN settings redirecting localhost (found in GB)
|
||||||
|
Properties properties = System.getProperties();
|
||||||
|
properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
|
||||||
|
properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Intent createNotificationSettingsIntent() {
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
|
||||||
|
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
|
||||||
|
} else {
|
||||||
|
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||||
|
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||||
|
intent.setData(Uri.parse("package:" + getPackageName()));
|
||||||
|
}
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryToEmit(String eventName, WritableMap event) {
|
||||||
|
try {
|
||||||
|
((MainApplication) getApplication()).getReactNativeHost()
|
||||||
|
.getReactInstanceManager()
|
||||||
|
.getCurrentReactContext()
|
||||||
|
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||||
|
.emit("url", event);
|
||||||
|
} catch(Exception e) {/* we expect NPE on first start, which is OK because we have a fallback */}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewIntent(final Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
if (intent.getDataString() != null && intent.getData().getScheme().startsWith("app-settings")) {
|
||||||
|
startActivity(createNotificationSettingsIntent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
||||||
|
setTheme(R.style.DarkTheme);
|
||||||
|
// Make sure we get an Alert for every uncaught exceptions
|
||||||
|
registerUncaughtExceptionHandler(MainActivity.this);
|
||||||
|
|
||||||
|
// Report memory details for this application
|
||||||
|
final ActivityManager activityManager = getActivityManager();
|
||||||
|
Log.v("RNBootstrap", "Available system memory "+getAvailableMemory(activityManager).availMem + ", maximum usable application memory " + activityManager.getLargeMemoryClass()+"M");
|
||||||
|
|
||||||
|
setSecureFlag();
|
||||||
|
|
||||||
|
// NOTE: Try to not restore the state https://github.com/software-mansion/react-native-screens/issues/17
|
||||||
|
super.onCreate(null);
|
||||||
|
|
||||||
|
if (!shouldShowRootedNotification()) {
|
||||||
|
configureStatus();
|
||||||
|
} else {
|
||||||
|
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
|
||||||
|
.setMessage(getResources().getString(R.string.root_warning))
|
||||||
|
.setPositiveButton(getResources().getString(R.string.root_okay), new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
rejectRootedNotification();
|
||||||
|
dialog.dismiss();
|
||||||
|
configureStatus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(getResources().getString(R.string.root_cancel), new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
dialog.dismiss();
|
||||||
|
MainActivity.this.finishAffinity();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setOnCancelListener(new OnCancelListener() {
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
dialog.dismiss();
|
||||||
|
MainActivity.this.finishAffinity();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.loadLibrary("status-logs");
|
||||||
|
|
||||||
|
// when app is started but the Activity has been destroyed, the deep linking url event is
|
||||||
|
// not emitted when coming back to foreground. This is a workaround. If the problem is
|
||||||
|
// resolved in react-native this code should be removed
|
||||||
|
if (getIntent().getData() != null) {
|
||||||
|
WritableMap event = Arguments.createMap();
|
||||||
|
event.putString("url", getIntent().getDataString());
|
||||||
|
// on first start emit will (silently) fail, but the regular deep linking handler will work
|
||||||
|
tryToEmit("url", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
splashScreen.setKeepOnScreenCondition(() -> keepSplash);
|
||||||
|
|
||||||
|
Handler handler = new Handler();
|
||||||
|
handler.postDelayed(() -> keepSplash = false, SPLASH_DELAY);
|
||||||
|
|
||||||
|
StatusThreadPoolExecutor.getInstance().execute(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
Intent intent = new Intent("onConfigurationChanged");
|
||||||
|
intent.putExtra("newConfig", newConfig);
|
||||||
|
this.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String REJECTED_ROOTED_NOTIFICATION = "rejectedRootedNotification";
|
||||||
|
private static final Integer FREQUENCY_OF_REMINDER_IN_PERCENT = 5;
|
||||||
|
|
||||||
|
private boolean shouldShowRootedNotification() {
|
||||||
|
if (RootUtil.isDeviceRooted() && BuildConfig.ENABLE_ROOT_ALERT == "1") {
|
||||||
|
if (userRejectedRootedNotification()) {
|
||||||
|
return ((Math.random() * 100) < FREQUENCY_OF_REMINDER_IN_PERCENT);
|
||||||
|
} else return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean userRejectedRootedNotification() {
|
||||||
|
SharedPreferences preferences = getPreferences(0);
|
||||||
|
return preferences.getBoolean(REJECTED_ROOTED_NOTIFICATION, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rejectRootedNotification() {
|
||||||
|
SharedPreferences preferences = getPreferences(0);
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
editor.putBoolean(REJECTED_ROOTED_NOTIFICATION, true);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSecureFlag() {
|
||||||
|
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
final boolean setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", false);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
} else {
|
||||||
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.M)
|
||||||
|
public void requestPermissions(String[] permissions, int requestCode, PermissionListener listener) {
|
||||||
|
mPermissionListener = listener;
|
||||||
|
requestPermissions(permissions, requestCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
if (mPermissionListener != null && mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
|
||||||
|
mPermissionListener = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
package im.status.ethereum
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.app.AlertDialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.preference.PreferenceManager
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.annotation.Nullable
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
|
||||||
import com.facebook.react.ReactActivityDelegate
|
|
||||||
import com.facebook.react.bridge.Arguments
|
|
||||||
import com.facebook.react.bridge.WritableMap
|
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
|
|
||||||
import com.facebook.react.defaults.DefaultReactActivityDelegate
|
|
||||||
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
||||||
import com.facebook.react.modules.core.PermissionListener
|
|
||||||
import com.reactnativenavigation.NavigationActivity
|
|
||||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView
|
|
||||||
import im.status.ethereum.MainApplication
|
|
||||||
import im.status.ethereum.module.StatusThreadPoolExecutor
|
|
||||||
import java.util.Properties
|
|
||||||
|
|
||||||
class MainActivity : NavigationActivity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private var mPermissionListener: PermissionListener? = null
|
|
||||||
private var keepSplash = true
|
|
||||||
private val SPLASH_DELAY = 3200
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
|
||||||
* rendering of the component.
|
|
||||||
*/
|
|
||||||
protected fun getMainComponentName(): String {
|
|
||||||
return "StatusIm"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerUncaughtExceptionHandler(context: Context) {
|
|
||||||
val defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
|
|
||||||
// High priority, so don't use StatusThreadPoolExecutor
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler { thread, t ->
|
|
||||||
Thread {
|
|
||||||
Looper.prepare()
|
|
||||||
AlertDialog.Builder(context)
|
|
||||||
.setTitle("Error")
|
|
||||||
.setMessage(t.toString())
|
|
||||||
.setNegativeButton("Exit") { dialog, id ->
|
|
||||||
dialog.dismiss()
|
|
||||||
defaultUncaughtExceptionHandler.uncaughtException(thread, t)
|
|
||||||
}.show()
|
|
||||||
Looper.loop()
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getActivityManager(): ActivityManager {
|
|
||||||
return getSystemService(ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAvailableMemory(activityManager: ActivityManager): ActivityManager.MemoryInfo {
|
|
||||||
val memoryInfo = ActivityManager.MemoryInfo()
|
|
||||||
activityManager.getMemoryInfo(memoryInfo)
|
|
||||||
return memoryInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun configureStatus() {
|
|
||||||
// Required because of crazy APN settings redirecting localhost (found in GB)
|
|
||||||
val properties = System.getProperties()
|
|
||||||
properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1")
|
|
||||||
properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createNotificationSettingsIntent(): Intent {
|
|
||||||
val intent = Intent()
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
|
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
|
|
||||||
} else {
|
|
||||||
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
|
||||||
intent.addCategory(Intent.CATEGORY_DEFAULT)
|
|
||||||
intent.data = Uri.parse("package:$packageName")
|
|
||||||
}
|
|
||||||
return intent
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryToEmit(eventName: String, event: WritableMap) {
|
|
||||||
try {
|
|
||||||
(getApplication() as MainApplication).reactNativeHost
|
|
||||||
.getReactInstanceManager()
|
|
||||||
.getCurrentReactContext()
|
|
||||||
?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
||||||
?.emit("url", event)
|
|
||||||
} catch (e: Exception) { // we expect NPE on first start, which is OK because we have a fallback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
|
||||||
super.onNewIntent(intent)
|
|
||||||
if (intent.dataString != null && intent.data!!.scheme!!.startsWith("app-settings")) {
|
|
||||||
startActivity(createNotificationSettingsIntent())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
val splashScreen = installSplashScreen();
|
|
||||||
setTheme(R.style.DarkTheme)
|
|
||||||
// Make sure we get an Alert for every uncaught exceptions
|
|
||||||
registerUncaughtExceptionHandler(this)
|
|
||||||
|
|
||||||
// Report memory details for this application
|
|
||||||
val activityManager = getActivityManager()
|
|
||||||
Log.v("RNBootstrap", "Available system memory " + getAvailableMemory(activityManager).availMem + ", maximum usable application memory " + activityManager.largeMemoryClass + "M")
|
|
||||||
|
|
||||||
setSecureFlag()
|
|
||||||
|
|
||||||
// NOTE: Try to not restore the state https://github.com/software-mansion/react-native-screens/issues/17
|
|
||||||
super.onCreate(null)
|
|
||||||
|
|
||||||
if (!shouldShowRootedNotification()) {
|
|
||||||
configureStatus()
|
|
||||||
} else {
|
|
||||||
val dialog = AlertDialog.Builder(this)
|
|
||||||
.setMessage(resources.getString(R.string.root_warning))
|
|
||||||
.setPositiveButton(resources.getString(R.string.root_okay)) { dialog, which ->
|
|
||||||
rejectRootedNotification()
|
|
||||||
dialog.dismiss()
|
|
||||||
configureStatus()
|
|
||||||
}
|
|
||||||
.setNegativeButton(resources.getString(R.string.root_cancel)) { dialog, which ->
|
|
||||||
dialog.dismiss()
|
|
||||||
finishAffinity()
|
|
||||||
}
|
|
||||||
.setOnCancelListener {
|
|
||||||
it.dismiss()
|
|
||||||
finishAffinity()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
val r = Runnable {
|
|
||||||
System.loadLibrary("status-logs")
|
|
||||||
|
|
||||||
// when app is started but the Activity has been destroyed, the deep linking url event is
|
|
||||||
// not emitted when coming back to foreground. This is a workaround. If the problem is
|
|
||||||
// resolved in react-native this code should be removed
|
|
||||||
if (intent.data != null) {
|
|
||||||
val event = Arguments.createMap()
|
|
||||||
event.putString("url", intent.dataString)
|
|
||||||
// on first start emit will (silently) fail, but the regular deep linking handler will work
|
|
||||||
tryToEmit("url", event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
splashScreen.setKeepOnScreenCondition { keepSplash }
|
|
||||||
|
|
||||||
val handler = Handler()
|
|
||||||
handler.postDelayed({ keepSplash = false }, SPLASH_DELAY.toLong())
|
|
||||||
|
|
||||||
StatusThreadPoolExecutor.getInstance().execute(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
||||||
super.onConfigurationChanged(newConfig)
|
|
||||||
val intent = Intent("onConfigurationChanged")
|
|
||||||
intent.putExtra("newConfig", newConfig)
|
|
||||||
sendBroadcast(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val REJECTED_ROOTED_NOTIFICATION = "rejectedRootedNotification"
|
|
||||||
private val FREQUENCY_OF_REMINDER_IN_PERCENT = 5
|
|
||||||
|
|
||||||
private fun shouldShowRootedNotification(): Boolean {
|
|
||||||
if (RootUtil.isDeviceRooted() && BuildConfig.ENABLE_ROOT_ALERT == "1") {
|
|
||||||
return if (userRejectedRootedNotification()) {
|
|
||||||
(Math.random() * 100) < FREQUENCY_OF_REMINDER_IN_PERCENT
|
|
||||||
} else true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun userRejectedRootedNotification(): Boolean {
|
|
||||||
val preferences = getPreferences(0)
|
|
||||||
return preferences.getBoolean(REJECTED_ROOTED_NOTIFICATION, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun rejectRootedNotification() {
|
|
||||||
val preferences = getPreferences(0)
|
|
||||||
val editor = preferences.edit()
|
|
||||||
editor.putBoolean(REJECTED_ROOTED_NOTIFICATION, true)
|
|
||||||
editor.commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setSecureFlag() {
|
|
||||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
|
|
||||||
val setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", false)
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && setSecure) {
|
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
|
||||||
} else {
|
|
||||||
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
|
||||||
override fun requestPermissions(permissions: Array<String>, requestCode: Int, listener: PermissionListener) {
|
|
||||||
mPermissionListener = listener
|
|
||||||
super.requestPermissions(permissions, requestCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
|
||||||
if (mPermissionListener != null && mPermissionListener!!.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
|
|
||||||
mPermissionListener = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package im.status.ethereum;
|
||||||
|
|
||||||
|
import androidx.multidex.MultiDexApplication;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import com.facebook.react.PackageList;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactApplication;
|
||||||
|
import cl.json.RNSharePackage;
|
||||||
|
import com.facebook.react.ReactNativeHost;
|
||||||
|
import com.reactnativenavigation.NavigationApplication;
|
||||||
|
import com.reactnativenavigation.react.NavigationReactNativeHost;
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||||
|
import com.reactnativecommunity.blurview.BlurViewPackage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import im.status.ethereum.keycard.RNStatusKeycardPackage;
|
||||||
|
import im.status.ethereum.module.StatusPackage;
|
||||||
|
import im.status.ethereum.pushnotifications.PushNotificationPackage;
|
||||||
|
import im.status.ethereum.StatusOkHttpClientFactory;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.JSIModulePackage;
|
||||||
|
|
||||||
|
public class MainApplication extends NavigationApplication {
|
||||||
|
|
||||||
|
private final ReactNativeHost mReactNativeHost = new NavigationReactNativeHost(this) {
|
||||||
|
@Override
|
||||||
|
public boolean getUseDeveloperSupport() {
|
||||||
|
return BuildConfig.DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ReactPackage> getPackages() {
|
||||||
|
|
||||||
|
StatusPackage statusPackage = new StatusPackage(RootUtil.isDeviceRooted());
|
||||||
|
|
||||||
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
|
packages.add(statusPackage);
|
||||||
|
packages.add(new RNStatusKeycardPackage());
|
||||||
|
packages.add(new PushNotificationPackage());
|
||||||
|
packages.add(new BlurViewPackage());
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getJSMainModuleName() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isNewArchEnabled() {
|
||||||
|
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean isHermesEnabled() {
|
||||||
|
return BuildConfig.IS_HERMES_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReactNativeHost getReactNativeHost() {
|
||||||
|
return mReactNativeHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
OkHttpClientProvider.setOkHttpClientFactory(new StatusOkHttpClientFactory());
|
||||||
|
|
||||||
|
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
|
||||||
|
|
||||||
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||||
|
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||||
|
DefaultNewArchitectureEntryPoint.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package im.status.ethereum
|
|
||||||
|
|
||||||
import android.webkit.WebView
|
|
||||||
import androidx.multidex.MultiDexApplication
|
|
||||||
import com.facebook.react.PackageList
|
|
||||||
import com.facebook.react.ReactApplication
|
|
||||||
import com.facebook.react.ReactNativeHost
|
|
||||||
import com.facebook.react.ReactPackage
|
|
||||||
import com.facebook.react.bridge.JSIModulePackage
|
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
|
|
||||||
import com.facebook.react.modules.network.OkHttpClientProvider
|
|
||||||
import com.reactnativenavigation.NavigationApplication
|
|
||||||
import com.reactnativenavigation.react.NavigationReactNativeHost
|
|
||||||
import cl.json.RNSharePackage
|
|
||||||
import com.reactnativecommunity.blurview.BlurViewPackage
|
|
||||||
import im.status.ethereum.keycard.RNStatusKeycardPackage
|
|
||||||
import im.status.ethereum.module.StatusPackage
|
|
||||||
import im.status.ethereum.pushnotifications.PushNotificationPackage
|
|
||||||
import im.status.ethereum.StatusOkHttpClientFactory
|
|
||||||
|
|
||||||
class MainApplication : NavigationApplication() {
|
|
||||||
|
|
||||||
private val mReactNativeHost = object : NavigationReactNativeHost(this) {
|
|
||||||
override fun getUseDeveloperSupport(): Boolean {
|
|
||||||
return BuildConfig.DEBUG
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPackages(): List<ReactPackage> =
|
|
||||||
PackageList(this).packages.apply {
|
|
||||||
// Packages that cannot be autolinked yet can be added manually here
|
|
||||||
add(StatusPackage(RootUtil.isDeviceRooted()))
|
|
||||||
add(RNStatusKeycardPackage())
|
|
||||||
add(PushNotificationPackage())
|
|
||||||
add(BlurViewPackage())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getJSMainModuleName(): String = "index"
|
|
||||||
|
|
||||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
||||||
|
|
||||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
|
|
||||||
}
|
|
||||||
|
|
||||||
override val reactNativeHost: ReactNativeHost
|
|
||||||
get() = mReactNativeHost
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
|
|
||||||
OkHttpClientProvider.setOkHttpClientFactory(StatusOkHttpClientFactory())
|
|
||||||
|
|
||||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1")
|
|
||||||
|
|
||||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
||||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
|
||||||
DefaultNewArchitectureEntryPoint.load()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package im.status.ethereum;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/** @author Kevin Kowalewski */
|
||||||
|
public class RootUtil {
|
||||||
|
|
||||||
|
public static boolean isDeviceRooted() {
|
||||||
|
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkRootMethod1() {
|
||||||
|
String buildTags = android.os.Build.TAGS;
|
||||||
|
return buildTags != null && buildTags.contains("test-keys");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkRootMethod2() {
|
||||||
|
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
|
||||||
|
"/system/bin/failsafe/su", "/data/local/su" };
|
||||||
|
for (String path : paths) {
|
||||||
|
if (new File(path).exists()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkRootMethod3() {
|
||||||
|
Process process = null;
|
||||||
|
try {
|
||||||
|
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
return in.readLine() != null;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (process != null) process.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package im.status.ethereum
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.File
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
|
|
||||||
object RootUtil {
|
|
||||||
|
|
||||||
fun isDeviceRooted(): Boolean =
|
|
||||||
checkRootMethod1() || checkRootMethod2() || checkRootMethod3()
|
|
||||||
|
|
||||||
private fun checkRootMethod1(): Boolean =
|
|
||||||
Build.TAGS?.contains("test-keys") ?: false
|
|
||||||
|
|
||||||
private fun checkRootMethod2(): Boolean {
|
|
||||||
val paths = arrayOf(
|
|
||||||
"/system/app/Superuser.apk",
|
|
||||||
"/sbin/su",
|
|
||||||
"/system/bin/su",
|
|
||||||
"/system/xbin/su",
|
|
||||||
"/data/local/xbin/su",
|
|
||||||
"/data/local/bin/su",
|
|
||||||
"/system/sd/xbin/su",
|
|
||||||
"/system/bin/failsafe/su",
|
|
||||||
"/data/local/su"
|
|
||||||
)
|
|
||||||
return paths.any { File(it).exists() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkRootMethod3(): Boolean {
|
|
||||||
var process: Process? = null
|
|
||||||
return try {
|
|
||||||
process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
|
|
||||||
BufferedReader(InputStreamReader(process.inputStream)).readLine() != null
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
false
|
|
||||||
} finally {
|
|
||||||
process?.destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package im.status.ethereum
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.facebook.react.modules.network.OkHttpClientFactory
|
|
||||||
import com.facebook.react.modules.network.OkHttpClientProvider
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.tls.HandshakeCertificates
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
import java.lang.RuntimeException
|
|
||||||
import java.lang.reflect.Field
|
|
||||||
import java.lang.reflect.Method
|
|
||||||
import java.security.cert.CertificateFactory
|
|
||||||
import java.security.cert.X509Certificate
|
|
||||||
import im.status.ethereum.module.StatusPackage
|
|
||||||
|
|
||||||
class StatusOkHttpClientFactory : OkHttpClientFactory {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "StatusOkHttpClientFactory"
|
|
||||||
private const val SLEEP_DURATION = 500L // milliseconds
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createNewNetworkModuleClient(): OkHttpClient? {
|
|
||||||
val certPem = getCertificatePem().takeIf { it.isNotEmpty() }
|
|
||||||
?: return logAndReturnNull("Certificate is empty, cannot create OkHttpClient without a valid certificate")
|
|
||||||
|
|
||||||
val cert = try {
|
|
||||||
induceSleep()
|
|
||||||
// Convert PEM certificate string to X509Certificate object
|
|
||||||
CertificateFactory.getInstance("X.509")
|
|
||||||
.generateCertificate(ByteArrayInputStream(certPem.toByteArray())) as? X509Certificate
|
|
||||||
?: return logAndReturnNull("Certificate could not be parsed as non-null")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return logAndReturnNull("Could not parse certificate", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
val clientCertificates = try {
|
|
||||||
induceSleep()
|
|
||||||
// Create HandshakeCertificates object with our certificate
|
|
||||||
HandshakeCertificates.Builder()
|
|
||||||
.addPlatformTrustedCertificates()
|
|
||||||
.addTrustedCertificate(cert)
|
|
||||||
.build()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return logAndReturnNull("Could not build HandshakeCertificates", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return try {
|
|
||||||
OkHttpClientProvider.createClientBuilder()
|
|
||||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager)
|
|
||||||
.build()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logAndReturnNull("Could not create OkHttpClient", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getCertificatePem(): String {
|
|
||||||
return try {
|
|
||||||
// Create OkHttpClient with custom SSL socket factory and trust manager
|
|
||||||
StatusPackage.getImageTLSCert().takeIf { !it.isNullOrBlank() }
|
|
||||||
?: logAndReturnEmpty("Certificate PEM string is null or empty")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logAndReturnEmpty("Could not getImageTLSCert", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun induceSleep() {
|
|
||||||
try {
|
|
||||||
// induce half second sleep because sometimes a cert is not immediately available
|
|
||||||
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
|
||||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
|
||||||
Thread.sleep(SLEEP_DURATION)
|
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
Log.e(TAG, "Sleep interrupted", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun logAndReturnNull(message: String, e: Exception? = null): Nothing? {
|
|
||||||
Log.e(TAG, message, e)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun logAndReturnEmpty(message: String, e: Exception? = null): String {
|
|
||||||
Log.e(TAG, message, e)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package im.status.ethereum;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientFactory;
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.tls.HandshakeCertificates;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.RuntimeException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import im.status.ethereum.module.StatusPackage;
|
||||||
|
|
||||||
|
class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
||||||
|
|
||||||
|
private static final String TAG = "StatusOkHttpClientFactory";
|
||||||
|
|
||||||
|
public OkHttpClient createNewNetworkModuleClient() {
|
||||||
|
X509Certificate cert = null;
|
||||||
|
HandshakeCertificates clientCertificates;
|
||||||
|
String certPem = "";
|
||||||
|
// Get TLS PEM certificate from status-go
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
certPem = getCertificatePem();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (certPem.isEmpty()) {
|
||||||
|
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert PEM certificate string to X509Certificate object
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not parse certificate",e);
|
||||||
|
}
|
||||||
|
// Create HandshakeCertificates object with our certificate
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
clientCertificates = new HandshakeCertificates.Builder()
|
||||||
|
.addPlatformTrustedCertificates()
|
||||||
|
.addTrustedCertificate(cert)
|
||||||
|
.build();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not build HandshakeCertificates", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create OkHttpClient with custom SSL socket factory and trust manager
|
||||||
|
try {
|
||||||
|
return OkHttpClientProvider.createClientBuilder()
|
||||||
|
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
|
||||||
|
.build();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not create OkHttpClient", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private String getCertificatePem() {
|
||||||
|
try {
|
||||||
|
String certPem = StatusPackage.getImageTLSCert();
|
||||||
|
if (certPem == null || certPem.trim().isEmpty()) {
|
||||||
|
Log.e(TAG, "Certificate PEM string is null or empty");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return certPem;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Could not getImageTLSCert", e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 92 B |
|
Before Width: | Height: | Size: 940 B After Width: | Height: | Size: 498 B |
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 100 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 972 B |
|
After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 452 B After Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 108 B |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 824 B After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 69 KiB |
@@ -2,5 +2,4 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_background"/>
|
<background android:drawable="@mipmap/ic_background"/>
|
||||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
</adaptive-icon>
|
||||||
</adaptive-icon>
|
|
||||||
@@ -2,5 +2,4 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_background"/>
|
<background android:drawable="@mipmap/ic_background"/>
|
||||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
</adaptive-icon>
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 374 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 239 B |
|
Before Width: | Height: | Size: 737 B After Width: | Height: | Size: 678 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 970 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 905 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 10 KiB |
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
ext {
|
ext {
|
||||||
// kotlin_version is needed for react-native-camera-kit library
|
// kotlin_version is needed for react-native-camera-kit library
|
||||||
kotlin_version = project.kotlinPluginVersion
|
kotlin_version = project.kotlinVersion
|
||||||
RNNKotlinVersion = project.kotlinPluginVersion
|
RNNKotlinVersion = project.kotlinPluginVersion
|
||||||
RNGH_kotlinVersion = project.kotlinPluginVersion
|
RNGH_kotlinVersion = project.kotlinPluginVersion
|
||||||
buildToolsVersion = project.buildToolsVersion
|
buildToolsVersion = project.buildToolsVersion
|
||||||
@@ -14,9 +14,8 @@ ext {
|
|||||||
targetSdkVersion = Integer.valueOf(project.targetSdkVersion)
|
targetSdkVersion = Integer.valueOf(project.targetSdkVersion)
|
||||||
supportLibVersion = project.supportLibVersion
|
supportLibVersion = project.supportLibVersion
|
||||||
gradlePluginVersion = project.gradlePluginVersion
|
gradlePluginVersion = project.gradlePluginVersion
|
||||||
kotlinVersion = project.kotlinPluginVersion
|
|
||||||
kotlinPluginVersion = project.kotlinPluginVersion
|
kotlinPluginVersion = project.kotlinPluginVersion
|
||||||
kotlinToolsVersion = project.kotlinPluginVersion
|
|
||||||
ndkVersion = "25.2.9519653"
|
ndkVersion = "25.2.9519653"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +29,6 @@ buildscript {
|
|||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinPluginVersion}"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.ext.kotlinPluginVersion}"
|
||||||
classpath("com.android.tools.build:gradle")
|
classpath("com.android.tools.build:gradle")
|
||||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,30 +42,11 @@ subprojects {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// Speed up Tests Stage
|
|
||||||
tasks.withType(Test).configureEach {
|
|
||||||
// https://docs.gradle.org/current/userguide/performance.html#execute_tests_in_parallel
|
|
||||||
maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
|
|
||||||
// https://docs.gradle.org/current/userguide/performance.html#fork_tests_into_multiple_processes
|
|
||||||
forkEvery = 100
|
|
||||||
// https://docs.gradle.org/current/userguide/performance.html#disable_reports
|
|
||||||
reports.html.required = false
|
|
||||||
reports.junitXml.required = false
|
|
||||||
}
|
|
||||||
// Speed up Java Compile Stage
|
|
||||||
// https://docs.gradle.org/current/userguide/performance.html#run_the_compiler_as_a_separate_process
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
|
||||||
options.fork = true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: "com.facebook.react.rootproject"
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
beforeEvaluate {
|
beforeEvaluate {
|
||||||
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
|
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
|
||||||
|
|||||||
@@ -21,14 +21,15 @@
|
|||||||
# $keytool -genkey -v -keystore ./status-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias status
|
# $keytool -genkey -v -keystore ./status-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias status
|
||||||
|
|
||||||
# Version requirements used throughout the Gradle scripts
|
# Version requirements used throughout the Gradle scripts
|
||||||
|
kotlinVersion=1.7.22
|
||||||
minSdkVersion=24
|
minSdkVersion=24
|
||||||
compileSdkVersion=34
|
compileSdkVersion=33
|
||||||
targetSdkVersion=34
|
targetSdkVersion=33
|
||||||
buildToolsVersion=34.0.0
|
buildToolsVersion=33.0.0
|
||||||
supportLibVersion=28.0.0
|
supportLibVersion=28.0.0
|
||||||
# This should match version from nix/pkgs/aapt2/default.nix
|
# This should match version from nix/pkgs/aapt2/default.nix
|
||||||
gradlePluginVersion=7.4.2
|
gradlePluginVersion=7.4.2
|
||||||
kotlinPluginVersion=1.9.0
|
kotlinPluginVersion=1.7.22
|
||||||
|
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
@@ -38,12 +39,12 @@ KEYSTORE_PASSWORD=password
|
|||||||
KEYSTORE_ALIAS=status
|
KEYSTORE_ALIAS=status
|
||||||
KEYSTORE_KEY_PASSWORD=password
|
KEYSTORE_KEY_PASSWORD=password
|
||||||
|
|
||||||
# Splitting by CPU Architecture produces smaller APKs.
|
# By default we build a mostly universal APK
|
||||||
ANDROID_ABI_SPLIT=true
|
ANDROID_ABI_SPLIT=false
|
||||||
# By default its better to only build apk for most recent devices.
|
# Some platforms are excluded though
|
||||||
ANDROID_ABI_INCLUDE=arm64-v8a
|
ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86
|
||||||
|
|
||||||
org.gradle.jvmargs=-Xmx8704M -XX:+UseParallelGC
|
org.gradle.jvmargs=-Xmx8704M
|
||||||
|
|
||||||
versionCode=9999
|
versionCode=9999
|
||||||
commitHash=unknown
|
commitHash=unknown
|
||||||
@@ -57,6 +58,4 @@ newArchEnabled=false
|
|||||||
|
|
||||||
# Use this property to enable or disable the Hermes JS engine.
|
# Use this property to enable or disable the Hermes JS engine.
|
||||||
# If set to false, you will be using JSC instead.
|
# If set to false, you will be using JSC instead.
|
||||||
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
|
hermesEnabled=true
|
||||||
# https://github.com/status-im/status-mobile/issues/18493
|
|
||||||
hermesEnabled=false
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
initscript {
|
|
||||||
repositories {
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath "org.gradle:github-dependency-graph-gradle-plugin:+"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
apply plugin: org.gradle.dependencygraph.simple.SimpleDependencyGraphPlugin
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
include ':react-native-share'
|
||||||
|
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal() // Let's prioritize local Maven repos so that Nix can provide them offline
|
mavenLocal() // Let's prioritize local Maven repos so that Nix can provide them offline
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
include ':react-native-share'
|
|
||||||
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
|
||||||
rootProject.name = 'StatusIm'
|
rootProject.name = 'StatusIm'
|
||||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||||
include ':react-native-nfc-manager'
|
include ':react-native-nfc-manager'
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['module:@react-native/babel-preset'],
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
plugins: ['react-native-reanimated/plugin', '@babel/plugin-transform-named-capturing-groups-regex'],
|
plugins: ['react-native-reanimated/plugin', '@babel/plugin-transform-named-capturing-groups-regex'],
|
||||||
|
env: {
|
||||||
|
test: {
|
||||||
|
presets: [
|
||||||
|
'@babel/preset-react',
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
{
|
||||||
|
targets: {
|
||||||
|
node: 'current',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.9.20'
|
library 'status-jenkins-lib@v1.7.15'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux && x86_64 && nix-2.24' }
|
agent { label 'linux && x86_64 && nix-2.14' }
|
||||||
|
|
||||||
options {
|
options {
|
||||||
timestamps()
|
timestamps()
|
||||||
@@ -15,7 +15,7 @@ pipeline {
|
|||||||
buildDiscarder(logRotator(
|
buildDiscarder(logRotator(
|
||||||
numToKeepStr: '10',
|
numToKeepStr: '10',
|
||||||
daysToKeepStr: '20',
|
daysToKeepStr: '20',
|
||||||
artifactNumToKeepStr: '1',
|
artifactNumToKeepStr: '10',
|
||||||
))
|
))
|
||||||
/* Allows combined build to copy */
|
/* Allows combined build to copy */
|
||||||
copyArtifactPermission('/status-mobile/*')
|
copyArtifactPermission('/status-mobile/*')
|
||||||
@@ -34,14 +34,13 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
LANG = 'en_US.UTF-8'
|
LANG = "en_US.UTF-8"
|
||||||
LC_ALL = 'en_US.UTF-8'
|
LC_ALL = "en_US.UTF-8"
|
||||||
LANGUAGE = 'en_US.UTF-8'
|
LANGUAGE = "en_US.UTF-8"
|
||||||
PLATFORM = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||||
BUILD_ENV = 'prod'
|
BUILD_ENV = 'prod'
|
||||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||||
FASTLANE_DISABLE_COLORS = 1
|
FASTLANE_DISABLE_COLORS = 1
|
||||||
SENTRY_PRODUCTION = "${utils.isReleaseBuild() ? 'true' : 'false'}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
@@ -72,8 +71,12 @@ pipeline {
|
|||||||
}
|
}
|
||||||
stage('Upload') {
|
stage('Upload') {
|
||||||
steps { script {
|
steps { script {
|
||||||
def urls = apks.collect { s5cmd.upload(it) }
|
def urls = apks.collect { s3.uploadArtifact(it) }
|
||||||
env.PKG_URL = urls.first()
|
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||||
|
env.PKG_URL = urls.find { it.contains('universal') }
|
||||||
|
} else { /* If no universal is available pick first. */
|
||||||
|
env.PKG_URL = urls.first()
|
||||||
|
}
|
||||||
jenkins.setBuildDesc(APK: env.PKG_URL)
|
jenkins.setBuildDesc(APK: env.PKG_URL)
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
|
|||||||