Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb129b97f3 |
@@ -0,0 +1,186 @@
|
||||
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.transport.core-test/messages
|
||||
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"]
|
||||
:output {:exclude-files ["src/user.cljs" "src/dev/user.cljs"]}
|
||||
:lint-as {legacy.status-im.utils.views/defview clojure.core/defn
|
||||
legacy.status-im.utils.views/letsubs clojure.core/let
|
||||
reagent.core/with-let clojure.core/let
|
||||
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clojure.core/defn
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
legacy.status-im.utils.styles/def clojure.core/def
|
||||
legacy.status-im.utils.styles/defn clojure.core/defn
|
||||
test-helpers.unit/deftest-sub clojure.core/defn
|
||||
test-helpers.unit/deftest-event clojure.core/defn
|
||||
|
||||
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}
|
||||
:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||
status-im.utils.views/letsubs clojure.core/let
|
||||
reagent.core/with-let clojure.core/let
|
||||
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
status-im.utils.styles/def clojure.core/def
|
||||
status-im.utils.styles/defn clojure.core/defn
|
||||
test-helpers.unit/deftest-sub clojure.core/defn
|
||||
taoensso.tufte/defnp clojure.core/defn}
|
||||
:linters {:case-duplicate-test {:level :error}
|
||||
:case-quoted-test {:level :error}
|
||||
:case-symbol-test {:level :error}
|
||||
:clj-kondo-config {:level :error}
|
||||
:cond-else {:level :error}
|
||||
:condition-always-true {:level :error}
|
||||
:conflicting-alias {:level :error}
|
||||
:consistent-alias {:level :error
|
||||
:aliases {clojure.set set
|
||||
clojure.string string
|
||||
clojure.walk walk
|
||||
malli.core malli
|
||||
malli.dev.pretty malli.pretty
|
||||
malli.dev.virhe malli.virhe
|
||||
malli.error malli.error
|
||||
malli.generator malli.generator
|
||||
malli.transform malli.transform
|
||||
malli.util malli.util
|
||||
promesa.core promesa
|
||||
schema.core schema
|
||||
status-im.feature-flags ff
|
||||
taoensso.timbre log}}
|
||||
:aliases {clojure.set set
|
||||
clojure.string string
|
||||
clojure.walk walk
|
||||
malli.core malli
|
||||
malli.dev.pretty malli.pretty
|
||||
malli.dev.virhe malli.virhe
|
||||
malli.error malli.error
|
||||
malli.generator malli.generator
|
||||
malli.transform malli.transform
|
||||
malli.util malli.util
|
||||
schema.core schema
|
||||
taoensso.timbre log}}
|
||||
:deprecated-namespace {:level :warning}
|
||||
:docstring-blank {:level :error}
|
||||
:equals-true {:level :error}
|
||||
:inline-def {:level :error}
|
||||
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
|
||||
utils.re-frame/defn
|
||||
utils.re-frame/merge]}
|
||||
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||
:loop-without-recur {:level :error}
|
||||
:minus-one {:level :error}
|
||||
:misplaced-docstring {:level :error}
|
||||
:missing-body-in-when {:level :error}
|
||||
:missing-clause-in-try {:level :error}
|
||||
:missing-else-branch {:level :error}
|
||||
:multiple-async-in-deftest {:level :error}
|
||||
:not-empty? {:level :error}
|
||||
:plus-one {:level :error}
|
||||
:redundant-do {:level :error}
|
||||
:redundant-let {: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
|
||||
;; We temporarily use :include to define an
|
||||
;; allowlist of core Clojure vars. In the
|
||||
@@ -86,11 +51,9 @@
|
||||
;; vars, we should be able to delete this
|
||||
;; option and lint all vars.
|
||||
:exclude [type name]}
|
||||
:self-requiring-namespace {:level :error}
|
||||
:single-operand-comparison {:level :error}
|
||||
:syntax {:level :error}
|
||||
:unbound-destructuring-default {:level :error}
|
||||
:underscore-in-namespace {:level :error}
|
||||
:uninitialized-var {:level :error}
|
||||
:unknown-require-option {:level :error}
|
||||
:unreachable-code {:level :error}
|
||||
@@ -99,8 +62,7 @@
|
||||
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||
number
|
||||
legacy.status-im.test-helpers/restore-app-db
|
||||
(cljs.test/is [match-strict?])]}
|
||||
status-im.test-helpers/restore-app-db]}
|
||||
:unresolved-var {:level :error}
|
||||
:unsorted-required-namespaces {:level :error}
|
||||
: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,4 +0,0 @@
|
||||
{:linters
|
||||
{:unresolved-symbol
|
||||
{:exclude [(cljs.test/is [match? thrown-match?])
|
||||
(clojure.test/is [match? thrown-match?])]}}}
|
||||
@@ -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
|
||||
{:analyze-call
|
||||
{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}}}
|
||||
{:hooks {:analyze-call {utils.i18n/label utils.i18n/label}}
|
||||
:linters {:status-im.linter/invalid-translation-keyword {: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
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
DEV_BUILD=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -24,6 +26,7 @@ APN_TOPIC=im.status.ethereum.pr
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
COMMANDS_ENABLED=1
|
||||
TWO_MINUTES_SYNCING=1
|
||||
SWAP_ENABLED=1
|
||||
@@ -31,10 +34,3 @@ STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
TEST_STATEOFUS=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
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.staging
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||
@@ -21,8 +22,8 @@ KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
||||
VERIFY_ENS_CHAIN_ID=11155111
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
COMMUNITIES_ENABLED=1
|
||||
@@ -32,13 +33,3 @@ TWO_MINUTES_SYNCING=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_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
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
@@ -20,8 +22,8 @@ KEYCARD_TEST_MENU=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
||||
VERIFY_ENS_CHAIN_ID=11155111
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
BLANK_PREVIEW=0
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
@@ -33,9 +35,3 @@ ENABLE_QUO_PREVIEW=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_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
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -20,9 +22,3 @@ COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
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
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
LOG_LEVEL=
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -16,10 +18,5 @@ PARTITIONED_TOPIC=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
MAX_IMAGES_BATCH=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
TEST_NETWORKS_ENABLED=0
|
||||
STATUS_PROXY_STAGE_NAME=prod
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
API_LOGGING_ENABLED=1
|
||||
SENTRY_ENABLED=1
|
||||
SENTRY_ENVIRONMENT=production
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native',
|
||||
extends: '@react-native-community',
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Bug Report
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
type: 'Bug'
|
||||
labels: 'E:Mobile Bug MVP'
|
||||
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)
|
||||
|
||||
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
|
||||
|
||||
*otherwise*
|
||||
|
||||
fixes #...
|
||||
|
||||
## Summary
|
||||
### Summary
|
||||
|
||||
[comment]: # (Summarise the problem and how the pull request solves it)
|
||||
...
|
||||
|
||||
## Review notes
|
||||
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
|
||||
<!-- (Optional, remove if no changes to documentation) -->
|
||||
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
|
||||
|
||||
## Testing notes
|
||||
[comment]: # (Optional)
|
||||
### Review notes
|
||||
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
|
||||
|
||||
### Platforms
|
||||
[comment]: # (Optional. Specify which platforms should be tested)
|
||||
### Testing notes
|
||||
<!-- (Optional) -->
|
||||
|
||||
#### Platforms
|
||||
<!-- (Optional. Specify which platforms should be tested) -->
|
||||
|
||||
- Android
|
||||
- iOS
|
||||
- macOS
|
||||
- Linux
|
||||
- Windows
|
||||
|
||||
### Areas that may be impacted
|
||||
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
|
||||
#### Areas that maybe impacted
|
||||
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
|
||||
|
||||
#### Functional
|
||||
##### Functional
|
||||
|
||||
- 1-1 chats
|
||||
- public chats
|
||||
@@ -35,36 +48,25 @@ fixes #...
|
||||
- fleet
|
||||
- bootnodes
|
||||
|
||||
#### Non-functional
|
||||
##### Non-functional
|
||||
|
||||
- battery performance
|
||||
- CPU performance / speed of the app
|
||||
- network consumption
|
||||
|
||||
## Steps to test
|
||||
[comment]: # (Specify exact steps to test if there are such)
|
||||
### Steps to test
|
||||
<!-- (Specify exact steps to test if there are such) -->
|
||||
|
||||
- Open Status
|
||||
- ...
|
||||
- Step 3, etc.
|
||||
|
||||
<!-- (PRs will only be accepted if squashed into single commit.) -->
|
||||
|
||||
[comment]: # (Can be ready or wip)
|
||||
status: ready
|
||||
### Before and after screenshots comparison
|
||||
|
||||
| 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
|
||||
|
||||
- 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.
|
||||
|
||||
|
||||
-->
|
||||
status: ready <!-- Can be ready or wip -->
|
||||
|
||||
@@ -36,10 +36,6 @@ project.xcworkspace
|
||||
**/android/.project
|
||||
**/android/.settings/org.eclipse.buildship.core.prefs
|
||||
local.properties
|
||||
*.hprof
|
||||
.cxx/
|
||||
*.keystore
|
||||
!debug.keystore
|
||||
|
||||
# Atom
|
||||
.tags*
|
||||
@@ -83,9 +79,6 @@ shim.js
|
||||
figwheel_server.log
|
||||
.nrepl-port
|
||||
|
||||
# FlowStorm (Clojure debugger)
|
||||
repl-client-debug
|
||||
|
||||
# Lein
|
||||
#
|
||||
.lein-failures
|
||||
@@ -130,8 +123,6 @@ fastlane/README.md
|
||||
# Clj
|
||||
|
||||
.cpcache/
|
||||
src/user.cljs
|
||||
src/dev/user.cljs
|
||||
|
||||
# emacs
|
||||
.dir-locals.el
|
||||
@@ -200,5 +191,6 @@ test/appium/tests/users.py
|
||||
## git hooks
|
||||
lefthook.yml
|
||||
|
||||
## build time logs
|
||||
/logs/*.log
|
||||
## clj-kondo
|
||||
/.clj-kondo/taoensso/*
|
||||
/.clj-kondo/babashka/*
|
||||
|
||||
@@ -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": [
|
||||
"target/test/legacy/status_im/**"
|
||||
"target/test/status_im/**"
|
||||
],
|
||||
"exclude": [
|
||||
"target/test/legacy/status_im/test/**",
|
||||
"target/test/legacy/status_im/ui/**"
|
||||
"target/test/status_im/test/**",
|
||||
"target/test/status_im/ui/**"
|
||||
],
|
||||
"report-dir": "./coverage-report",
|
||||
"all": true,
|
||||
@@ -14,4 +14,4 @@
|
||||
"exclude-after-remap": false,
|
||||
"extension": [".js"],
|
||||
"reporter": ["lcovonly"]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
/*
|
||||
|
||||
# Format top-level js files.
|
||||
*
|
||||
!*.js
|
||||
|
||||
# Ignore all except src/js/**/*.js
|
||||
!/src/
|
||||
/src/*
|
||||
!/src/js
|
||||
!/src/js/**/*.js
|
||||
|
||||
# Ignore all except translations/en.json
|
||||
!/translations/
|
||||
/translations/*
|
||||
!/translations/en.json
|
||||
!*/
|
||||
*.clj-kondo
|
||||
*.shadow-cljs
|
||||
modules
|
||||
result
|
||||
target
|
||||
component-spec
|
||||
/app
|
||||
|
||||
@@ -6,8 +6,4 @@ module.exports = {
|
||||
tabWidth: 2,
|
||||
trailingComma: 'all',
|
||||
useTabs: false,
|
||||
|
||||
// JSON sorting
|
||||
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
|
||||
plugins: ['prettier-plugin-sort-json'],
|
||||
};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{
|
||||
"ignore_dirs": [
|
||||
"android/build",
|
||||
"target",
|
||||
".clj-kondo",
|
||||
".shadow-cljs"
|
||||
"target"
|
||||
]
|
||||
}
|
||||
@@ -1,62 +1,53 @@
|
||||
;; -*- mode: clojure -*-
|
||||
;; vi: ft=clojure
|
||||
{:width 105
|
||||
:remove {:fn-force-nl #{:noarg1-body}}
|
||||
{:width 105
|
||||
:style [;; community style
|
||||
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
||||
:community
|
||||
|
||||
:style
|
||||
[;; community style https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
||||
:community
|
||||
;; no comma in map
|
||||
:no-comma
|
||||
|
||||
;; no comma in map
|
||||
:no-comma
|
||||
:custom-justify
|
||||
|
||||
: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-nl
|
||||
|
||||
;; 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]
|
||||
;; 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]
|
||||
:fn-map
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
"h/describe-skip" :arg1-body
|
||||
"h/describe-only" :arg1-body
|
||||
"h/test" :arg1-body
|
||||
"h/test-skip" :arg1-body
|
||||
"h/test-only" :arg1-body
|
||||
"test/async" :arg1-body
|
||||
"test/use-fixtures" :arg1-body
|
||||
"global.describe" :arg1-body
|
||||
"global.test" :arg1-body
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"reg-event-fx" :arg1-pair
|
||||
"reg-fx" :arg1-pair
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"deftest-event" :arg1-body
|
||||
"test-async" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
"with-deps-check" :arg1-body
|
||||
"schema/=>" :arg1-body
|
||||
"->" [: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"}
|
||||
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
"h/test" :arg1-body
|
||||
"global.describe" :arg1-body
|
||||
"global.test" :arg1-body
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"reg-event-fx" :arg1-pair
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
"with-deps-check" :arg1-body
|
||||
"schema/=>" :arg1-body
|
||||
"->" [: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"}
|
||||
:remove {:fn-force-nl #{:noarg1-body}}
|
||||
:style-map
|
||||
{:no-comma {:map {:comma? false}}
|
||||
{:no-comma {:map {:comma? false}}
|
||||
:custom-justify
|
||||
{:doc "Justify everything using pre-1.1.2 approach"
|
||||
:binding {:justify? true :justify {:max-variance 1000}}
|
||||
|
||||
@@ -32,19 +32,19 @@ ifndef BUILD_TAG
|
||||
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
||||
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)
|
||||
# This has to be specified for both the Node.JS server process and the Qt process.
|
||||
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.
|
||||
export NODE_OPTIONS += --openssl-legacy-provider
|
||||
# The path can be anything, but home is usually safest.
|
||||
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
|
||||
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
|
||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
||||
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
||||
@@ -54,6 +54,12 @@ export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
||||
# Useful for Android release builds
|
||||
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
|
||||
#----------------
|
||||
@@ -95,8 +101,6 @@ nix-purge: ##@nix Completely remove Nix setup, including /nix directory
|
||||
nix/scripts/purge.sh
|
||||
|
||||
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/deps/gradle/generate.sh
|
||||
|
||||
@@ -139,7 +143,7 @@ _install-hooks: ##@prepare Create prepare-commit-msg git hook symlink
|
||||
|
||||
# Remove directories and ignored files
|
||||
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
|
||||
|
||||
# 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
|
||||
cd ios && pod install; cd --
|
||||
|
||||
FLEETS_FILE := ./resources/config/fleets.json
|
||||
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
||||
curl -s https://fleets.status.im/ \
|
||||
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
||||
> $(FLEETS_FILE)
|
||||
echo >> $(FLEETS_FILE)
|
||||
> resources/config/fleets.json
|
||||
|
||||
$(KEYSTORE_PATH): export TARGET := keytool
|
||||
$(KEYSTORE_PATH):
|
||||
@@ -196,10 +198,6 @@ xcode-clean: XCODE_HOME := $(HOME)/Library/Developer/Xcode
|
||||
xcode-clean: ##@prepare Clean XCode derived data and archives
|
||||
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
|
||||
#----------------
|
||||
@@ -214,14 +212,16 @@ build-fdroid: ##@build Build release for F-Droid
|
||||
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
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
|
||||
@scripts/build-android.sh
|
||||
|
||||
release-android: export TARGET := keytool
|
||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
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 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: ##@run Start Metro to build React Native changes
|
||||
@scripts/run-metro.sh
|
||||
|
||||
export RE_FRISK_PORT ?= 4567
|
||||
@scripts/start-react-native.sh
|
||||
|
||||
run-re-frisk: export TARGET := clojure
|
||||
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
|
||||
run-android: export TARGET := android
|
||||
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
|
||||
# https://github.com/status-im/status-mobile/issues/18493
|
||||
run-android: export ORG_GRADLE_PROJECT_hermesEnabled := false
|
||||
run-android: export ORG_GRADLE_PROJECT_universalApk := false
|
||||
# INFO: If it's empty (no devices attached, parsing issues, script error) - for Nix it's the same as not set.
|
||||
run-android: export ANDROID_ABI_INCLUDE ?= $(shell ./scripts/adb_devices_abis.sh)
|
||||
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
|
||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
||||
run-ios: export TARGET := ios
|
||||
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
||||
run-ios: ##@run Build iOS app and start it in on the simulator
|
||||
@scripts/run-ios.sh "${SIMULATOR}"
|
||||
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
|
||||
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||
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
|
||||
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 IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
||||
run-ios-device: ##@run iOS app and start it on the first connected iPhone
|
||||
@scripts/run-ios-device.sh
|
||||
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||
run-ios-device: ##@run iOS app and start it on a connected device by its name
|
||||
ifndef DEVICE_NAME
|
||||
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
|
||||
endif
|
||||
react-native run-ios --device "$(DEVICE_NAME)"
|
||||
|
||||
#--------------
|
||||
# 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
|
||||
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
|
||||
|
||||
lint: export TARGET := clojure
|
||||
@@ -318,7 +319,7 @@ lint: ##@test Run code style checks
|
||||
scripts/lint/translations.clj && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
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
|
||||
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) && \
|
||||
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 && \
|
||||
node_modules/.bin/prettier --write .
|
||||
|
||||
@@ -334,88 +335,50 @@ shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
yarn shadow-cljs server
|
||||
|
||||
_test-clojure: export TARGET := clojure
|
||||
_test-clojure: export WATCH ?= false
|
||||
_test-clojure: status-go-library
|
||||
_test-clojure:
|
||||
ifeq ($(WATCH), true)
|
||||
yarn node-pre-gyp rebuild && \
|
||||
yarn shadow-cljs compile mocks && \
|
||||
nodemon --exec "yarn shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
|
||||
else
|
||||
yarn node-pre-gyp rebuild && \
|
||||
test-watch: export TARGET := clojure
|
||||
test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
|
||||
|
||||
test-watch-for-repl: export TARGET := clojure
|
||||
test-watch-for-repl: ##@ Watch tests and support REPL connections
|
||||
yarn install
|
||||
rm -f target/test/test.js
|
||||
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 test && \
|
||||
node --require ./test-resources/override.js "$$SHADOW_OUTPUT_TO"
|
||||
endif
|
||||
node --require ./test-resources/override.js target/test/test.js
|
||||
|
||||
test: export SHADOW_OUTPUT_TO := target/test/test.js
|
||||
test: export SHADOW_NS_REGEXP := .*-test$$
|
||||
test: ##@test Run all Clojure tests
|
||||
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
|
||||
android-test: jsbundle
|
||||
android-test: export TARGET := android
|
||||
android-test:
|
||||
cd android && ./gradlew test
|
||||
|
||||
test-component-watch: export TARGET := clojure
|
||||
test-component-watch: export COMPONENT_TEST := true
|
||||
test-component-watch: export BABEL_ENV := test
|
||||
test-component-watch: export JEST_USE_SILENT_REPORTER := false
|
||||
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
@scripts/check-metro-shadow-process.sh
|
||||
component-test-watch: export TARGET := clojure
|
||||
component-test-watch: export COMPONENT_TEST := true
|
||||
component-test-watch: export BABEL_ENV := test
|
||||
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
@@scripts/check-metro-shadow-process.sh
|
||||
rm -rf ./component-spec
|
||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
|
||||
yarn install
|
||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js' -e cljs
|
||||
|
||||
test-component: export TARGET := clojure
|
||||
test-component: export COMPONENT_TEST := true
|
||||
test-component: export BABEL_ENV := test
|
||||
test-component: export JEST_USE_SILENT_REPORTER := false
|
||||
test-component: ##@test Run component tests once in NodeJS
|
||||
component-test: export TARGET := clojure
|
||||
component-test: export COMPONENT_TEST := true
|
||||
component-test: export BABEL_ENV := test
|
||||
component-test: ##@test Run component tests once in NodeJS
|
||||
@scripts/check-metro-shadow-process.sh
|
||||
rm -rf ./component-spec
|
||||
yarn install
|
||||
yarn shadow-cljs compile component-test && \
|
||||
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)
|
||||
jest --config=test/jest/jest.config.js
|
||||
|
||||
#--------------
|
||||
# Other
|
||||
@@ -427,48 +390,25 @@ geth-connect: ##@other Connect to Geth on the device
|
||||
build/bin/geth attach http://localhost:8545
|
||||
|
||||
ios-clean: SHELL := /bin/sh
|
||||
ios-clean: ios-simulator-cache-clean
|
||||
ios-clean: ##@prepare Clean iOS build artifacts
|
||||
git clean -dxf -f target/ios
|
||||
|
||||
android-clean: SHELL := /bin/sh
|
||||
android-clean: export TARGET := gradle
|
||||
android-clean: ##@prepare Clean Gradle state
|
||||
git clean -dxf -f ./android/app/build; \
|
||||
rm -rf android/.gradle \
|
||||
rm -rf android/build \
|
||||
rm -rf ~/.gradle
|
||||
[[ -d android/.gradle ]] && cd android && ./gradlew clean
|
||||
|
||||
|
||||
android-ports: export FLOWSTORM_PORT ?= 7722
|
||||
android-ports: export TARGET := android-sdk
|
||||
android-ports: export RCT_METRO_PORT ?= 8081
|
||||
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:$(RE_FRISK_PORT) tcp:$(RE_FRISK_PORT) && \
|
||||
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
|
||||
adb reverse tcp:4567 tcp:4567 && \
|
||||
adb forward tcp:5561 tcp:5561
|
||||
|
||||
android-devices: export TARGET := android-sdk
|
||||
android-devices: ##@other Invoke 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: ##@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 :'
|
||||
@@ -482,10 +422,6 @@ _list: SHELL := /bin/sh
|
||||
_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 '^$@$$'
|
||||
|
||||
patch-file: export TARGET := default
|
||||
patch-file: ##@other Generates patch file for npm deps
|
||||
@scripts/patch-npm-lib.sh
|
||||
|
||||
#--------------
|
||||
# REPLs
|
||||
#--------------
|
||||
@@ -495,18 +431,3 @@ repl-clojure: ##@repl Start Clojure repl for mobile App
|
||||
yarn shadow-cljs cljs-repl mobile
|
||||
|
||||
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).
|
||||
|
||||
- **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**
|
||||
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**
|
||||
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!
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -1,75 +1,128 @@
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: "org.jetbrains.kotlin.android"
|
||||
apply plugin: "com.facebook.react"
|
||||
|
||||
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
import com.sun.org.apache.xalan.internal.xsltc.compiler.Copy
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant:
|
||||
* - bundlePrJsAndAssets
|
||||
* - bundleDebugJsAndAssets
|
||||
* - bundleReleaseJsAndAssets
|
||||
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||
* bundle directly from the development server. Below you can see all the possible configurations
|
||||
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||
* `apply from: "../../node_modules/react-native/react.gradle"` line.
|
||||
*
|
||||
* project.ext.react = [
|
||||
* // the name of the generated asset file containing your JS bundle
|
||||
* bundleAssetName: "index.android.bundle",
|
||||
*
|
||||
* // the entry file for bundle generation
|
||||
* entryFile: "index.js",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
* bundleInDebug: false,
|
||||
*
|
||||
* // whether to bundle JS and assets in release mode
|
||||
* bundleInRelease: true,
|
||||
*
|
||||
* // whether to bundle JS and assets in another build variant (if configured).
|
||||
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'bundleIn${productFlavor}${buildType}'
|
||||
* // 'bundleIn${buildType}'
|
||||
* // bundleInFreeDebug: true,
|
||||
* // bundleInPaidRelease: true,
|
||||
* // bundleInBeta: true,
|
||||
*
|
||||
* // whether to disable dev mode in custom build variants (by default only disabled in release)
|
||||
* // for example: to disable dev mode in the staging build type (if configured)
|
||||
* devDisabledInStaging: true,
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'devDisabledIn${productFlavor}${buildType}'
|
||||
* // 'devDisabledIn${buildType}'
|
||||
*
|
||||
* // the root of your project, i.e. where "package.json" lives
|
||||
* root: "../../",
|
||||
*
|
||||
* // where to put the JS bundle asset in debug mode
|
||||
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||
*
|
||||
* // where to put the JS bundle asset in release mode
|
||||
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in debug mode
|
||||
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in release mode
|
||||
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||
*
|
||||
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||
* // for example, you might want to remove it from here.
|
||||
* inputExcludes: ["android/**", "ios/**"],
|
||||
*
|
||||
* // override which node gets called and with what additional arguments
|
||||
* nodeExecutableAndArgs: ["node", "--max-old-space-size=8192"],
|
||||
*
|
||||
* // supply additional arguments to the packager
|
||||
* extraPackagerArgs: []
|
||||
* ]
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the configuration block to customize your React Native Android app.
|
||||
* By default you don't need to apply any configuration, just uncomment the lines you need.
|
||||
Enabling Hermes on x86 devices is crashing the app after a few reloads,
|
||||
this flag can be used to disable Hermes while building app.
|
||||
https://github.com/status-im/status-mobile/issues/14031
|
||||
*/
|
||||
react {
|
||||
/* Folders */
|
||||
// The root of your project, i.e. where "package.json" lives. Default is '..'
|
||||
// root = file("../")
|
||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
|
||||
// reactNativeDir = file("../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
|
||||
// cliFile = file("../node_modules/react-native/cli.js")
|
||||
|
||||
/* Variants */
|
||||
// The list of variants to that are debuggable. For those we're going to
|
||||
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
|
||||
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
|
||||
// debuggableVariants = ["liteDebug", "prodDebug"]
|
||||
def disableHermes = System.getenv('DISABLE_HERMES') == 'true'
|
||||
|
||||
/* Bundling */
|
||||
// A list containing the node command and its flags. Default is just 'node'.
|
||||
nodeExecutableAndArgs = ["node", "--max-old-space-size=16384" ]
|
||||
//
|
||||
// The command to run when bundling. By default is 'bundle'
|
||||
// bundleCommand = "ram-bundle"
|
||||
//
|
||||
// The path to the CLI configuration file. Default is empty.
|
||||
// bundleConfig = file(../rn-cli.config.js)
|
||||
//
|
||||
// The name of the generated asset file containing your JS bundle
|
||||
// bundleAssetName = "MyApplication.android.bundle"
|
||||
//
|
||||
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
|
||||
// entryFile = file("../js/MyApplication.android.js")
|
||||
//
|
||||
// A list of extra flags to pass to the 'bundle' commands.
|
||||
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
|
||||
// extraPackagerArgs = []
|
||||
project.ext.react = [
|
||||
nodeExecutableAndArgs: ["node", "--max-old-space-size=16384"],
|
||||
entryFile: "index.js",
|
||||
/* NOTE: Hermes engine is required for Android 64-bit builds running on 64 devices,
|
||||
* to guard against a hang in the UI thread after invoking status-go.
|
||||
* Also a clean and rebuild is required when changing this. */
|
||||
enableHermes: !disableHermes,
|
||||
/* Disable 'The first definition was here.' warnings */
|
||||
hermesFlagsRelease: ["-w"],
|
||||
/* FIXME: Workaround for crash caused by missing libhermes-executor-release.so.
|
||||
* https://github.com/facebook/react-native/issues/32928 */
|
||||
deleteDebugFilesForVariant: { false },
|
||||
enableVmCleanup: false,
|
||||
bundleInPr: true,
|
||||
inputExcludes: ["android/**", "ios/**", "react-native/**", "src/**", "test/**"]
|
||||
]
|
||||
|
||||
/* Hermes Commands */
|
||||
// The hermes compiler command to run. By default it is 'hermesc'
|
||||
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
|
||||
//
|
||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
|
||||
// hermesFlags = ["-O", "-output-source-map"]
|
||||
}
|
||||
// NOTE: Uncomment if building RN from a fork
|
||||
// configurations.all {
|
||||
// exclude group: 'com.facebook.react', module: 'react-native'
|
||||
// }
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
|
||||
/**
|
||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
||||
* Run Proguard to shrink the Java bytecode in release builds.
|
||||
*/
|
||||
def enableProguardInReleaseBuilds = true
|
||||
def enableProguardInReleaseBuilds = false
|
||||
|
||||
/**
|
||||
* The preferred build flavor of JavaScriptCore (JSC)
|
||||
* The preferred build flavor of JavaScriptCore.
|
||||
*
|
||||
* For example, to use the international variant, you can use:
|
||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
||||
*
|
||||
* The international variant includes ICU i18n library and necessary data
|
||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
||||
* give correct results when using with locales other than en-US. Note that
|
||||
* give correct results when using with locales other than en-US. Note that
|
||||
* this variant is about 6MiB larger per architecture than default.
|
||||
*/
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
@@ -81,7 +134,15 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||
* and the benefits of using Hermes will therefore be sharply reduced.
|
||||
*/
|
||||
def enableHermes = hermesEnabled.toBoolean();
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for.
|
||||
*/
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
def getCommitHash = { ->
|
||||
if (project.hasProperty("commitHash")) {
|
||||
@@ -137,31 +198,13 @@ def getEnvOrConfig = { varName ->
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
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"
|
||||
}
|
||||
}
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
namespace "im.status.ethereum"
|
||||
defaultConfig {
|
||||
applicationId "im.status.ethereum"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
@@ -177,8 +220,70 @@ android {
|
||||
abiFilters getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||
}
|
||||
}
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-21",
|
||||
"APP_STL=c++_shared",
|
||||
"NDK_TOOLCHAIN_VERSION=clang",
|
||||
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||
"PROJECT_BUILD_DIR=$buildDir",
|
||||
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
|
||||
"NODE_MODULES_DIR=$rootDir/../node_modules"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "rndiffapp_appmodules"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "$projectDir/src/main/jni/Android.mk"
|
||||
}
|
||||
}
|
||||
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
|
||||
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
|
||||
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
afterEvaluate {
|
||||
// If you wish to add a custom TurboModule or component locally,
|
||||
// you should uncomment this line.
|
||||
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||
|
||||
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||
reactNativeArchitectures().each { architecture ->
|
||||
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||
dependsOn("preDebugBuild")
|
||||
}
|
||||
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||
dependsOn("preReleaseBuild")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Arbitrary project metadata
|
||||
* https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
|
||||
@@ -210,12 +315,16 @@ android {
|
||||
doNotStrip '*/mips/*.so'
|
||||
doNotStrip '*/mips64/*.so'
|
||||
}
|
||||
dexOptions {
|
||||
jumboMode true
|
||||
javaMaxHeapSize "8g"
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
||||
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||
universalApk getEnvOrConfig('ORG_GRADLE_PROJECT_universalApk').toBoolean()
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
@@ -236,7 +345,6 @@ android {
|
||||
}
|
||||
release {
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
shrinkResources enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
signingConfig null
|
||||
}
|
||||
@@ -244,13 +352,12 @@ android {
|
||||
initWith release
|
||||
applicationIdSuffix ".pr"
|
||||
versionNameSuffix ".pr"
|
||||
debuggable false
|
||||
debuggable false
|
||||
matchingFallbacks = ["release"]
|
||||
// necessary to make react-native-config's code generation work
|
||||
resValue "string", "build_config_package", "im.status.ethereum"
|
||||
}
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
@@ -266,7 +373,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
aaptOptions {
|
||||
// disable PNG optimization as for some reason it cannot be trusted to provide deterministic output (see https://f-droid.org/en/docs/Reproducible_Builds/)
|
||||
cruncherEnabled = false
|
||||
@@ -278,33 +384,54 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// The version of react-native is set by the React Native Gradle Plugin
|
||||
implementation("com.facebook.react:react-android")
|
||||
implementation("androidx.core:core-splashscreen:1.0.0")
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
implementation 'com.facebook.soloader:soloader:0.10.3+'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
implementation "androidx.core:core-splashscreen:1.0.0"
|
||||
|
||||
if (enableHermes) {
|
||||
implementation("com.facebook.react:hermes-android")
|
||||
} else {
|
||||
// https://github.com/status-im/status-mobile/issues/18493
|
||||
// we don't use hermes for debug builds because it crashes too often
|
||||
implementation(jscFlavor)
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||
exclude group: 'com.facebook.fbjni' }
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
|
||||
// react-native-screens
|
||||
implementation("androidx.appcompat:appcompat:1.1.0-rc01")
|
||||
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.appcompat:appcompat:1.1.0-rc01'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||
|
||||
implementation 'androidx.multidex:multidex:2.0.1' // only needed if minSdkVersion is less than 21 (https://developer.android.com/studio/build/multidex)
|
||||
implementation project(':react-native-dialogs')
|
||||
implementation project(':react-native-blur')
|
||||
// Force using exact RN version instead of relying on gradle dependency resolution
|
||||
// https://docs.gradle.org/current/userguide/introduction_dependency_management.html#sec:dependency_resolution
|
||||
// NOTE: Uncomment if building RN from a fork
|
||||
//compile ("com.facebook.react:react-native:0.55.4") { force = true } // From node_modules
|
||||
implementation project(':react-native-status')
|
||||
implementation project(':react-native-status-keycard')
|
||||
implementation("com.github.status-im:function:0.0.1")
|
||||
implementation("com.facebook.fresco:fresco:2.5.0")
|
||||
implementation("com.facebook.fresco:animated-gif:2.5.0")
|
||||
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
|
||||
implementation("com.google.prefab:cli:2.0.0")
|
||||
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
|
||||
implementation 'com.github.status-im:function:0.0.1'
|
||||
implementation 'com.facebook.fresco:fresco:2.5.0'
|
||||
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||
implementation "com.squareup.okhttp3:okhttp-tls:4.9.2"
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// If new architecture is enabled, we let you build RN from source
|
||||
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||
// This will be applied to all the imported transtitive dependency.
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
.using(project(":ReactAndroid"))
|
||||
.because("On New Architecture we're building React Native from source")
|
||||
substitute(module("com.facebook.react:hermes-engine"))
|
||||
.using(project(":ReactAndroid:hermes-engine"))
|
||||
.because("On New Architecture we're building Hermes from source")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def getLocalNDKDir = { ->
|
||||
def rootDir = project.rootDir
|
||||
@@ -339,3 +466,11 @@ task hemroidBuild(type: Exec) {
|
||||
preBuild.dependsOn hemroidBuild
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
// To opt-in for the New Architecture, you can either:
|
||||
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||
// - Invoke gradle with `-newArchEnabled=true`
|
||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||
}
|
||||
|
||||
@@ -58,9 +58,6 @@
|
||||
-keep interface okhttp3.** { *; }
|
||||
-dontwarn okhttp3.**
|
||||
|
||||
# to fix : java.security.KeyStoreException: BKS not found
|
||||
-keep class org.bouncycastle.** { *; }
|
||||
|
||||
# okio
|
||||
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
@@ -78,13 +75,4 @@
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
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">
|
||||
|
||||
<!-- 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. -->
|
||||
<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>
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="auto">
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent>
|
||||
</queries>
|
||||
android:installLocation="auto"
|
||||
package="im.status.ethereum">
|
||||
|
||||
<!-- non-dangerous permissions -->
|
||||
<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.NFC"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
@@ -24,11 +17,11 @@
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
<application
|
||||
@@ -36,7 +29,6 @@
|
||||
android:allowBackup="false"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:theme="@style/Theme.AppSplash"
|
||||
android:name=".MainApplication"
|
||||
android:largeHeap="true"
|
||||
@@ -71,30 +63,8 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<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="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 android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@@ -105,13 +75,7 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
||||
<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>
|
||||
<service android:name="im.status.ethereum.pushnotifications.ForegroundService"></service>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
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.ReactRootView;
|
||||
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 com.facebook.react.ReactActivity;
|
||||
|
||||
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;
|
||||
|
||||
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.content.Context;
|
||||
import android.webkit.WebView;
|
||||
import im.status.ethereum.newarchitecture.MainApplicationReactNativeHost;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import com.facebook.react.PackageList;
|
||||
|
||||
import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
|
||||
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.config.ReactFeatureFlags;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
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;
|
||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||
|
||||
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 ReactNativeDialogsPackage());
|
||||
packages.add(new RNStatusKeycardPackage());
|
||||
packages.add(new PushNotificationPackage());
|
||||
packages.add(new BlurViewPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new ReanimatedJSIModulePackage();
|
||||
}
|
||||
};
|
||||
|
||||
private final ReactNativeHost mNewArchitectureNativeHost = new MainApplicationReactNativeHost(this);
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
return mNewArchitectureNativeHost;
|
||||
} else {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
|
||||
OkHttpClientProvider.setOkHttpClientFactory(new StatusOkHttpClientFactory());
|
||||
|
||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,77 @@
|
||||
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 = StatusPackage.getImageTLSCert();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package im.status.ethereum.newarchitecture;
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.facebook.react.bridge.JSIModuleProvider;
|
||||
import com.facebook.react.bridge.JSIModuleSpec;
|
||||
import com.facebook.react.bridge.JSIModuleType;
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||
import com.facebook.react.fabric.ReactNativeConfig;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import im.status.ethereum.BuildConfig;
|
||||
import im.status.ethereum.newarchitecture.components.MainComponentsRegistry;
|
||||
import im.status.ethereum.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
/**
|
||||
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
|
||||
* TurboModule delegates and the Fabric Renderer.
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||
public MainApplicationReactNativeHost(Application application) {
|
||||
super(application);
|
||||
}
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
|
||||
// packages.add(new TurboReactPackage() { ... });
|
||||
// If you have custom Fabric Components, their ViewManagers should also be loaded here
|
||||
// inside a ReactPackage.
|
||||
return packages;
|
||||
}
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
protected ReactPackageTurboModuleManagerDelegate.Builder
|
||||
getReactPackageTurboModuleManagerDelegateBuilder() {
|
||||
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
|
||||
// for the new architecture and to use TurboModules correctly.
|
||||
return new MainApplicationTurboModuleManagerDelegate.Builder();
|
||||
}
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new JSIModulePackage() {
|
||||
@Override
|
||||
public List<JSIModuleSpec> getJSIModules(
|
||||
final ReactApplicationContext reactApplicationContext,
|
||||
final JavaScriptContextHolder jsContext) {
|
||||
final List<JSIModuleSpec> specs = new ArrayList<>();
|
||||
// Here we provide a new JSIModuleSpec that will be responsible of providing the
|
||||
// custom Fabric Components.
|
||||
specs.add(
|
||||
new JSIModuleSpec() {
|
||||
@Override
|
||||
public JSIModuleType getJSIModuleType() {
|
||||
return JSIModuleType.UIManager;
|
||||
}
|
||||
@Override
|
||||
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
|
||||
final ComponentFactory componentFactory = new ComponentFactory();
|
||||
CoreComponentsRegistry.register(componentFactory);
|
||||
// Here we register a Components Registry.
|
||||
// The one that is generated with the template contains no components
|
||||
// and just provides you the one from React Native core.
|
||||
MainComponentsRegistry.register(componentFactory);
|
||||
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
|
||||
ViewManagerRegistry viewManagerRegistry =
|
||||
new ViewManagerRegistry(
|
||||
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
|
||||
return new FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
ReactNativeConfig.DEFAULT_CONFIG,
|
||||
viewManagerRegistry);
|
||||
}
|
||||
});
|
||||
return specs;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package im.status.ethereum.newarchitecture.components;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
/**
|
||||
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class MainComponentsRegistry {
|
||||
static {
|
||||
SoLoader.loadLibrary("fabricjni");
|
||||
}
|
||||
@DoNotStrip private final HybridData mHybridData;
|
||||
@DoNotStrip
|
||||
private native HybridData initHybrid(ComponentFactory componentFactory);
|
||||
@DoNotStrip
|
||||
private MainComponentsRegistry(ComponentFactory componentFactory) {
|
||||
mHybridData = initHybrid(componentFactory);
|
||||
}
|
||||
@DoNotStrip
|
||||
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
|
||||
return new MainComponentsRegistry(componentFactory);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package im.status.ethereum.newarchitecture.modules;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.util.List;
|
||||
/**
|
||||
* Class responsible to load the TurboModules. This class has native methods and needs a
|
||||
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||
* folder for you).
|
||||
*
|
||||
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||
* `newArchEnabled` property). Is ignored otherwise.
|
||||
*/
|
||||
public class MainApplicationTurboModuleManagerDelegate
|
||||
extends ReactPackageTurboModuleManagerDelegate {
|
||||
private static volatile boolean sIsSoLibraryLoaded;
|
||||
protected MainApplicationTurboModuleManagerDelegate(
|
||||
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
|
||||
super(reactApplicationContext, packages);
|
||||
}
|
||||
protected native HybridData initHybrid();
|
||||
native boolean canCreateTurboModule(String moduleName);
|
||||
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
|
||||
protected MainApplicationTurboModuleManagerDelegate build(
|
||||
ReactApplicationContext context, List<ReactPackage> packages) {
|
||||
return new MainApplicationTurboModuleManagerDelegate(context, packages);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected synchronized void maybeLoadOtherSoLibraries() {
|
||||
if (!sIsSoLibraryLoaded) {
|
||||
// If you change the name of your application .so file in the Android.mk file,
|
||||
// make sure you update the name here as well.
|
||||
SoLoader.loadLibrary("status-im_appmodules");
|
||||
sIsSoLibraryLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
THIS_DIR := $(call my-dir)
|
||||
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to include the following autogenerated makefile.
|
||||
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_PATH := $(THIS_DIR)
|
||||
# You can customize the name of your application .so file here.
|
||||
LOCAL_MODULE := rndiffapp_appmodules
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||
#
|
||||
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
|
||||
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
# Here you should add any native library you wish to depend on.
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libfabricjni \
|
||||
libfbjni \
|
||||
libfolly_runtime \
|
||||
libglog \
|
||||
libjsi \
|
||||
libreact_codegen_rncore \
|
||||
libreact_debug \
|
||||
libreact_nativemodule_core \
|
||||
libreact_render_componentregistry \
|
||||
libreact_render_core \
|
||||
libreact_render_debug \
|
||||
libreact_render_graphics \
|
||||
librrc_view \
|
||||
libruntimeexecutor \
|
||||
libturbomodulejsijni \
|
||||
libyoga
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
#include <rncore.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
// Here you can provide your own module provider for TurboModules coming from
|
||||
// either your application or from external libraries. The approach to follow
|
||||
// is similar to the following (for a library called `samplelibrary`:
|
||||
//
|
||||
// auto module = samplelibrary_ModuleProvider(moduleName, params);
|
||||
// if (module != nullptr) {
|
||||
// return module;
|
||||
// }
|
||||
// return rncore_ModuleProvider(moduleName, params);
|
||||
return rncore_ModuleProvider(moduleName, params);
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <ReactCommon/JavaTurboModule.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||
const std::string moduleName,
|
||||
const JavaTurboModule::InitParams ¶ms);
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainApplicationModuleProvider.h"
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
|
||||
MainApplicationTurboModuleManagerDelegate::initHybrid(
|
||||
jni::alias_ref<jhybridobject>) {
|
||||
return makeCxxInstance();
|
||||
}
|
||||
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod(
|
||||
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
|
||||
makeNativeMethod(
|
||||
"canCreateTurboModule",
|
||||
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
|
||||
});
|
||||
}
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<TurboModule>
|
||||
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) {
|
||||
return MainApplicationModuleProvider(name, params);
|
||||
}
|
||||
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
|
||||
std::string name) {
|
||||
return getTurboModule(name, nullptr) != nullptr ||
|
||||
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
class MainApplicationTurboModuleManagerDelegate
|
||||
: public jni::HybridClass<
|
||||
MainApplicationTurboModuleManagerDelegate,
|
||||
TurboModuleManagerDelegate> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/rndiffapp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
|
||||
static void registerNatives();
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||
std::shared_ptr<TurboModule> getTurboModule(
|
||||
const std::string name,
|
||||
const JavaTurboModule::InitParams ¶ms) override;
|
||||
/**
|
||||
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||
* created by instances of this class.
|
||||
*/
|
||||
bool canCreateTurboModule(std::string name);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "MainComponentsRegistry.h"
|
||||
#include <CoreComponentsRegistry.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
|
||||
std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
MainComponentsRegistry::sharedProviderRegistry() {
|
||||
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
|
||||
// Custom Fabric Components go here. You can register custom
|
||||
// components coming from your App or from 3rd party libraries here.
|
||||
//
|
||||
// providerRegistry->add(concreteComponentDescriptorProvider<
|
||||
// AocViewerComponentDescriptor>());
|
||||
return providerRegistry;
|
||||
}
|
||||
jni::local_ref<MainComponentsRegistry::jhybriddata>
|
||||
MainComponentsRegistry::initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate) {
|
||||
auto instance = makeCxxInstance(delegate);
|
||||
auto buildRegistryFunction =
|
||||
[](EventDispatcher::Weak const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
-> ComponentDescriptorRegistry::Shared {
|
||||
auto registry = MainComponentsRegistry::sharedProviderRegistry()
|
||||
->createComponentDescriptorRegistry(
|
||||
{eventDispatcher, contextContainer});
|
||||
auto mutableRegistry =
|
||||
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
|
||||
mutableRegistry->setFallbackComponentDescriptor(
|
||||
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
|
||||
ComponentDescriptorParameters{
|
||||
eventDispatcher, contextContainer, nullptr}));
|
||||
return registry;
|
||||
};
|
||||
delegate->buildRegistryFunction = buildRegistryFunction;
|
||||
return instance;
|
||||
}
|
||||
void MainComponentsRegistry::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
|
||||
});
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <ComponentFactory.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
class MainComponentsRegistry
|
||||
: public facebook::jni::HybridClass<MainComponentsRegistry> {
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
constexpr static auto kJavaDescriptor =
|
||||
"Lcom/rndiffapp/newarchitecture/components/MainComponentsRegistry;";
|
||||
static void registerNatives();
|
||||
MainComponentsRegistry(ComponentFactory *delegate);
|
||||
private:
|
||||
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||
sharedProviderRegistry();
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
ComponentFactory *delegate);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <fbjni/fbjni.h>
|
||||
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||
#include "MainComponentsRegistry.h"
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||
return facebook::jni::initialize(vm, [] {
|
||||
facebook::react::MainApplicationTurboModuleManagerDelegate::
|
||||
registerNatives();
|
||||
facebook::react::MainComponentsRegistry::registerNatives();
|
||||
});
|
||||
}
|
||||
|
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">
|
||||
<background android:drawable="@mipmap/ic_background"/>
|
||||
<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">
|
||||
<background android:drawable="@mipmap/ic_background"/>
|
||||
<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 |