Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
301b2bc6f7 |
@@ -0,0 +1,185 @@
|
|||||||
|
status-im.utils.build/warning-handler
|
||||||
|
status-im.utils.build/get-current-sha
|
||||||
|
status-im2.constants/spacing-char
|
||||||
|
status-im2.constants/arg-wrapping-char
|
||||||
|
status-im.ios.core/init
|
||||||
|
status-im.ui.components.camera/aspects
|
||||||
|
status-im.ui.components.camera/capture-targets
|
||||||
|
status-im.ui.components.camera/set-torch
|
||||||
|
status-im.ui.components.camera/request-access-ios
|
||||||
|
status-im.chat.models.message-content/stylings
|
||||||
|
status-im.chat.models.message-content/actions
|
||||||
|
status-im.chat.models.message-content/blank-string
|
||||||
|
status-im.chat.models.message-content/sorted-ranges
|
||||||
|
status-im.ethereum.mnemonic/words->passphrase
|
||||||
|
native-module.core/listener
|
||||||
|
native-module.core/multiaccount-reset
|
||||||
|
native-module.core/extract-group-membership-signatures
|
||||||
|
native-module.core/sign-group-membership
|
||||||
|
native-module.core/update-mailservers
|
||||||
|
status-im.ethereum.abi-spec/bytes-to-hex
|
||||||
|
status-im.android.core/init
|
||||||
|
status-im.chat.models.message/transport-keys
|
||||||
|
status-im.utils.datetime/week
|
||||||
|
status-im.utils.datetime/time-ago
|
||||||
|
status-im.utils.datetime/format-date
|
||||||
|
status-im.utils.datetime/get-ordinal-date
|
||||||
|
reagent.dom/render
|
||||||
|
reagent.dom/unmount-component-at-node
|
||||||
|
reagent.dom/dom-node
|
||||||
|
reagent.dom/force-update-all
|
||||||
|
status-im.multiaccounts.create.core/get-new-key-code
|
||||||
|
status-im.ethereum.decode/string
|
||||||
|
status-im.ui.screens.network.views/mainnet?
|
||||||
|
status-im.data-store.chats/event->string
|
||||||
|
status-im.mailserver.constants/seven-days
|
||||||
|
status-im.mailserver.constants/connection-timeout
|
||||||
|
status-im.hardwallet.card/install-applet
|
||||||
|
status-im.hardwallet.card/install-cash-applet
|
||||||
|
status-im.multiaccount.login.data-test/all-contacts
|
||||||
|
status-im.multiaccount.login.data-test/multiaccounts
|
||||||
|
status-im.multiaccount.login.data-test/get-chats
|
||||||
|
status-im.multiaccount.login.data-test/transport
|
||||||
|
status-im.multiaccount.login.data-test/topics
|
||||||
|
status-im.utils.utils/clear-timeout
|
||||||
|
status-im.utils.handlers/logged-in
|
||||||
|
status-im.multiaccounts.model/credentials
|
||||||
|
status-im.multiaccounts.login.core/contract-fleet?
|
||||||
|
status-im.multiaccounts.login.core/fetch-nodes
|
||||||
|
status-im2.config/rpc-networks-only?
|
||||||
|
status-im2.config/waku-enabled?
|
||||||
|
status-im.utils.pairing/has-paired-installations?
|
||||||
|
status-im.tribute-to-talk.core-test/user-cofx
|
||||||
|
mocks.js-dependencies/action-button
|
||||||
|
mocks.js-dependencies/camera
|
||||||
|
mocks.js-dependencies/dismiss-keyboard
|
||||||
|
mocks.js-dependencies/emoji-picker
|
||||||
|
mocks.js-dependencies/i18n
|
||||||
|
mocks.js-dependencies/qr-code
|
||||||
|
mocks.js-dependencies/svg
|
||||||
|
mocks.js-dependencies/icons
|
||||||
|
mocks.js-dependencies/webview
|
||||||
|
mocks.js-dependencies/desktop-linking
|
||||||
|
mocks.js-dependencies/desktop-shortcuts
|
||||||
|
mocks.js-dependencies/snoopy
|
||||||
|
mocks.js-dependencies/snoopy-filter
|
||||||
|
mocks.js-dependencies/snoopy-bars
|
||||||
|
mocks.js-dependencies/snoopy-buffer
|
||||||
|
mocks.js-dependencies/desktop-menu
|
||||||
|
mocks.js-dependencies/desktop-config
|
||||||
|
mocks.js-dependencies/react-native-navigation-twopane
|
||||||
|
mocks.js-dependencies/react-native-screens
|
||||||
|
mocks.js-dependencies/react-native-shake
|
||||||
|
mocks.js-dependencies/back-handler
|
||||||
|
mocks.js-dependencies/react
|
||||||
|
mocks.js-dependencies/react-navigation-native
|
||||||
|
mocks.js-dependencies/react-navigation-stack
|
||||||
|
mocks.js-dependencies/react-navigation-bottom-tabs
|
||||||
|
mocks.js-dependencies/react-native-haptic-feedback
|
||||||
|
mocks.js-dependencies/mock
|
||||||
|
quo.previews.main/init
|
||||||
|
status-im.chat.models.message-list-test/descending-range
|
||||||
|
status-im.chat.models.message-list-test/random-range
|
||||||
|
status-im.ethereum.eip165/supports?
|
||||||
|
status-im.utils.hex/valid-hex?
|
||||||
|
status-im.multiaccounts.core/chat-send?
|
||||||
|
status-im.hardwallet.simulated-keycard/install-cash-applet
|
||||||
|
status-im.hardwallet.simulated-keycard/sign-typed-data
|
||||||
|
status-im.utils.core/safe-read-message-content
|
||||||
|
status-im.ui.components.react/native-modules
|
||||||
|
status-im.ui.components.react/progress-bar
|
||||||
|
react-native.fs/move-file
|
||||||
|
react-native.fs/read-dir
|
||||||
|
react-native.fs/mkdir
|
||||||
|
react-native.fs/unlink
|
||||||
|
react-native.fs/file-exists?
|
||||||
|
status-im.ui.components.colors/white
|
||||||
|
status-im.ui.components.colors/black
|
||||||
|
status-im.ui.components.core/animated-header
|
||||||
|
status-im.ui.components.core/safe-area-provider
|
||||||
|
status-im.ui.components.core/safe-area-consumer
|
||||||
|
status-im.ui.components.core/safe-area-view
|
||||||
|
status-im.utils.universal-links.core/open!
|
||||||
|
status-im.transport.filters.core-test/member-2
|
||||||
|
status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
|
||||||
|
status-im.ethereum.ens/ttl
|
||||||
|
status-im.ethereum.ens/addr-hash
|
||||||
|
status-im.ethereum.ens/name-hash
|
||||||
|
status-im.ethereum.ens/ABI-hash
|
||||||
|
status-im.ethereum.ens/pubkey-hash
|
||||||
|
status-im.network.core/get-network
|
||||||
|
status-im2.constants/desktop-content-types
|
||||||
|
status-im2.constants/blocks-per-hour
|
||||||
|
status-im2.constants/one-earth-day
|
||||||
|
status-im2.constants/left-pane-min-width
|
||||||
|
status-im2.constants/system
|
||||||
|
status-im2.constants/contact-discovery
|
||||||
|
status-im2.constants/send-transaction-failed-parse-response
|
||||||
|
status-im2.constants/send-transaction-failed-parse-params
|
||||||
|
status-im2.constants/send-transaction-no-account-selected
|
||||||
|
status-im2.constants/send-transaction-invalid-tx-sender
|
||||||
|
status-im2.constants/web3-get-logs
|
||||||
|
status-im2.constants/web3-transaction-receipt
|
||||||
|
status-im2.constants/web3-new-filter
|
||||||
|
status-im2.constants/web3-new-pending-transaction-filter
|
||||||
|
status-im2.constants/web3-new-block-filter
|
||||||
|
status-im2.constants/web3-uninstall-filter
|
||||||
|
status-im2.constants/web3-get-filter-changes
|
||||||
|
status-im2.constants/web3-shh-post
|
||||||
|
status-im2.constants/web3-shh-new-identity
|
||||||
|
status-im2.constants/web3-shh-has-identity
|
||||||
|
status-im2.constants/web3-shh-new-group
|
||||||
|
status-im2.constants/web3-shh-add-to-group
|
||||||
|
status-im2.constants/web3-shh-new-filter
|
||||||
|
status-im2.constants/web3-shh-uninstall-filter
|
||||||
|
status-im2.constants/web3-shh-get-filter-changes
|
||||||
|
status-im2.constants/web3-shh-get-messages
|
||||||
|
status-im2.constants/status-create-address
|
||||||
|
status-im2.constants/event-transfer-hash
|
||||||
|
status-im2.constants/regx-rtl-characters
|
||||||
|
status-im2.constants/desktop-msg-chars-hard-limit
|
||||||
|
status-im2.constants/debug-metrics
|
||||||
|
status-im2.constants/scan-qr-code
|
||||||
|
status-im2.constants/ipfs-proto-code
|
||||||
|
status-im2.constants/swarm-proto-code
|
||||||
|
status-im.multiaccounts.update.publisher/publish-update!
|
||||||
|
status-im.utils.async/task-queue
|
||||||
|
status-im.utils.async/async-periodic-run!
|
||||||
|
status-im.desktop.core/app-root
|
||||||
|
status-im.desktop.core/init
|
||||||
|
status-im.chat.models-test/test-db
|
||||||
|
status-im.ui.components.spacing/padding-vertical
|
||||||
|
status-im.utils.money/percent-change
|
||||||
|
utils.debounce/clear-all
|
||||||
|
status-im.transport.db/create-chat
|
||||||
|
status-im.utils.priority-map/priority-map
|
||||||
|
status-im.utils.priority-map/priority-map-by
|
||||||
|
status-im.utils.priority-map/priority-map-keyfn
|
||||||
|
status-im.utils.priority-map/empty-message-map
|
||||||
|
status-im.wallet.choose-recipient.core/use-default-eth-gas
|
||||||
|
status-im.ui.components.animation/decay
|
||||||
|
status-im.ui.components.animation/remove-all-listeners
|
||||||
|
status-im.ui.components.animation/stop-animation
|
||||||
|
status-im.ui.components.animation/animated
|
||||||
|
status-im.ui.components.animation/add
|
||||||
|
status-im.ui.components.animation/subtract
|
||||||
|
status-im.ui.components.animation/get-layout
|
||||||
|
status-im.wallet.transactions-test/uri-query-data
|
||||||
|
status-im.utils.name/shortened-name
|
||||||
|
status-im.ui.components.button.haptic/trigger
|
||||||
|
status-im.contact.db/filter-dapps
|
||||||
|
status-im.contact.db/filter-group-contacts
|
||||||
|
status-im.contact.db/legacy-pending?
|
||||||
|
status-im.utils.transducers-test/preview-call-1
|
||||||
|
status-im.utils.transducers-test/preview-call-2
|
||||||
|
status-im.utils.types/to-string
|
||||||
|
status-im.chat.db/datemark?
|
||||||
|
status-im.chat.db/gap?
|
||||||
|
status-im.chat.db/map->sorted-seq
|
||||||
|
status-im.utils.snoopy/status-module-filter
|
||||||
|
status-im.utils.snoopy/websocket-filter
|
||||||
|
status-im.utils.snoopy/touches-filter
|
||||||
|
status-im.utils.snoopy/native-animation-filter
|
||||||
|
status-im.utils.snoopy/keyboard-observer-filter
|
||||||
|
status-im.utils.multihash/hex
|
||||||
|
status-im.utils.multihash/decode-array
|
||||||
@@ -1,84 +1,49 @@
|
|||||||
{:config-paths ["status-im"]
|
{:config-paths ["status-im"]
|
||||||
:output {:exclude-files ["src/user.cljs" "src/dev/user.cljs"]}
|
:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||||
:lint-as {legacy.status-im.utils.views/defview clojure.core/defn
|
status-im.utils.views/letsubs clojure.core/let
|
||||||
legacy.status-im.utils.views/letsubs clojure.core/let
|
reagent.core/with-let clojure.core/let
|
||||||
reagent.core/with-let clojure.core/let
|
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||||
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||||
utils.re-frame/defn clojure.core/defn
|
quo.react/with-deps-check clojure.core/fn
|
||||||
quo.react/with-deps-check clojure.core/fn
|
quo.previews.preview/list-comp clojure.core/for
|
||||||
quo.previews.preview/list-comp clojure.core/for
|
status-im.utils.styles/def clojure.core/def
|
||||||
legacy.status-im.utils.styles/def clojure.core/def
|
status-im.utils.styles/defn clojure.core/defn
|
||||||
legacy.status-im.utils.styles/defn clojure.core/defn
|
test-helpers.unit/deftest-sub clojure.core/defn
|
||||||
test-helpers.unit/deftest-sub clojure.core/defn
|
taoensso.tufte/defnp clojure.core/defn}
|
||||||
test-helpers.unit/deftest-event clojure.core/defn
|
:linters {:case-duplicate-test {:level :error}
|
||||||
|
|
||||||
taoensso.tufte/defnp clojure.core/defn}
|
|
||||||
:linters {:clojure-lsp/unused-public-var {:exclude-when-defined-by #{utils.re-frame/defn}
|
|
||||||
:exclude #{
|
|
||||||
;; even if we are not
|
|
||||||
;; using color now, we
|
|
||||||
;; will need it later
|
|
||||||
quo.foundations.colors
|
|
||||||
|
|
||||||
;; same for funcs from
|
|
||||||
;; native-module
|
|
||||||
native-module.core
|
|
||||||
|
|
||||||
;; some funcs used
|
|
||||||
;; temporarily during
|
|
||||||
;; development
|
|
||||||
test-helpers.component
|
|
||||||
test-helpers.unit
|
|
||||||
|
|
||||||
;; not sure if unused
|
|
||||||
;; functions here should
|
|
||||||
;; be removed:
|
|
||||||
keycard.keycard
|
|
||||||
react-native.fs}}
|
|
||||||
:case-duplicate-test {:level :error}
|
|
||||||
:case-quoted-test {:level :error}
|
:case-quoted-test {:level :error}
|
||||||
:case-symbol-test {:level :error}
|
:case-symbol-test {:level :error}
|
||||||
:clj-kondo-config {:level :error}
|
:clj-kondo-config {:level :error}
|
||||||
:cond-else {:level :error}
|
:cond-else {:level :error}
|
||||||
:condition-always-true {:level :error}
|
|
||||||
:conflicting-alias {:level :error}
|
|
||||||
:consistent-alias {:level :error
|
:consistent-alias {:level :error
|
||||||
:aliases {clojure.set set
|
:aliases {clojure.set set
|
||||||
clojure.string string
|
clojure.string string
|
||||||
clojure.walk walk
|
clojure.walk walk
|
||||||
malli.core malli
|
malli.core malli
|
||||||
malli.dev.pretty malli.pretty
|
malli.dev.pretty malli.pretty
|
||||||
malli.dev.virhe malli.virhe
|
malli.dev.virhe malli.virhe
|
||||||
malli.error malli.error
|
malli.error malli.error
|
||||||
malli.generator malli.generator
|
malli.generator malli.generator
|
||||||
malli.transform malli.transform
|
malli.transform malli.transform
|
||||||
malli.util malli.util
|
malli.util malli.util
|
||||||
promesa.core promesa
|
schema.core schema
|
||||||
schema.core schema
|
taoensso.timbre log}}
|
||||||
status-im.feature-flags ff
|
|
||||||
taoensso.timbre log}}
|
|
||||||
:deprecated-namespace {:level :warning}
|
:deprecated-namespace {:level :warning}
|
||||||
:docstring-blank {:level :error}
|
:docstring-blank {:level :error}
|
||||||
:equals-true {:level :error}
|
:equals-true {:level :error}
|
||||||
:inline-def {:level :error}
|
:inline-def {:level :error}
|
||||||
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
|
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||||
utils.re-frame/defn
|
|
||||||
utils.re-frame/merge]}
|
|
||||||
:loop-without-recur {:level :error}
|
:loop-without-recur {:level :error}
|
||||||
:minus-one {:level :error}
|
:minus-one {:level :error}
|
||||||
:misplaced-docstring {:level :error}
|
:misplaced-docstring {:level :error}
|
||||||
:missing-body-in-when {:level :error}
|
:missing-body-in-when {:level :error}
|
||||||
:missing-clause-in-try {:level :error}
|
:missing-clause-in-try {:level :error}
|
||||||
:missing-else-branch {:level :error}
|
:missing-else-branch {:level :error}
|
||||||
:multiple-async-in-deftest {:level :error}
|
|
||||||
:not-empty? {:level :error}
|
:not-empty? {:level :error}
|
||||||
:plus-one {:level :error}
|
:plus-one {:level :error}
|
||||||
:redundant-do {:level :error}
|
:redundant-do {:level :error}
|
||||||
:redundant-let {:level :error}
|
:redundant-let {:level :error}
|
||||||
:refer-all {:level :error}
|
:refer-all {:level :error}
|
||||||
;; ignore error in config itself saying that `:shadowed-fn-param` is unknown
|
|
||||||
#_{:clj-kondo/ignore [:clj-kondo-config]}
|
|
||||||
:shadowed-fn-param {:level :error}
|
|
||||||
:shadowed-var {:level :error
|
:shadowed-var {:level :error
|
||||||
;; We temporarily use :include to define an
|
;; We temporarily use :include to define an
|
||||||
;; allowlist of core Clojure vars. In the
|
;; allowlist of core Clojure vars. In the
|
||||||
@@ -86,11 +51,9 @@
|
|||||||
;; vars, we should be able to delete this
|
;; vars, we should be able to delete this
|
||||||
;; option and lint all vars.
|
;; option and lint all vars.
|
||||||
:exclude [type name]}
|
:exclude [type name]}
|
||||||
:self-requiring-namespace {:level :error}
|
|
||||||
:single-operand-comparison {:level :error}
|
:single-operand-comparison {:level :error}
|
||||||
:syntax {:level :error}
|
:syntax {:level :error}
|
||||||
:unbound-destructuring-default {:level :error}
|
:unbound-destructuring-default {:level :error}
|
||||||
:underscore-in-namespace {:level :error}
|
|
||||||
:uninitialized-var {:level :error}
|
:uninitialized-var {:level :error}
|
||||||
:unknown-require-option {:level :error}
|
:unknown-require-option {:level :error}
|
||||||
:unreachable-code {:level :error}
|
:unreachable-code {:level :error}
|
||||||
@@ -99,8 +62,7 @@
|
|||||||
;; https://github.com/borkdude/clj-kondo/issues/867
|
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||||
number
|
number
|
||||||
legacy.status-im.test-helpers/restore-app-db
|
status-im.test-helpers/restore-app-db]}
|
||||||
(cljs.test/is [match-strict?])]}
|
|
||||||
:unresolved-var {:level :error}
|
:unresolved-var {:level :error}
|
||||||
:unsorted-required-namespaces {:level :error}
|
:unsorted-required-namespaces {:level :error}
|
||||||
:unused-alias {:level :warning}
|
:unused-alias {:level :warning}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{:lint-as {promesa.core/-> clojure.core/->
|
|
||||||
promesa.core/->> clojure.core/->>
|
|
||||||
promesa.core/as-> clojure.core/as->
|
|
||||||
promesa.core/let clojure.core/let
|
|
||||||
promesa.core/plet clojure.core/let
|
|
||||||
promesa.core/loop clojure.core/loop
|
|
||||||
promesa.core/recur clojure.core/recur
|
|
||||||
promesa.core/with-redefs clojure.core/with-redefs
|
|
||||||
promesa.core/doseq clojure.core/doseq}}
|
|
||||||
@@ -1,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
|
{:hooks {:analyze-call {utils.i18n/label utils.i18n/label}}
|
||||||
{:analyze-call
|
:linters {:status-im.linter/invalid-translation-keyword {:level :error}}}
|
||||||
{utils.i18n/label utils.i18n/label
|
|
||||||
test-helpers.component/get-all-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/get-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/query-all-by-translation-text utils.i18n/label
|
|
||||||
test-helpers.component/query-by-translation-text utils.i18n/label
|
|
||||||
|
|
||||||
cljs.test/deftest cljs.test/deftest}}
|
|
||||||
:linters {:status-im.linter/invalid-translation-keyword {:level :error}
|
|
||||||
:status-im.linter/inconsistent-test-name {:level :error}}}
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{:hooks {:analyze-call {taoensso.encore/defalias taoensso.encore/defalias}}}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
(ns taoensso.encore
|
|
||||||
(:require
|
|
||||||
[clj-kondo.hooks-api :as hooks]))
|
|
||||||
|
|
||||||
(defn defalias [{:keys [node]}]
|
|
||||||
(let [[sym-raw src-raw] (rest (:children node))
|
|
||||||
src (if src-raw src-raw sym-raw)
|
|
||||||
sym (if src-raw
|
|
||||||
sym-raw
|
|
||||||
(symbol (name (hooks/sexpr src))))]
|
|
||||||
{:node (with-meta
|
|
||||||
(hooks/list-node
|
|
||||||
[(hooks/token-node 'def)
|
|
||||||
(hooks/token-node (hooks/sexpr sym))
|
|
||||||
(hooks/token-node (hooks/sexpr src))])
|
|
||||||
(meta src))}))
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
DEV_BUILD=1
|
DEV_BUILD=1
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=info
|
LOG_LEVEL=info
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
@@ -24,6 +26,7 @@ APN_TOPIC=im.status.ethereum.pr
|
|||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
|
COLLECTIBLES_ENABLED=1
|
||||||
COMMANDS_ENABLED=1
|
COMMANDS_ENABLED=1
|
||||||
TWO_MINUTES_SYNCING=1
|
TWO_MINUTES_SYNCING=1
|
||||||
SWAP_ENABLED=1
|
SWAP_ENABLED=1
|
||||||
@@ -31,10 +34,3 @@ STICKERS_TEST_ENABLED=1
|
|||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
SHOW_NOT_IMPLEMENTED_FEATURES=0
|
|
||||||
ENABLE_ALERT_BANNER=0
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=goerli_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
FLEET=status.staging
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||||
@@ -21,8 +22,8 @@ KEYCARD_TEST_MENU=1
|
|||||||
QR_READ_TEST_MENU=1
|
QR_READ_TEST_MENU=1
|
||||||
ENABLE_ROOT_ALERT=0
|
ENABLE_ROOT_ALERT=0
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||||
VERIFY_ENS_CHAIN_ID=11155111
|
VERIFY_ENS_CHAIN_ID=5
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
COMMUNITIES_ENABLED=1
|
COMMUNITIES_ENABLED=1
|
||||||
@@ -32,13 +33,3 @@ TWO_MINUTES_SYNCING=1
|
|||||||
STICKERS_TEST_ENABLED=1
|
STICKERS_TEST_ENABLED=1
|
||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
SHOW_NOT_IMPLEMENTED_FEATURES=1
|
|
||||||
DELETE_MESSAGE_FOR_ME_UNDO_TIME_LIMIT=10000
|
|
||||||
DELETE_MESSAGE_UNDO_TIME_LIMIT=10000
|
|
||||||
ENABLE_ALERT_BANNER=0
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
MOBILE_DATA_SYNCING_TOGGLE_ENABLE=0
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
CACHED_WEBVIEWS_ENABLED=1
|
CACHED_WEBVIEWS_ENABLED=1
|
||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=goerli_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
@@ -20,8 +22,8 @@ KEYCARD_TEST_MENU=0
|
|||||||
ENABLE_ROOT_ALERT=1
|
ENABLE_ROOT_ALERT=1
|
||||||
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
||||||
APN_TOPIC=im.status.ethereum.pr
|
APN_TOPIC=im.status.ethereum.pr
|
||||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||||
VERIFY_ENS_CHAIN_ID=11155111
|
VERIFY_ENS_CHAIN_ID=5
|
||||||
TEST_STATEOFUS=1
|
TEST_STATEOFUS=1
|
||||||
BLANK_PREVIEW=0
|
BLANK_PREVIEW=0
|
||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
@@ -33,9 +35,3 @@ ENABLE_QUO_PREVIEW=1
|
|||||||
STICKERS_TEST_ENABLED=1
|
STICKERS_TEST_ENABLED=1
|
||||||
LOCAL_PAIRING_ENABLED=1
|
LOCAL_PAIRING_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||||
TEST_NETWORKS_ENABLED=1
|
|
||||||
ENABLE_ALERT_BANNER=1
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=0
|
|
||||||
SENTRY_ENVIRONMENT=ci-main
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
DEBUG_WEBVIEW=1
|
DEBUG_WEBVIEW=1
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=1
|
ETHEREUM_DEV_CLUSTER=1
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=info
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
PFS_ENCRYPTION_ENABLED=1
|
PFS_ENCRYPTION_ENABLED=1
|
||||||
@@ -20,9 +22,3 @@ COMMUNITIES_ENABLED=1
|
|||||||
DATABASE_MANAGEMENT_ENABLED=1
|
DATABASE_MANAGEMENT_ENABLED=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||||
TEST_NETWORKS_ENABLED=0
|
|
||||||
ENABLE_ALERT_BANNER=1
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=1
|
|
||||||
SENTRY_ENABLED=1
|
|
||||||
SENTRY_ENVIRONMENT=ci-nightly
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
DEBUG_WEBVIEW=0
|
DEBUG_WEBVIEW=0
|
||||||
|
DEFAULT_NETWORK=mainnet_rpc
|
||||||
ETHEREUM_DEV_CLUSTER=0
|
ETHEREUM_DEV_CLUSTER=0
|
||||||
EXTENSIONS=0
|
EXTENSIONS=0
|
||||||
|
FLEET=status.prod
|
||||||
GROUP_CHATS_ENABLED=1
|
GROUP_CHATS_ENABLED=1
|
||||||
LOG_LEVEL=error
|
LOG_LEVEL=
|
||||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||||
MAINNET_WARNING_ENABLED=1
|
MAINNET_WARNING_ENABLED=1
|
||||||
PFS_ENCRYPTION_ENABLED=1
|
PFS_ENCRYPTION_ENABLED=1
|
||||||
@@ -16,10 +18,5 @@ PARTITIONED_TOPIC=0
|
|||||||
ENABLE_ROOT_ALERT=1
|
ENABLE_ROOT_ALERT=1
|
||||||
MAX_IMAGES_BATCH=1
|
MAX_IMAGES_BATCH=1
|
||||||
DELETE_MESSAGE_ENABLED=1
|
DELETE_MESSAGE_ENABLED=1
|
||||||
|
COLLECTIBLES_ENABLED=1
|
||||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||||
TEST_NETWORKS_ENABLED=0
|
|
||||||
STATUS_PROXY_STAGE_NAME=prod
|
|
||||||
FLAG_WALLET_CONNECT_ENABLED=1
|
|
||||||
API_LOGGING_ENABLED=0
|
|
||||||
SENTRY_ENABLED=1
|
|
||||||
SENTRY_ENVIRONMENT=production
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
extends: '@react-native',
|
extends: '@react-native-community',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: Bug Report
|
name: MVPBug Report
|
||||||
about: Bug Report
|
about: MVPBug Report
|
||||||
title: ''
|
title: ''
|
||||||
type: 'Bug'
|
labels: 'E:Mobile Bug MVP'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,26 +1,39 @@
|
|||||||
|
[comment]: # (Please replace ... with your information. Remove < and >)
|
||||||
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
||||||
|
|
||||||
|
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
|
||||||
|
|
||||||
|
*otherwise*
|
||||||
|
|
||||||
fixes #...
|
fixes #...
|
||||||
|
|
||||||
## Summary
|
### Summary
|
||||||
|
|
||||||
[comment]: # (Summarise the problem and how the pull request solves it)
|
[comment]: # (Summarise the problem and how the pull request solves it)
|
||||||
...
|
...
|
||||||
|
|
||||||
## Review notes
|
<!-- (Optional, remove if no changes to documentation) -->
|
||||||
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
|
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
|
||||||
|
|
||||||
## Testing notes
|
### Review notes
|
||||||
[comment]: # (Optional)
|
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
|
||||||
|
|
||||||
### Platforms
|
### Testing notes
|
||||||
[comment]: # (Optional. Specify which platforms should be tested)
|
<!-- (Optional) -->
|
||||||
|
|
||||||
|
#### Platforms
|
||||||
|
<!-- (Optional. Specify which platforms should be tested) -->
|
||||||
|
|
||||||
- Android
|
- Android
|
||||||
- iOS
|
- iOS
|
||||||
|
- macOS
|
||||||
|
- Linux
|
||||||
|
- Windows
|
||||||
|
|
||||||
### Areas that may be impacted
|
#### Areas that maybe impacted
|
||||||
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
|
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
|
||||||
|
|
||||||
#### Functional
|
##### Functional
|
||||||
|
|
||||||
- 1-1 chats
|
- 1-1 chats
|
||||||
- public chats
|
- public chats
|
||||||
@@ -35,36 +48,25 @@ fixes #...
|
|||||||
- fleet
|
- fleet
|
||||||
- bootnodes
|
- bootnodes
|
||||||
|
|
||||||
#### Non-functional
|
##### Non-functional
|
||||||
|
|
||||||
- battery performance
|
- battery performance
|
||||||
- CPU performance / speed of the app
|
- CPU performance / speed of the app
|
||||||
- network consumption
|
- network consumption
|
||||||
|
|
||||||
## Steps to test
|
### Steps to test
|
||||||
[comment]: # (Specify exact steps to test if there are such)
|
<!-- (Specify exact steps to test if there are such) -->
|
||||||
|
|
||||||
- Open Status
|
- Open Status
|
||||||
- ...
|
- ...
|
||||||
- Step 3, etc.
|
- Step 3, etc.
|
||||||
|
|
||||||
|
<!-- (PRs will only be accepted if squashed into single commit.) -->
|
||||||
|
|
||||||
[comment]: # (Can be ready or wip)
|
### Before and after screenshots comparison
|
||||||
status: ready
|
|
||||||
|
|
||||||
|
| Figma (if available) | iOS (if available) | Android (if available)
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
|
||||||
|
|
||||||
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
|
status: ready <!-- Can be ready or wip -->
|
||||||
|
|
||||||
- Specify potentially impacted user flows in _Areas that may be impacted*.
|
|
||||||
- Ensure that _Steps to test_ is filled in.
|
|
||||||
|
|
||||||
### Risk
|
|
||||||
|
|
||||||
Described potential risks and worst case scenarios.
|
|
||||||
|
|
||||||
Tick **one**:
|
|
||||||
- [ ] Low risk: 2 devs MUST perform testing as specified above and attach their results as comments to this PR **before** merging.
|
|
||||||
- [ ] High risk: QA team MUST perform additional testing in the specified affected areas **before** merging.
|
|
||||||
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ project.xcworkspace
|
|||||||
**/android/.project
|
**/android/.project
|
||||||
**/android/.settings/org.eclipse.buildship.core.prefs
|
**/android/.settings/org.eclipse.buildship.core.prefs
|
||||||
local.properties
|
local.properties
|
||||||
*.hprof
|
|
||||||
.cxx/
|
|
||||||
*.keystore
|
|
||||||
!debug.keystore
|
|
||||||
|
|
||||||
# Atom
|
# Atom
|
||||||
.tags*
|
.tags*
|
||||||
@@ -83,9 +79,6 @@ shim.js
|
|||||||
figwheel_server.log
|
figwheel_server.log
|
||||||
.nrepl-port
|
.nrepl-port
|
||||||
|
|
||||||
# FlowStorm (Clojure debugger)
|
|
||||||
repl-client-debug
|
|
||||||
|
|
||||||
# Lein
|
# Lein
|
||||||
#
|
#
|
||||||
.lein-failures
|
.lein-failures
|
||||||
@@ -130,8 +123,6 @@ fastlane/README.md
|
|||||||
# Clj
|
# Clj
|
||||||
|
|
||||||
.cpcache/
|
.cpcache/
|
||||||
src/user.cljs
|
|
||||||
src/dev/user.cljs
|
|
||||||
|
|
||||||
# emacs
|
# emacs
|
||||||
.dir-locals.el
|
.dir-locals.el
|
||||||
@@ -200,5 +191,6 @@ test/appium/tests/users.py
|
|||||||
## git hooks
|
## git hooks
|
||||||
lefthook.yml
|
lefthook.yml
|
||||||
|
|
||||||
## build time logs
|
## clj-kondo
|
||||||
/logs/*.log
|
/.clj-kondo/taoensso/*
|
||||||
|
/.clj-kondo/babashka/*
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
[submodule "legal-docs"]
|
|
||||||
path = legal-docs
|
|
||||||
url = https://github.com/status-im/status-software-legal-documents.git
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"include": [
|
"include": [
|
||||||
"target/test/legacy/status_im/**"
|
"target/test/status_im/**"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"target/test/legacy/status_im/test/**",
|
"target/test/status_im/test/**",
|
||||||
"target/test/legacy/status_im/ui/**"
|
"target/test/status_im/ui/**"
|
||||||
],
|
],
|
||||||
"report-dir": "./coverage-report",
|
"report-dir": "./coverage-report",
|
||||||
"all": true,
|
"all": true,
|
||||||
@@ -14,4 +14,4 @@
|
|||||||
"exclude-after-remap": false,
|
"exclude-after-remap": false,
|
||||||
"extension": [".js"],
|
"extension": [".js"],
|
||||||
"reporter": ["lcovonly"]
|
"reporter": ["lcovonly"]
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
/*
|
*
|
||||||
|
|
||||||
# Format top-level js files.
|
|
||||||
!*.js
|
!*.js
|
||||||
|
!*/
|
||||||
# Ignore all except src/js/**/*.js
|
*.clj-kondo
|
||||||
!/src/
|
*.shadow-cljs
|
||||||
/src/*
|
modules
|
||||||
!/src/js
|
result
|
||||||
!/src/js/**/*.js
|
target
|
||||||
|
component-spec
|
||||||
# Ignore all except translations/en.json
|
/app
|
||||||
!/translations/
|
|
||||||
/translations/*
|
|
||||||
!/translations/en.json
|
|
||||||
|
|||||||
@@ -6,8 +6,4 @@ module.exports = {
|
|||||||
tabWidth: 2,
|
tabWidth: 2,
|
||||||
trailingComma: 'all',
|
trailingComma: 'all',
|
||||||
useTabs: false,
|
useTabs: false,
|
||||||
|
|
||||||
// JSON sorting
|
|
||||||
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
|
|
||||||
plugins: ['prettier-plugin-sort-json'],
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ignore_dirs": [
|
"ignore_dirs": [
|
||||||
"android/build",
|
"android/build",
|
||||||
"target",
|
"target"
|
||||||
".clj-kondo",
|
|
||||||
".shadow-cljs"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,62 +1,54 @@
|
|||||||
;; -*- mode: clojure -*-
|
;; -*- mode: clojure -*-
|
||||||
;; vi: ft=clojure
|
;; vi: ft=clojure
|
||||||
{:width 105
|
{:width 105
|
||||||
:remove {:fn-force-nl #{:noarg1-body}}
|
:style [;; community style
|
||||||
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
||||||
|
:community
|
||||||
|
|
||||||
:style
|
;; no comma in map
|
||||||
[;; community style https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
|
:no-comma
|
||||||
:community
|
|
||||||
|
|
||||||
;; no comma in map
|
:custom-justify
|
||||||
:no-comma
|
|
||||||
|
|
||||||
:custom-justify
|
;; respect all newlines
|
||||||
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
|
||||||
|
:respect-nl
|
||||||
|
|
||||||
;; respect all newlines https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
|
;; respect blank line
|
||||||
:respect-nl
|
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
|
||||||
|
:respect-bl
|
||||||
;; respect blank line https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
|
|
||||||
:respect-bl
|
|
||||||
|
|
||||||
;; hang multiline left-hand-thing https://github.com/kkinnear/zprint/issues/273
|
|
||||||
:multi-lhs-hang]
|
|
||||||
|
|
||||||
|
;; hang multiline left-hand-thing
|
||||||
|
;; https://github.com/kkinnear/zprint/issues/273
|
||||||
|
:multi-lhs-hang]
|
||||||
:fn-map
|
:fn-map
|
||||||
{"reg-sub" :arg1-pair
|
{"reg-sub" :arg1-pair
|
||||||
"h/describe" :arg1-body
|
"h/describe" :arg1-body
|
||||||
"h/describe-skip" :arg1-body
|
"h/test" :arg1-body
|
||||||
"h/describe-only" :arg1-body
|
"global.describe" :arg1-body
|
||||||
"h/test" :arg1-body
|
"global.test" :arg1-body
|
||||||
"h/test-skip" :arg1-body
|
"list-comp" :binding
|
||||||
"h/test-only" :arg1-body
|
"defview" :arg1-body
|
||||||
"test/async" :arg1-body
|
"letsubs" :binding
|
||||||
"test/use-fixtures" :arg1-body
|
"with-let" "let"
|
||||||
"global.describe" :arg1-body
|
"reg-event-fx" :arg1-pair
|
||||||
"global.test" :arg1-body
|
"reg-fx" :arg1-pair
|
||||||
"list-comp" :binding
|
"testing" :arg1-body
|
||||||
"defview" :arg1-body
|
"deftest-sub" :arg1-body
|
||||||
"letsubs" :binding
|
"wait-for" :arg1-body
|
||||||
"with-let" "let"
|
"with-deps-check" :arg1-body
|
||||||
"reg-event-fx" :arg1-pair
|
"schema/=>" :arg1-body
|
||||||
"reg-fx" :arg1-pair
|
"->" [:noarg1-body
|
||||||
"testing" :arg1-body
|
{:list {:constant-pair? false :force-nl? false}
|
||||||
"deftest-sub" :arg1-body
|
:next-inner-restore [[:list :constant-pair?]]}]
|
||||||
"deftest-event" :arg1-body
|
"set!" "reset!"
|
||||||
"test-async" :arg1-body
|
"assoc-when" "assoc"
|
||||||
"wait-for" :arg1-body
|
"assoc-some" "assoc"
|
||||||
"with-deps-check" :arg1-body
|
"conj-when" "conj"
|
||||||
"schema/=>" :arg1-body
|
"conj-some" "conj"}
|
||||||
"->" [:noarg1-body
|
:remove {:fn-force-nl #{:noarg1-body}}
|
||||||
{:list {:constant-pair? false :force-nl? false}
|
|
||||||
:next-inner-restore [[:list :constant-pair?]]}]
|
|
||||||
"set!" "reset!"
|
|
||||||
"assoc-when" "assoc"
|
|
||||||
"assoc-some" "assoc"
|
|
||||||
"conj-when" "conj"
|
|
||||||
"conj-some" "conj"}
|
|
||||||
|
|
||||||
:style-map
|
:style-map
|
||||||
{:no-comma {:map {:comma? false}}
|
{:no-comma {:map {:comma? false}}
|
||||||
:custom-justify
|
:custom-justify
|
||||||
{:doc "Justify everything using pre-1.1.2 approach"
|
{:doc "Justify everything using pre-1.1.2 approach"
|
||||||
:binding {:justify? true :justify {:max-variance 1000}}
|
:binding {:justify? true :justify {:max-variance 1000}}
|
||||||
|
|||||||
@@ -32,19 +32,19 @@ ifndef BUILD_TAG
|
|||||||
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
export BUILD_TAG := $(shell git rev-parse --short HEAD)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# We don't want to use /run/user/$UID because it runs out of space too easily.
|
# We don't want to use /run/user/$UID because it runs out of space too easilly.
|
||||||
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
|
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
|
||||||
# This has to be specified for both the Node.JS server process and the Qt process.
|
# This has to be specified for both the Node.JS server process and the Qt process.
|
||||||
export REACT_SERVER_PORT ?= 5001
|
export REACT_SERVER_PORT ?= 5001
|
||||||
# Default metro port used by scripts/run-android.sh.
|
|
||||||
export RCT_METRO_PORT ?= 8081
|
|
||||||
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
|
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
|
||||||
export NODE_OPTIONS += --openssl-legacy-provider
|
export NODE_OPTIONS += --openssl-legacy-provider
|
||||||
# The path can be anything, but home is usually safest.
|
# The path can be anything, but home is usually safest.
|
||||||
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||||
|
|
||||||
|
# Our custom config is located in nix/nix.conf
|
||||||
|
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
|
||||||
# Location of symlinks to derivations that should not be garbage collected
|
# Location of symlinks to derivations that should not be garbage collected
|
||||||
export _NIX_GCROOTS = ./.nix-gcroots
|
export _NIX_GCROOTS = /nix/var/nix/gcroots/per-user/$(USER)/status-mobile
|
||||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||||
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
||||||
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
|
||||||
@@ -54,6 +54,12 @@ export _NIX_KEEP ?= TMPDIR,BUILD_ENV,\
|
|||||||
# Useful for Android release builds
|
# Useful for Android release builds
|
||||||
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
TMP_BUILD_NUMBER := $(shell ./scripts/version/gen_build_no.sh | cut -c1-10)
|
||||||
|
|
||||||
|
# MacOS root is read-only, read nix/README.md for details
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
export NIX_IGNORE_SYMLINK_STORE=1
|
||||||
|
endif
|
||||||
|
|
||||||
#----------------
|
#----------------
|
||||||
# Nix targets
|
# Nix targets
|
||||||
#----------------
|
#----------------
|
||||||
@@ -95,8 +101,6 @@ nix-purge: ##@nix Completely remove Nix setup, including /nix directory
|
|||||||
nix/scripts/purge.sh
|
nix/scripts/purge.sh
|
||||||
|
|
||||||
nix-update-gradle: export TARGET := gradle
|
nix-update-gradle: export TARGET := gradle
|
||||||
nix-update-gradle: export ORG_GRADLE_PROJECT_hermesEnabled := false
|
|
||||||
nix-update-gradle: export ORG_GRADLE_PROJECT_universalApk := false
|
|
||||||
nix-update-gradle: ##@nix Update maven nix expressions based on current gradle setup
|
nix-update-gradle: ##@nix Update maven nix expressions based on current gradle setup
|
||||||
nix/deps/gradle/generate.sh
|
nix/deps/gradle/generate.sh
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ _install-hooks: ##@prepare Create prepare-commit-msg git hook symlink
|
|||||||
|
|
||||||
# Remove directories and ignored files
|
# Remove directories and ignored files
|
||||||
clean: SHELL := /bin/sh
|
clean: SHELL := /bin/sh
|
||||||
clean: _fix-node-perms _tmpdir-rm ios-clean android-clean ##@prepare Remove all output folders
|
clean: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
|
||||||
git clean -dXf
|
git clean -dXf
|
||||||
|
|
||||||
# Remove directories, ignored and non-ignored files
|
# Remove directories, ignored and non-ignored files
|
||||||
@@ -156,12 +160,10 @@ pod-install: export TARGET := ios
|
|||||||
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
|
pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile.lock
|
||||||
cd ios && pod install; cd --
|
cd ios && pod install; cd --
|
||||||
|
|
||||||
FLEETS_FILE := ./resources/config/fleets.json
|
|
||||||
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
|
||||||
curl -s https://fleets.status.im/ \
|
curl -s https://fleets.status.im/ \
|
||||||
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
|
||||||
> $(FLEETS_FILE)
|
> resources/config/fleets.json
|
||||||
echo >> $(FLEETS_FILE)
|
|
||||||
|
|
||||||
$(KEYSTORE_PATH): export TARGET := keytool
|
$(KEYSTORE_PATH): export TARGET := keytool
|
||||||
$(KEYSTORE_PATH):
|
$(KEYSTORE_PATH):
|
||||||
@@ -196,10 +198,6 @@ xcode-clean: XCODE_HOME := $(HOME)/Library/Developer/Xcode
|
|||||||
xcode-clean: ##@prepare Clean XCode derived data and archives
|
xcode-clean: ##@prepare Clean XCode derived data and archives
|
||||||
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
|
rm -fr $(XCODE_HOME)/DerivedData/StatusIm-* $(XCODE_HOME)/Archives/*/StatusIm*
|
||||||
|
|
||||||
ios-simulator-cache-clean: SHELL := /bin/sh
|
|
||||||
ios-simulator-cache-clean: ##@prepare Clean iOS Simulator Caches
|
|
||||||
rm -rf ~/Library/Developer/CoreSimulator/Cache
|
|
||||||
|
|
||||||
#----------------
|
#----------------
|
||||||
# Release builds
|
# Release builds
|
||||||
#----------------
|
#----------------
|
||||||
@@ -214,14 +212,16 @@ build-fdroid: ##@build Build release for F-Droid
|
|||||||
|
|
||||||
build-android: export BUILD_ENV ?= prod
|
build-android: export BUILD_ENV ?= prod
|
||||||
build-android: export BUILD_TYPE ?= nightly
|
build-android: export BUILD_TYPE ?= nightly
|
||||||
build-android: export ORG_GRADLE_PROJECT_versionCode ?= $(TMP_BUILD_NUMBER)
|
build-android: export BUILD_NUMBER ?= $(TMP_BUILD_NUMBER)
|
||||||
|
build-android: export ANDROID_ABI_SPLIT ?= false
|
||||||
|
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||||
build-android: ##@build Build unsigned Android APK
|
build-android: ##@build Build unsigned Android APK
|
||||||
@scripts/build-android.sh
|
@scripts/build-android.sh
|
||||||
|
|
||||||
release-android: export TARGET := keytool
|
release-android: export TARGET := keytool
|
||||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||||
release-android: keystore build-android ##@build Build signed Android APK
|
release-android: keystore build-android ##@build Build signed Android APK
|
||||||
@scripts/sign-android.sh result/app-arm64-v8a-release-unsigned.apk
|
@scripts/sign-android.sh result/app-release-unsigned.apk
|
||||||
|
|
||||||
release-ios: export TARGET := ios
|
release-ios: export TARGET := ios
|
||||||
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||||
@@ -265,38 +265,39 @@ run-clojure: ##@run Watch for and build Clojure changes for mobile
|
|||||||
|
|
||||||
run-metro: export TARGET := clojure
|
run-metro: export TARGET := clojure
|
||||||
run-metro: ##@run Start Metro to build React Native changes
|
run-metro: ##@run Start Metro to build React Native changes
|
||||||
@scripts/run-metro.sh
|
@scripts/start-react-native.sh
|
||||||
|
|
||||||
export RE_FRISK_PORT ?= 4567
|
|
||||||
|
|
||||||
run-re-frisk: export TARGET := clojure
|
run-re-frisk: export TARGET := clojure
|
||||||
run-re-frisk: ##@run Start re-frisk server
|
run-re-frisk: ##@run Start re-frisk server
|
||||||
yarn shadow-cljs run re-frisk-remote.core/start ${RE_FRISK_PORT}
|
yarn shadow-cljs run re-frisk-remote.core/start
|
||||||
|
|
||||||
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
||||||
run-android: export TARGET := android
|
run-android: export TARGET := android
|
||||||
# Disabled for debug builds to avoid 'maximum call stack exceeded' errors.
|
# INFO: If it's empty (no devices attached, parsing issues, script error) - for Nix it's the same as not set.
|
||||||
# https://github.com/status-im/status-mobile/issues/18493
|
run-android: export ANDROID_ABI_INCLUDE ?= $(shell ./scripts/adb_devices_abis.sh)
|
||||||
run-android: export ORG_GRADLE_PROJECT_hermesEnabled := false
|
|
||||||
run-android: export ORG_GRADLE_PROJECT_universalApk := false
|
|
||||||
run-android: ##@run Build Android APK and start it on the device
|
run-android: ##@run Build Android APK and start it on the device
|
||||||
@scripts/run-android.sh
|
npx react-native run-android --appIdSuffix debug
|
||||||
|
|
||||||
SIMULATOR=iPhone 13
|
SIMULATOR=iPhone 13
|
||||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
|
||||||
run-ios: export TARGET := ios
|
run-ios: export TARGET := ios
|
||||||
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
|
||||||
run-ios: ##@run Build iOS app and start it in on the simulator
|
run-ios: ##@run Build iOS app and start it in a simulator/device
|
||||||
@scripts/run-ios.sh "${SIMULATOR}"
|
ifneq ("$(SIMULATOR)", "")
|
||||||
|
npx react-native run-ios --simulator="$(SIMULATOR)"
|
||||||
|
else
|
||||||
|
npx react-native run-ios
|
||||||
|
endif
|
||||||
|
|
||||||
show-ios-devices: ##@other shows connected ios device and its name
|
show-ios-devices: ##@other shows connected ios device and its name
|
||||||
xcrun xctrace list devices
|
xcrun xctrace list devices
|
||||||
|
|
||||||
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
|
|
||||||
run-ios-device: export TARGET := ios
|
run-ios-device: export TARGET := ios
|
||||||
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
|
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||||
run-ios-device: ##@run iOS app and start it on the first connected iPhone
|
run-ios-device: ##@run iOS app and start it on a connected device by its name
|
||||||
@scripts/run-ios-device.sh
|
ifndef DEVICE_NAME
|
||||||
|
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
|
||||||
|
endif
|
||||||
|
react-native run-ios --device "$(DEVICE_NAME)"
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# Tests
|
# Tests
|
||||||
@@ -304,7 +305,7 @@ run-ios-device: ##@run iOS app and start it on the first connected iPhone
|
|||||||
|
|
||||||
# Get all clojure files, including untracked, excluding removed
|
# Get all clojure files, including untracked, excluding removed
|
||||||
define find_all_clojure_files
|
define find_all_clojure_files
|
||||||
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -E '((\.clj-kondo\/status-im)|(src).*\.clj[sc]?$$)|((\.clj-kondo\/(status-im|config))|(src).*\.edn$$)|shadow-cljs\.edn')
|
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
lint: export TARGET := clojure
|
lint: export TARGET := clojure
|
||||||
@@ -318,7 +319,7 @@ lint: ##@test Run code style checks
|
|||||||
scripts/lint/translations.clj && \
|
scripts/lint/translations.clj && \
|
||||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||||
sh scripts/lint/trailing-newline.sh && \
|
sh scripts/lint/trailing-newline.sh && \
|
||||||
node_modules/.bin/prettier --check .
|
node_modules/.bin/prettier --write .
|
||||||
|
|
||||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||||
lint-fix: export TARGET := clojure
|
lint-fix: export TARGET := clojure
|
||||||
@@ -326,7 +327,7 @@ lint-fix: ##@test Run code style checks and fix issues
|
|||||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||||
clojure-lsp --ns-exclude-regex ".*/\.clj-kondo/.*|.*/src/status_im/core\.cljs|.*/src/test_helpers/component_tests_preload\.cljs$$" clean-ns && \
|
clojure-lsp --ns-exclude-regex ".*/src/status_im2/core\.cljs$$" clean-ns && \
|
||||||
sh scripts/lint/trailing-newline.sh --fix && \
|
sh scripts/lint/trailing-newline.sh --fix && \
|
||||||
node_modules/.bin/prettier --write .
|
node_modules/.bin/prettier --write .
|
||||||
|
|
||||||
@@ -334,88 +335,50 @@ shadow-server: export TARGET := clojure
|
|||||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||||
yarn shadow-cljs server
|
yarn shadow-cljs server
|
||||||
|
|
||||||
_test-clojure: export TARGET := clojure
|
test-watch: export TARGET := clojure
|
||||||
_test-clojure: export WATCH ?= false
|
test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||||
_test-clojure: status-go-library
|
yarn install
|
||||||
_test-clojure:
|
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
|
||||||
ifeq ($(WATCH), true)
|
|
||||||
yarn node-pre-gyp rebuild && \
|
test-watch-for-repl: export TARGET := clojure
|
||||||
yarn shadow-cljs compile mocks && \
|
test-watch-for-repl: ##@ Watch tests and support REPL connections
|
||||||
nodemon --exec "yarn shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
|
yarn install
|
||||||
else
|
rm -f target/test/test.js
|
||||||
yarn node-pre-gyp rebuild && \
|
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
||||||
|
'yarn shadow-cljs compile mocks && yarn shadow-cljs watch test --verbose' \
|
||||||
|
'until [ -f ./target/test/test.js ] ; do sleep 1 ; done ; node --require ./test-resources/override.js ./target/test/test.js --repl'
|
||||||
|
|
||||||
|
test: export TARGET := clojure
|
||||||
|
test: ##@test Run tests once in NodeJS
|
||||||
|
# Here we create the gyp bindings for nodejs
|
||||||
|
yarn install
|
||||||
yarn shadow-cljs compile mocks && \
|
yarn shadow-cljs compile mocks && \
|
||||||
yarn shadow-cljs compile test && \
|
yarn shadow-cljs compile test && \
|
||||||
node --require ./test-resources/override.js "$$SHADOW_OUTPUT_TO"
|
node --require ./test-resources/override.js target/test/test.js
|
||||||
endif
|
|
||||||
|
|
||||||
test: export SHADOW_OUTPUT_TO := target/test/test.js
|
android-test: jsbundle
|
||||||
test: export SHADOW_NS_REGEXP := .*-test$$
|
android-test: export TARGET := android
|
||||||
test: ##@test Run all Clojure tests
|
android-test:
|
||||||
test: _test-clojure
|
|
||||||
|
|
||||||
# Note: we need to override the :output-to and :ns-regexp options because
|
|
||||||
# shadow-cljs has a bug where it will not read from the env vars to expand the
|
|
||||||
# configuration when the shadow-cljs mobile target is already running.
|
|
||||||
test-watch-for-repl: export TARGET := default
|
|
||||||
test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js
|
|
||||||
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$
|
|
||||||
test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connections
|
|
||||||
rm -f "$$SHADOW_OUTPUT_TO" && \
|
|
||||||
yarn install && shadow-cljs compile mocks && \
|
|
||||||
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
|
||||||
"yarn shadow-cljs watch test --verbose --config-merge '{:output-to \"$(SHADOW_OUTPUT_TO)\" :ns-regexp \"$(SHADOW_NS_REGEXP)\"}'" \
|
|
||||||
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
|
|
||||||
|
|
||||||
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
|
|
||||||
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests\.contract-test).*-test$$
|
|
||||||
test-unit: ##@test Run unit tests
|
|
||||||
test-unit: _test-clojure
|
|
||||||
|
|
||||||
test-integration: export SHADOW_OUTPUT_TO := target/integration_test/test.js
|
|
||||||
test-integration: export SHADOW_NS_REGEXP := ^tests\.integration-test.*$$
|
|
||||||
test-integration: ##@test Run integration tests
|
|
||||||
test-integration: _test-clojure
|
|
||||||
|
|
||||||
test-contract: export SHADOW_OUTPUT_TO := target/contract_test/test.js
|
|
||||||
test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
|
|
||||||
test-contract: ##@test Run contract tests
|
|
||||||
test-contract: _test-clojure
|
|
||||||
|
|
||||||
test-android: jsbundle
|
|
||||||
test-android: export TARGET := android
|
|
||||||
test-android: ##@test Android Gradle test
|
|
||||||
cd android && ./gradlew test
|
cd android && ./gradlew test
|
||||||
|
|
||||||
test-component-watch: export TARGET := clojure
|
component-test-watch: export TARGET := clojure
|
||||||
test-component-watch: export COMPONENT_TEST := true
|
component-test-watch: export COMPONENT_TEST := true
|
||||||
test-component-watch: export BABEL_ENV := test
|
component-test-watch: export BABEL_ENV := test
|
||||||
test-component-watch: export JEST_USE_SILENT_REPORTER := false
|
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||||
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
|
@@scripts/check-metro-shadow-process.sh
|
||||||
@scripts/check-metro-shadow-process.sh
|
|
||||||
rm -rf ./component-spec
|
rm -rf ./component-spec
|
||||||
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
|
component-test: export TARGET := clojure
|
||||||
test-component: export COMPONENT_TEST := true
|
component-test: export COMPONENT_TEST := true
|
||||||
test-component: export BABEL_ENV := test
|
component-test: export BABEL_ENV := test
|
||||||
test-component: export JEST_USE_SILENT_REPORTER := false
|
component-test: ##@test Run component tests once in NodeJS
|
||||||
test-component: ##@test Run component tests once in NodeJS
|
|
||||||
@scripts/check-metro-shadow-process.sh
|
@scripts/check-metro-shadow-process.sh
|
||||||
rm -rf ./component-spec
|
rm -rf ./component-spec
|
||||||
|
yarn install
|
||||||
yarn shadow-cljs compile component-test && \
|
yarn shadow-cljs compile component-test && \
|
||||||
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
|
jest --config=test/jest/jest.config.js
|
||||||
|
|
||||||
# Reference: https://flow-storm.github.io/flow-storm-debugger/user_guide.html#_debugging_react_native_applications
|
|
||||||
run-flow-storm: export SHADOW_CLJS_BUILD_ID := :mobile
|
|
||||||
run-flow-storm: export TARGET := clojure
|
|
||||||
run-flow-storm: export GDK_DPI_SCALE := 1.0
|
|
||||||
run-flow-storm: ##@run Start FlowStorm debugger
|
|
||||||
clj -Sforce -Sdeps '{:deps {com.github.jpmonettas/flow-storm-dbg {:mvn/version "3.7.5"}}}' \
|
|
||||||
-X flow-storm.debugger.main/start-debugger \
|
|
||||||
:port 7888 \
|
|
||||||
:repl-type :shadow \
|
|
||||||
:build-id $(SHADOW_CLJS_BUILD_ID)
|
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# Other
|
# Other
|
||||||
@@ -427,48 +390,25 @@ geth-connect: ##@other Connect to Geth on the device
|
|||||||
build/bin/geth attach http://localhost:8545
|
build/bin/geth attach http://localhost:8545
|
||||||
|
|
||||||
ios-clean: SHELL := /bin/sh
|
ios-clean: SHELL := /bin/sh
|
||||||
ios-clean: ios-simulator-cache-clean
|
|
||||||
ios-clean: ##@prepare Clean iOS build artifacts
|
ios-clean: ##@prepare Clean iOS build artifacts
|
||||||
git clean -dxf -f target/ios
|
git clean -dxf -f target/ios
|
||||||
|
|
||||||
android-clean: SHELL := /bin/sh
|
android-clean: export TARGET := gradle
|
||||||
android-clean: ##@prepare Clean Gradle state
|
android-clean: ##@prepare Clean Gradle state
|
||||||
git clean -dxf -f ./android/app/build; \
|
git clean -dxf -f ./android/app/build; \
|
||||||
rm -rf android/.gradle \
|
[[ -d android/.gradle ]] && cd android && ./gradlew clean
|
||||||
rm -rf android/build \
|
|
||||||
rm -rf ~/.gradle
|
|
||||||
|
|
||||||
|
|
||||||
android-ports: export FLOWSTORM_PORT ?= 7722
|
|
||||||
android-ports: export TARGET := android-sdk
|
android-ports: export TARGET := android-sdk
|
||||||
android-ports: export RCT_METRO_PORT ?= 8081
|
|
||||||
android-ports: ##@other Add proxies to Android Device/Simulator
|
android-ports: ##@other Add proxies to Android Device/Simulator
|
||||||
adb reverse tcp:$(RCT_METRO_PORT) tcp:$(RCT_METRO_PORT) && \
|
adb reverse tcp:8081 tcp:8081 && \
|
||||||
adb reverse tcp:3449 tcp:3449 && \
|
adb reverse tcp:3449 tcp:3449 && \
|
||||||
adb reverse tcp:$(RE_FRISK_PORT) tcp:$(RE_FRISK_PORT) && \
|
adb reverse tcp:4567 tcp:4567 && \
|
||||||
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
|
|
||||||
adb forward tcp:5561 tcp:5561
|
adb forward tcp:5561 tcp:5561
|
||||||
|
|
||||||
android-devices: export TARGET := android-sdk
|
android-devices: export TARGET := android-sdk
|
||||||
android-devices: ##@other Invoke adb devices
|
android-devices: ##@other Invoke adb devices
|
||||||
adb devices
|
adb devices
|
||||||
|
|
||||||
android-pull-geth: export TARGET := android-sdk
|
|
||||||
android-pull-geth: export VERSION ?= debug
|
|
||||||
android-pull-geth:
|
|
||||||
adb pull "/storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log"
|
|
||||||
|
|
||||||
android-tail-geth: export TARGET := android-sdk
|
|
||||||
android-tail-geth: export VERSION ?= debug
|
|
||||||
android-tail-geth:
|
|
||||||
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
|
||||||
|
|
||||||
android-clean-geth: export TARGET := android-sdk
|
|
||||||
android-clean-geth: export VERSION ?= debug
|
|
||||||
android-clean-geth:
|
|
||||||
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
|
||||||
|
|
||||||
|
|
||||||
android-logcat: export TARGET := android-sdk
|
android-logcat: export TARGET := android-sdk
|
||||||
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
||||||
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
||||||
@@ -482,10 +422,6 @@ _list: SHELL := /bin/sh
|
|||||||
_list:
|
_list:
|
||||||
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
||||||
|
|
||||||
patch-file: export TARGET := default
|
|
||||||
patch-file: ##@other Generates patch file for npm deps
|
|
||||||
@scripts/patch-npm-lib.sh
|
|
||||||
|
|
||||||
#--------------
|
#--------------
|
||||||
# REPLs
|
# REPLs
|
||||||
#--------------
|
#--------------
|
||||||
@@ -495,18 +431,3 @@ repl-clojure: ##@repl Start Clojure repl for mobile App
|
|||||||
yarn shadow-cljs cljs-repl mobile
|
yarn shadow-cljs cljs-repl mobile
|
||||||
|
|
||||||
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
|
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
|
||||||
|
|
||||||
#--------------
|
|
||||||
# Dev Automation Flows
|
|
||||||
#--------------
|
|
||||||
|
|
||||||
auto-login: export TARGET := default
|
|
||||||
auto-login: ##@auto runs flow for login or onboarding app on simulator/emulator
|
|
||||||
maestro test "maestro/create-account-or-login.yaml"
|
|
||||||
|
|
||||||
auto-custom: export TARGET := default
|
|
||||||
auto-custom: ##@auto runs any custom maestro automation flow on simulator/emulator
|
|
||||||
ifndef FLOW
|
|
||||||
$(error Usage: make automate FLOW=your-maestro-flow-file.yaml)
|
|
||||||
endif
|
|
||||||
maestro test "$(FLOW)"
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ project dependencies, coding guidelines and testing procedures.
|
|||||||
Check out our [coding guidelines](doc/new-guidelines.md).
|
Check out our [coding guidelines](doc/new-guidelines.md).
|
||||||
|
|
||||||
- **Community Management**
|
- **Community Management**
|
||||||
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.app/manifesto)
|
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about)
|
||||||
|
|
||||||
- **Specification / Documentation**
|
- **Specification / Documentation**
|
||||||
John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
|
John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have.
|
||||||
@@ -53,10 +53,10 @@ Status is a visual interface to make permanent changes on the Blockchain, it han
|
|||||||
|
|
||||||
- **Evangelism**
|
- **Evangelism**
|
||||||
Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
|
Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
|
||||||
|
|
||||||
## Give me Binaries!
|
## Give me Binaries!
|
||||||
|
|
||||||
You can get our Beta builds for both Android and iOS on our [website](https://status.app), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](doc/starting-guide.md).
|
You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](https://status.im/technical/build_status/).
|
||||||
|
|
||||||
## Core Contributors
|
## Core Contributors
|
||||||
|
|
||||||
|
|||||||
@@ -1,75 +1,128 @@
|
|||||||
apply plugin: "com.android.application"
|
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"
|
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||||
|
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
import com.sun.org.apache.xalan.internal.xsltc.compiler.Copy
|
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.
|
Enabling Hermes on x86 devices is crashing the app after a few reloads,
|
||||||
* By default you don't need to apply any configuration, just uncomment the lines you need.
|
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 */
|
def disableHermes = System.getenv('DISABLE_HERMES') == 'true'
|
||||||
// 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"]
|
|
||||||
|
|
||||||
/* Bundling */
|
project.ext.react = [
|
||||||
// A list containing the node command and its flags. Default is just 'node'.
|
nodeExecutableAndArgs: ["node", "--max-old-space-size=16384"],
|
||||||
nodeExecutableAndArgs = ["node", "--max-old-space-size=16384" ]
|
entryFile: "index.js",
|
||||||
//
|
/* NOTE: Hermes engine is required for Android 64-bit builds running on 64 devices,
|
||||||
// The command to run when bundling. By default is 'bundle'
|
* to guard against a hang in the UI thread after invoking status-go.
|
||||||
// bundleCommand = "ram-bundle"
|
* Also a clean and rebuild is required when changing this. */
|
||||||
//
|
enableHermes: !disableHermes,
|
||||||
// The path to the CLI configuration file. Default is empty.
|
/* Disable 'The first definition was here.' warnings */
|
||||||
// bundleConfig = file(../rn-cli.config.js)
|
hermesFlagsRelease: ["-w"],
|
||||||
//
|
/* FIXME: Workaround for crash caused by missing libhermes-executor-release.so.
|
||||||
// The name of the generated asset file containing your JS bundle
|
* https://github.com/facebook/react-native/issues/32928 */
|
||||||
// bundleAssetName = "MyApplication.android.bundle"
|
deleteDebugFilesForVariant: { false },
|
||||||
//
|
enableVmCleanup: false,
|
||||||
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
|
bundleInPr: true,
|
||||||
// entryFile = file("../js/MyApplication.android.js")
|
inputExcludes: ["android/**", "ios/**", "react-native/**", "src/**", "test/**"]
|
||||||
//
|
]
|
||||||
// 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 = []
|
|
||||||
|
|
||||||
/* Hermes Commands */
|
// NOTE: Uncomment if building RN from a fork
|
||||||
// The hermes compiler command to run. By default it is 'hermesc'
|
// configurations.all {
|
||||||
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
|
// exclude group: 'com.facebook.react', module: 'react-native'
|
||||||
//
|
// }
|
||||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
|
|
||||||
// hermesFlags = ["-O", "-output-source-map"]
|
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:
|
* For example, to use the international variant, you can use:
|
||||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
||||||
*
|
*
|
||||||
* The international variant includes ICU i18n library and necessary data
|
* The international variant includes ICU i18n library and necessary data
|
||||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
* 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.
|
* this variant is about 6MiB larger per architecture than default.
|
||||||
*/
|
*/
|
||||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
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
|
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||||
* and the benefits of using Hermes will therefore be sharply reduced.
|
* 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 = { ->
|
def getCommitHash = { ->
|
||||||
if (project.hasProperty("commitHash")) {
|
if (project.hasProperty("commitHash")) {
|
||||||
@@ -137,31 +198,13 @@ def getEnvOrConfig = { varName ->
|
|||||||
android {
|
android {
|
||||||
ndkVersion rootProject.ext.ndkVersion
|
ndkVersion rootProject.ext.ndkVersion
|
||||||
|
|
||||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
compileSdk rootProject.ext.compileSdkVersion
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
// Disable default lint checks to remove redundant lintVitalReportRelease task
|
|
||||||
lintOptions {
|
|
||||||
checkReleaseBuilds false
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
// This version must match cmakeVersions inside nix/pkgs/android-sdk/compose.nix
|
|
||||||
version "3.22.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_17
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_17
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace "im.status.ethereum"
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "im.status.ethereum"
|
applicationId "im.status.ethereum"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
@@ -177,8 +220,70 @@ android {
|
|||||||
abiFilters getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
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
|
* Arbitrary project metadata
|
||||||
* https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
|
* https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html
|
||||||
@@ -210,12 +315,16 @@ android {
|
|||||||
doNotStrip '*/mips/*.so'
|
doNotStrip '*/mips/*.so'
|
||||||
doNotStrip '*/mips64/*.so'
|
doNotStrip '*/mips64/*.so'
|
||||||
}
|
}
|
||||||
|
dexOptions {
|
||||||
|
jumboMode true
|
||||||
|
javaMaxHeapSize "8g"
|
||||||
|
}
|
||||||
splits {
|
splits {
|
||||||
abi {
|
abi {
|
||||||
reset()
|
reset()
|
||||||
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
||||||
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||||
universalApk getEnvOrConfig('ORG_GRADLE_PROJECT_universalApk').toBoolean()
|
universalApk true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
@@ -236,7 +345,6 @@ android {
|
|||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
minifyEnabled enableProguardInReleaseBuilds
|
||||||
shrinkResources enableProguardInReleaseBuilds
|
|
||||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
signingConfig null
|
signingConfig null
|
||||||
}
|
}
|
||||||
@@ -244,13 +352,12 @@ android {
|
|||||||
initWith release
|
initWith release
|
||||||
applicationIdSuffix ".pr"
|
applicationIdSuffix ".pr"
|
||||||
versionNameSuffix ".pr"
|
versionNameSuffix ".pr"
|
||||||
debuggable false
|
debuggable false
|
||||||
matchingFallbacks = ["release"]
|
matchingFallbacks = ["release"]
|
||||||
// necessary to make react-native-config's code generation work
|
// necessary to make react-native-config's code generation work
|
||||||
resValue "string", "build_config_package", "im.status.ethereum"
|
resValue "string", "build_config_package", "im.status.ethereum"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// applicationVariants are e.g. debug, release
|
// applicationVariants are e.g. debug, release
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
variant.outputs.each { output ->
|
variant.outputs.each { output ->
|
||||||
@@ -266,7 +373,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aaptOptions {
|
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/)
|
// 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
|
cruncherEnabled = false
|
||||||
@@ -278,33 +384,54 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// The version of react-native is set by the React Native Gradle Plugin
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation("com.facebook.react:react-android")
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||||
implementation("androidx.core:core-splashscreen:1.0.0")
|
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) {
|
if (enableHermes) {
|
||||||
implementation("com.facebook.react:hermes-android")
|
//noinspection GradleDynamicVersion
|
||||||
} else {
|
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||||
// https://github.com/status-im/status-mobile/issues/18493
|
exclude group: 'com.facebook.fbjni' }
|
||||||
// we don't use hermes for debug builds because it crashes too often
|
} else {
|
||||||
implementation(jscFlavor)
|
implementation jscFlavor
|
||||||
}
|
}
|
||||||
|
|
||||||
// react-native-screens
|
// react-native-screens
|
||||||
implementation("androidx.appcompat:appcompat:1.1.0-rc01")
|
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02")
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||||
implementation("androidx.multidex:multidex:2.0.1") // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
|
|
||||||
|
implementation 'androidx.multidex:multidex:2.0.1' // 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')
|
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')
|
||||||
implementation project(':react-native-status-keycard')
|
implementation project(':react-native-status-keycard')
|
||||||
implementation("com.github.status-im:function:0.0.1")
|
implementation 'com.github.status-im:function:0.0.1'
|
||||||
implementation("com.facebook.fresco:fresco:2.5.0")
|
implementation 'com.facebook.fresco:fresco:2.5.0'
|
||||||
implementation("com.facebook.fresco:animated-gif:2.5.0")
|
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||||
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
|
implementation "com.squareup.okhttp3:okhttp-tls:4.9.2"
|
||||||
implementation("com.google.prefab:cli:2.0.0")
|
|
||||||
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 getLocalNDKDir = { ->
|
||||||
def rootDir = project.rootDir
|
def rootDir = project.rootDir
|
||||||
@@ -339,3 +466,11 @@ task hemroidBuild(type: Exec) {
|
|||||||
preBuild.dependsOn hemroidBuild
|
preBuild.dependsOn hemroidBuild
|
||||||
|
|
||||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
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.** { *; }
|
-keep interface okhttp3.** { *; }
|
||||||
-dontwarn okhttp3.**
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
# to fix : java.security.KeyStoreException: BKS not found
|
|
||||||
-keep class org.bouncycastle.** { *; }
|
|
||||||
|
|
||||||
# okio
|
# okio
|
||||||
|
|
||||||
-keep class sun.misc.Unsafe { *; }
|
-keep class sun.misc.Unsafe { *; }
|
||||||
@@ -78,13 +75,4 @@
|
|||||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||||
**[] $VALUES;
|
**[] $VALUES;
|
||||||
public *;
|
public *;
|
||||||
}
|
}
|
||||||
|
|
||||||
# react-native-config
|
|
||||||
# https://github.com/lugg/react-native-config?tab=readme-ov-file#problems-with-proguard
|
|
||||||
-keep class im.status.ethereum.BuildConfig {*;}
|
|
||||||
|
|
||||||
# react-native-navigation
|
|
||||||
# to fix : java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
|
|
||||||
# at com.reactnativenavigation.views.element.animators.PropertyAnimatorCreator.getChildClass(Unknown Source:13)
|
|
||||||
-keep class com.reactnativenavigation.** {*;}
|
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
<!-- These are added by React Native for debug mode, but actually aren't needed in release mode -->
|
||||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
|
<!-- Remove licensing permission since we don't license our app and it blocks F-Droid submissions. -->
|
||||||
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
|
<uses-permission tools:node="remove" android:name="com.android.vending.CHECK_LICENSE"/>
|
||||||
|
|
||||||
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" />
|
<application tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" android:usesCleartextTraffic="true" >
|
||||||
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -1,17 +1,10 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto"
|
||||||
|
package="im.status.ethereum">
|
||||||
<queries>
|
|
||||||
<intent>
|
|
||||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
|
||||||
<data android:mimeType="*/*" />
|
|
||||||
</intent>
|
|
||||||
</queries>
|
|
||||||
|
|
||||||
<!-- non-dangerous permissions -->
|
<!-- non-dangerous permissions -->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.NFC"/>
|
<uses-permission android:name="android.permission.NFC"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
@@ -24,11 +17,11 @@
|
|||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<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.ACCESS_FINE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
@@ -36,7 +29,6 @@
|
|||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:theme="@style/Theme.AppSplash"
|
android:theme="@style/Theme.AppSplash"
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
@@ -71,30 +63,8 @@
|
|||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<!-- Handles http and https URLs for status.app -->
|
|
||||||
<data android:scheme="http" android:host="status.app" />
|
<data android:scheme="http" android:host="status.app" />
|
||||||
<data android:scheme="https" android:host="status.app" />
|
<data android:scheme="https" android:host="status.app" />
|
||||||
<!-- Community paths -->
|
|
||||||
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/c/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Community channel paths -->
|
|
||||||
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/cc/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- User paths -->
|
|
||||||
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/u/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Private chat paths -->
|
|
||||||
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/p/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Community request paths -->
|
|
||||||
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/cr/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Group chat paths -->
|
|
||||||
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/g/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
<!-- Wallet paths -->
|
|
||||||
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="http" />
|
|
||||||
<data android:pathPattern="/wallet/.*" android:host="status.app" android:scheme="https" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
@@ -105,13 +75,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
|
||||||
<service
|
<service android:name="im.status.ethereum.pushnotifications.ForegroundService"></service>
|
||||||
android:name="im.status.ethereum.pushnotifications.ForegroundService"
|
|
||||||
android:foregroundServiceType="specialUse">
|
|
||||||
<property
|
|
||||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
|
||||||
android:value="local notifications"/>
|
|
||||||
</service>
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.provider"
|
android:authorities="${applicationId}.provider"
|
||||||
|
|||||||
@@ -0,0 +1,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,95 @@
|
|||||||
|
package im.status.ethereum;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientFactory;
|
||||||
|
import com.facebook.react.modules.network.OkHttpClientProvider;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.tls.HandshakeCertificates;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.RuntimeException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import im.status.ethereum.module.StatusPackage;
|
||||||
|
|
||||||
|
class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
||||||
|
|
||||||
|
private static final String TAG = "StatusOkHttpClientFactory";
|
||||||
|
|
||||||
|
public OkHttpClient createNewNetworkModuleClient() {
|
||||||
|
X509Certificate cert = null;
|
||||||
|
HandshakeCertificates clientCertificates;
|
||||||
|
String certPem = "";
|
||||||
|
// Get TLS PEM certificate from status-go
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
certPem = getCertificatePem();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (certPem.isEmpty()) {
|
||||||
|
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert PEM certificate string to X509Certificate object
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not parse certificate",e);
|
||||||
|
}
|
||||||
|
// Create HandshakeCertificates object with our certificate
|
||||||
|
try {
|
||||||
|
// induce half second sleep because sometimes a cert is not immediately available
|
||||||
|
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||||
|
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||||
|
Thread.sleep(500);
|
||||||
|
clientCertificates = new HandshakeCertificates.Builder()
|
||||||
|
.addPlatformTrustedCertificates()
|
||||||
|
.addTrustedCertificate(cert)
|
||||||
|
.build();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not build HandshakeCertificates", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create OkHttpClient with custom SSL socket factory and trust manager
|
||||||
|
try {
|
||||||
|
return OkHttpClientProvider.createClientBuilder()
|
||||||
|
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
|
||||||
|
.build();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.e(TAG, "Could not create OkHttpClient", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private String getCertificatePem() {
|
||||||
|
try {
|
||||||
|
String certPem = StatusPackage.getImageTLSCert();
|
||||||
|
if (certPem == null || certPem.trim().isEmpty()) {
|
||||||
|
Log.e(TAG, "Certificate PEM string is null or empty");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return certPem;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Could not getImageTLSCert", e);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_background"/>
|
<background android:drawable="@mipmap/ic_background"/>
|
||||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
</adaptive-icon>
|
||||||
</adaptive-icon>
|
|
||||||
@@ -2,5 +2,4 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@mipmap/ic_background"/>
|
<background android:drawable="@mipmap/ic_background"/>
|
||||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
</adaptive-icon>
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 374 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 239 B |
|
Before Width: | Height: | Size: 737 B After Width: | Height: | Size: 678 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 970 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 905 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 3.0 KiB |