Compare commits

..
Author SHA1 Message Date
Omar Basem 502718440c draft 2023-03-21 14:09:06 +04:00
Omar Basem f0cbfd7155 updates 2023-03-21 13:40:14 +04:00
Omar Basem 9c49991bae draft 2023-03-21 13:26:12 +04:00
Omar Basem 1b4c65ea97 draft 2023-03-21 13:03:37 +04:00
Omar Basem 41547a70a5 draft 2023-03-21 12:49:00 +04:00
Omar Basem a030046401 draft 2023-03-21 12:32:56 +04:00
Omar Basem 7557e885d0 draft 2023-03-21 12:12:02 +04:00
Omar Basem 06fa981954 draft 2023-03-21 11:38:02 +04:00
Omar Basem 38522e5180 draft 2023-03-21 11:33:58 +04:00
Omar Basem ecba5ade66 lint 2023-03-21 10:54:53 +04:00
Omar Basem c94508e559 remove image delay 2023-03-21 09:05:33 +04:00
4910 changed files with 125245 additions and 186394 deletions
+203 -152
View File
@@ -1,55 +1,62 @@
legacy.status-im.utils.build/warning-handler status-im.utils.build/warning-handler
legacy.status-im.utils.build/get-current-sha status-im.utils.build/get-current-sha
status-im.constants/spacing-char status-im2.constants/spacing-char
status-im.constants/arg-wrapping-char status-im2.constants/arg-wrapping-char
legacy.status-im.ios.core/init status-im.ios.core/init
legacy.status-im.ui.components.camera/aspects status-im.ui.components.camera/aspects
legacy.status-im.ui.components.camera/capture-targets status-im.ui.components.camera/capture-targets
legacy.status-im.ui.components.camera/set-torch status-im.ui.components.camera/set-torch
legacy.status-im.ui.components.camera/request-access-ios status-im.ui.components.camera/request-access-ios
legacy.status-im.chat.models.message-content/stylings status-im.chat.models.message-content/stylings
legacy.status-im.chat.models.message-content/actions status-im.chat.models.message-content/actions
legacy.status-im.chat.models.message-content/blank-string status-im.chat.models.message-content/blank-string
legacy.status-im.chat.models.message-content/sorted-ranges status-im.chat.models.message-content/sorted-ranges
legacy.status-im.ethereum.mnemonic/words->passphrase status-im.ethereum.mnemonic/words->passphrase
native-module.core/listener status-im.native-module.core/listener
native-module.core/multiaccount-reset status-im.native-module.core/multiaccount-reset
native-module.core/extract-group-membership-signatures status-im.native-module.core/extract-group-membership-signatures
native-module.core/sign-group-membership status-im.native-module.core/sign-group-membership
native-module.core/update-mailservers status-im.native-module.core/update-mailservers
legacy.status-im.ethereum.abi-spec/bytes-to-hex status-im.ethereum.abi-spec/bytes-to-hex
legacy.status-im.android.core/init status-im.android.core/init
legacy.status-im.chat.models.message/transport-keys status-im.chat.models.message/transport-keys
legacy.status-im.utils.datetime/week status-im.utils.datetime/week
legacy.status-im.utils.datetime/time-ago status-im.utils.datetime/time-ago
legacy.status-im.utils.datetime/format-date status-im.utils.datetime/format-date
legacy.status-im.utils.datetime/get-ordinal-date status-im.utils.datetime/get-ordinal-date
reagent.dom/render reagent.dom/render
reagent.dom/unmount-component-at-node reagent.dom/unmount-component-at-node
reagent.dom/dom-node reagent.dom/dom-node
reagent.dom/force-update-all reagent.dom/force-update-all
legacy.status-im.multiaccounts.create.core/get-new-key-code status-im.multiaccounts.create.core/get-new-key-code
legacy.status-im.ethereum.decode/string status-im.ethereum.decode/string
legacy.status-im.ui.screens.network.views/mainnet? status-im.ui.screens.network.views/mainnet?
legacy.status-im.data-store.chats/event->string status-im.data-store.chats/event->string
legacy.status-im.mailserver.constants/seven-days status-im.mailserver.constants/seven-days
legacy.status-im.mailserver.constants/connection-timeout status-im.mailserver.constants/connection-timeout
legacy.status-im.hardwallet.card/install-applet status-im.hardwallet.card/install-applet
legacy.status-im.hardwallet.card/install-cash-applet status-im.hardwallet.card/install-cash-applet
legacy.status-im.multiaccount.login.data-test/all-contacts status-im.multiaccount.login.data-test/all-contacts
legacy.status-im.multiaccount.login.data-test/multiaccounts status-im.multiaccount.login.data-test/multiaccounts
legacy.status-im.multiaccount.login.data-test/get-chats status-im.multiaccount.login.data-test/get-chats
legacy.status-im.multiaccount.login.data-test/transport status-im.multiaccount.login.data-test/transport
legacy.status-im.multiaccount.login.data-test/topics status-im.multiaccount.login.data-test/topics
legacy.status-im.utils.utils/clear-timeout status-im.utils.utils/clear-timeout
legacy.status-im.utils.handlers/logged-in status-im.utils.handlers/logged-in
legacy.status-im.multiaccounts.model/credentials status-im.multiaccounts.model/credentials
legacy.status-im.multiaccounts.login.core/contract-fleet? status-im.multiaccounts.login.core/contract-fleet?
legacy.status-im.multiaccounts.login.core/fetch-nodes status-im.multiaccounts.login.core/fetch-nodes
status-im.config/rpc-networks-only? status-im2.config/rpc-networks-only?
status-im.config/waku-enabled? status-im2.config/waku-enabled?
legacy.status-im.utils.pairing/has-paired-installations? status-im.utils.pairing/has-paired-installations?
legacy.status-im.tribute-to-talk.core-test/user-cofx status-im.tribute-to-talk.core-test/user-cofx
quo.gesture-handler/tap-gesture-handler
quo.gesture-handler/pan-gesture-handler
quo.gesture-handler/long-press-gesture-handler
quo.gesture-handler/pure-native-button
quo.gesture-handler/createNativeWrapper
quo.gesture-handler/animated-raw-button
quo.gesture-handler/states
mocks.js-dependencies/action-button mocks.js-dependencies/action-button
mocks.js-dependencies/camera mocks.js-dependencies/camera
mocks.js-dependencies/dismiss-keyboard mocks.js-dependencies/dismiss-keyboard
@@ -78,108 +85,152 @@ mocks.js-dependencies/react-navigation-bottom-tabs
mocks.js-dependencies/react-native-haptic-feedback mocks.js-dependencies/react-native-haptic-feedback
mocks.js-dependencies/mock mocks.js-dependencies/mock
quo.previews.main/init quo.previews.main/init
legacy.status-im.chat.models.message-list-test/descending-range status-im.chat.models.message-list-test/descending-range
legacy.status-im.chat.models.message-list-test/random-range status-im.chat.models.message-list-test/random-range
legacy.status-im.ethereum.eip165/supports? status-im.ethereum.eip165/supports?
legacy.status-im.utils.hex/valid-hex? status-im.utils.hex/valid-hex?
legacy.status-im.multiaccounts.core/chat-send? status-im.multiaccounts.core/chat-send?
legacy.status-im.hardwallet.simulated-keycard/install-cash-applet status-im.hardwallet.simulated-keycard/install-cash-applet
legacy.status-im.hardwallet.simulated-keycard/sign-typed-data status-im.hardwallet.simulated-keycard/sign-typed-data
legacy.status-im.utils.core/safe-read-message-content status-im.utils.core/safe-read-message-content
legacy.status-im.ui.components.react/native-modules status-im.ui.components.react/native-modules
legacy.status-im.ui.components.react/progress-bar status-im.ui.components.react/progress-bar
react-native.fs/move-file status-im.utils.fs/move-file
react-native.fs/read-dir status-im.utils.fs/read-dir
react-native.fs/mkdir status-im.utils.fs/mkdir
react-native.fs/unlink status-im.utils.fs/unlink
react-native.fs/file-exists? status-im.utils.fs/file-exists?
legacy.status-im.ui.components.colors/white quo.animated/code
legacy.status-im.ui.components.colors/black quo.animated/eq
legacy.status-im.ui.components.core/animated-header quo.animated/neq
legacy.status-im.ui.components.core/safe-area-provider quo.animated/greater-or-eq
legacy.status-im.ui.components.core/safe-area-consumer quo.animated/not*
legacy.status-im.ui.components.core/safe-area-view quo.animated/or*
legacy.status-im.utils.universal-links.core/open! quo.animated/and*
legacy.status-im.transport.filters.core-test/member-2 quo.animated/add
legacy.status-im.ui.screens.chat.ttt/one-to-one-chat-description-container quo.animated/sub
legacy.status-im.ethereum.ens/ttl quo.animated/multiply
legacy.status-im.ethereum.ens/addr-hash quo.animated/abs
legacy.status-im.ethereum.ens/name-hash quo.animated/min*
legacy.status-im.ethereum.ens/ABI-hash quo.animated/max*
legacy.status-im.ethereum.ens/pubkey-hash quo.animated/set
legacy.status-im.network.core/get-network quo.animated/start-clock
status-im.constants/desktop-content-types quo.animated/stop-clock
status-im.constants/blocks-per-hour quo.animated/bezier
status-im.constants/one-earth-day quo.animated/linear
status-im.constants/left-pane-min-width quo.animated/set-value
status-im.constants/system quo.animated/clock
status-im.constants/contact-discovery quo.animated/debug
status-im.constants/send-transaction-failed-parse-response quo.animated/log
status-im.constants/send-transaction-failed-parse-params quo.animated/event
status-im.constants/send-transaction-no-account-selected quo.animated/on-change
status-im.constants/send-transaction-invalid-tx-sender quo.animated/cond*
status-im.constants/web3-get-logs quo.animated/block
status-im.constants/web3-transaction-receipt quo.animated/call*
status-im.constants/web3-new-filter quo.animated/timing
status-im.constants/web3-new-pending-transaction-filter quo.animated/spring
status-im.constants/web3-new-block-filter quo.animated/clamp
status-im.constants/web3-uninstall-filter quo.animated/with-spring
status-im.constants/web3-get-filter-changes quo.animated/with-timing
status-im.constants/web3-shh-post quo.animated/re-timing
status-im.constants/web3-shh-new-identity quo.design-system.colors/white
status-im.constants/web3-shh-has-identity quo.design-system.colors/black
status-im.constants/web3-shh-new-group status-im.transport.core-test/messages
status-im.constants/web3-shh-add-to-group status-im.ethereum.core/sidechain?
status-im.constants/web3-shh-new-filter status-im.ethereum.core/network-with-upstream-rpc?
status-im.constants/web3-shh-uninstall-filter status-im.ethereum.core/current-address
status-im.constants/web3-shh-get-filter-changes status-im.ethereum.core/network->network-name
status-im.constants/web3-shh-get-messages status-im.ethereum.core/estimate-gas
status-im.constants/status-create-address quo.core/animated-header
status-im.constants/event-transfer-hash quo.core/safe-area-provider
status-im.constants/regx-rtl-characters quo.core/safe-area-consumer
status-im.constants/desktop-msg-chars-hard-limit quo.core/safe-area-view
status-im.constants/debug-metrics status-im.utils.universal-links.core/open!
status-im.constants/scan-qr-code status-im.transport.filters.core-test/member-2
status-im.constants/ipfs-proto-code status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
status-im.constants/swarm-proto-code status-im.ethereum.ens/ttl
legacy.status-im.multiaccounts.update.publisher/publish-update! status-im.ethereum.ens/addr-hash
legacy.status-im.utils.async/task-queue status-im.ethereum.ens/name-hash
legacy.status-im.utils.async/async-periodic-run! status-im.ethereum.ens/ABI-hash
legacy.status-im.desktop.core/app-root status-im.ethereum.ens/pubkey-hash
legacy.status-im.desktop.core/init status-im.network.core/get-network
legacy.status-im.chat.models-test/test-db status-im2.constants/desktop-content-types
legacy.status-im.ui.components.spacing/padding-vertical status-im2.constants/blocks-per-hour
legacy.status-im.utils.money/percent-change 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
quo.design-system.spacing/padding-vertical
status-im.utils.money/percent-change
status-im.utils.platform/isMacOs?
status-im.utils.platform/isNix?
status-im.utils.platform/isWin?
status-im.utils.platform/android-version>=
utils.debounce/clear-all utils.debounce/clear-all
legacy.status-im.transport.db/create-chat status-im.transport.db/create-chat
legacy.status-im.utils.priority-map/priority-map status-im.utils.priority-map/priority-map
legacy.status-im.utils.priority-map/priority-map-by status-im.utils.priority-map/priority-map-by
legacy.status-im.utils.priority-map/priority-map-keyfn status-im.utils.priority-map/priority-map-keyfn
legacy.status-im.utils.priority-map/empty-message-map status-im.utils.priority-map/empty-message-map
legacy.status-im.wallet.choose-recipient.core/use-default-eth-gas status-im.wallet.choose-recipient.core/use-default-eth-gas
legacy.status-im.ui.components.animation/decay status-im.ui.components.animation/decay
legacy.status-im.ui.components.animation/remove-all-listeners status-im.ui.components.animation/remove-all-listeners
legacy.status-im.ui.components.animation/stop-animation status-im.ui.components.animation/stop-animation
legacy.status-im.ui.components.animation/animated status-im.ui.components.animation/animated
legacy.status-im.ui.components.animation/add status-im.ui.components.animation/add
legacy.status-im.ui.components.animation/subtract status-im.ui.components.animation/subtract
legacy.status-im.ui.components.animation/get-layout status-im.ui.components.animation/get-layout
legacy.status-im.wallet.transactions-test/uri-query-data status-im.wallet.transactions-test/uri-query-data
legacy.status-im.utils.name/shortened-name quo.react-native/touchable-highlight
legacy.status-im.ui.components.button.haptic/trigger status-im.utils.name/shortened-name
legacy.status-im.contact.db/filter-dapps status-im.ui.components.button.haptic/trigger
legacy.status-im.contact.db/filter-group-contacts status-im.contact.db/filter-dapps
legacy.status-im.contact.db/legacy-pending? status-im.contact.db/filter-group-contacts
legacy.status-im.utils.transducers-test/preview-call-1 status-im.contact.db/legacy-pending?
legacy.status-im.utils.transducers-test/preview-call-2 status-im.utils.transducers-test/preview-call-1
legacy.status-im.utils.types/to-string status-im.utils.transducers-test/preview-call-2
legacy.status-im.chat.db/datemark? status-im.utils.types/to-string
legacy.status-im.chat.db/gap? status-im.chat.db/datemark?
legacy.status-im.chat.db/map->sorted-seq status-im.chat.db/gap?
legacy.status-im.utils.snoopy/status-module-filter status-im.chat.db/map->sorted-seq
legacy.status-im.utils.snoopy/websocket-filter status-im.utils.snoopy/status-module-filter
legacy.status-im.utils.snoopy/touches-filter status-im.utils.snoopy/websocket-filter
legacy.status-im.utils.snoopy/native-animation-filter status-im.utils.snoopy/touches-filter
legacy.status-im.utils.snoopy/keyboard-observer-filter status-im.utils.snoopy/native-animation-filter
legacy.status-im.utils.multihash/hex status-im.utils.snoopy/keyboard-observer-filter
legacy.status-im.utils.multihash/decode-array status-im.utils.multihash/hex
status-im.utils.multihash/decode-array
-1
View File
@@ -1 +0,0 @@
{:lint-as {babashka.fs/with-temp-dir clojure.core/let}}
-1
View File
@@ -1 +0,0 @@
{:hooks {:macroexpand {sci.core/copy-ns sci.core/copy-ns}}}
-9
View File
@@ -1,9 +0,0 @@
(ns sci.core)
(defmacro copy-ns
([ns-sym sci-ns]
`(copy-ns ~ns-sym ~sci-ns nil))
([ns-sym sci-ns opts]
`[(quote ~ns-sym)
~sci-ns
(quote ~opts)]))
+10 -75
View File
@@ -1,88 +1,23 @@
{:config-paths ["status-im"] {:lint-as {status-im.utils.views/defview clojure.core/defn
:output {:exclude-files ["src/user.cljs" "src/dev/user.cljs"]} status-im.utils.views/letsubs clojure.core/let
:lint-as {legacy.status-im.utils.views/defview clojure.core/defn
legacy.status-im.utils.views/letsubs clojure.core/let
reagent.core/with-let clojure.core/let reagent.core/with-let clojure.core/let
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all 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 clj-kondo.lint-as/def-catch-all
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
legacy.status-im.utils.styles/def clojure.core/def status-im.utils.styles/def clojure.core/def
legacy.status-im.utils.styles/defn clojure.core/defn status-im.utils.styles/defn clojure.core/defn
test-helpers.unit/deftest-sub clojure.core/defn test-helpers.unit/deftest-sub clojure.core/defn
test-helpers.unit/deftest-event clojure.core/defn
taoensso.tufte/defnp clojure.core/defn} taoensso.tufte/defnp clojure.core/defn}
:linters {:case-duplicate-test {:level :error} :linters {:consistent-alias {:level :error
:case-quoted-test {:level :error} :aliases {clojure.string string
:case-symbol-test {:level :error} clojure.set set
:clj-kondo-config {:level :error}
:cond-else {:level :error}
:condition-always-true {:level :error}
:conflicting-alias {:level :error}
:consistent-alias {:level :error
:aliases {clojure.set set
clojure.string string
clojure.walk walk clojure.walk walk
malli.core malli
malli.dev.pretty malli.pretty
malli.dev.virhe malli.virhe
malli.error malli.error
malli.generator malli.generator
malli.transform malli.transform
malli.util malli.util
promesa.core promesa
schema.core schema
status-im.feature-flags ff
taoensso.timbre log}} taoensso.timbre log}}
:deprecated-namespace {:level :warning} :invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
:docstring-blank {:level :error}
:equals-true {:level :error}
:inline-def {:level :error}
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
utils.re-frame/defn]}
:loop-without-recur {:level :error}
:minus-one {:level :error}
:misplaced-docstring {:level :error}
:missing-body-in-when {:level :error}
:missing-clause-in-try {:level :error}
:missing-else-branch {:level :error}
:multiple-async-in-deftest {:level :error}
:not-empty? {:level :error}
:plus-one {:level :error}
:redundant-do {:level :error}
:redundant-let {:level :error}
:refer-all {:level :error}
:shadowed-fn-param {:level :error}
:shadowed-var {:level :error
;; We temporarily use :include to define an
;; allowlist of core Clojure vars. In the
;; future, as we progressively fix shadowed
;; vars, we should be able to delete this
;; option and lint all vars.
:exclude [type name]}
:self-requiring-namespace {:level :error}
:single-operand-comparison {:level :error}
:syntax {:level :error}
:unbound-destructuring-default {:level :error}
:underscore-in-namespace {:level :error}
:uninitialized-var {:level :error}
:unknown-require-option {:level :error}
:unreachable-code {:level :error}
:unresolved-namespace {:level :error}
;; TODO remove number when this is fixed ;; TODO remove number when this is fixed
;; 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}
:unsorted-required-namespaces {:level :error}
:unused-alias {:level :warning}
:unused-binding {:level :error}
:unused-import {:level :error}
:unused-namespace {:level :error}
:unused-private-var {:level :error}
:unused-referred-var {:level :error}
:use {:level :error}}
:config-in-ns {mocks.js-dependencies {:linters {:clojure-lsp/unused-public-var {:level :off}}}}} :config-in-ns {mocks.js-dependencies {:linters {:clojure-lsp/unused-public-var {:level :off}}}}}
-9
View File
@@ -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}}
-2
View File
@@ -1,2 +0,0 @@
{:lint-as {malli.experimental/defn schema.core/defn}
:linters {:unresolved-symbol {:exclude [(malli.core/=>)]}}}
@@ -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/->>}}
-21
View File
@@ -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))")})
)
-11
View File
@@ -1,11 +0,0 @@
{:hooks
{:analyze-call
{utils.i18n/label utils.i18n/label
test-helpers.component/get-all-by-translation-text utils.i18n/label
test-helpers.component/get-by-translation-text utils.i18n/label
test-helpers.component/query-all-by-translation-text utils.i18n/label
test-helpers.component/query-by-translation-text utils.i18n/label
cljs.test/deftest cljs.test/deftest}}
:linters {:status-im.linter/invalid-translation-keyword {:level :error}
:status-im.linter/inconsistent-test-name {:level :error}}}
-26
View File
@@ -1,26 +0,0 @@
(ns utils.i18n
(:require [clj-kondo.hooks-api :as hooks]))
(defn label
"Verify call to `utils.i18n/label` pass the translation keyword qualified with `t`."
[{:keys [node]}]
(let [[_ translation-key-node & _] (:children node)]
(when (and (hooks/keyword-node? translation-key-node)
(not= "t" (-> translation-key-node hooks/sexpr namespace)))
(hooks/reg-finding! (assoc (meta translation-key-node)
:message "Translation keyword should be qualified with \"t\""
:type :status-im.linter/invalid-translation-keyword)))))
(comment
;; Valid
(label {:node (hooks/parse-string "(i18n/label :t/foo {:var \"hello\"})")
:cljc false
:lang :cljs
:filename ""
:config {}
:ns ""
:context nil})
;; Invalid
(label {:node (hooks/parse-string "(i18n/label :foo)")})
)
-1
View File
@@ -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))}))
+37
View File
@@ -0,0 +1,37 @@
module.exports = {
"testRunner": "jest",
"testRegex": "\\.visual\\.js$",
"runner-config": "visual-test/config.json",
"devices": {
"simulator": {
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
}
},
"apps": {
"ios.release": {
"name": "StatusIm",
"type": "ios.app",
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/StatusIm.app",
"build": "make release-ios"
},
"ios.debug": {
"name": "StatusIm",
"type": "ios.app",
"binaryPath": process.env.TEST_BINARY_PATH,
"build": "make run-ios SIMULATOR='iPhone 11 Pro'"
}
},
"configurations": {
"ios.sim.release": {
"device": "simulator",
"app": "ios.release"
},
"ios.sim.debug": {
"device": "simulator",
"app": "ios.debug"
}
}
}
+3 -6
View File
@@ -4,6 +4,7 @@ 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
@@ -21,18 +22,14 @@ KEYCARD_TEST_MENU=0
QR_READ_TEST_MENU=1 QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=1 ENABLE_ROOT_ALERT=1
ENABLE_QUO_PREVIEW=1 ENABLE_QUO_PREVIEW=1
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr 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
STICKERS_TEST_ENABLED=1 STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1 LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=0
ENABLE_ALERT_BANNER=0
FLAG_WALLET_CONNECT_ENABLED=1
+2 -9
View File
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc 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,6 +21,7 @@ COMMANDS_ENABLED=1
KEYCARD_TEST_MENU=1 KEYCARD_TEST_MENU=1
QR_READ_TEST_MENU=1 QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=0 ENABLE_ROOT_ALERT=0
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr APN_TOPIC=im.status.ethereum.pr
VERIFY_TRANSACTION_CHAIN_ID=5 VERIFY_TRANSACTION_CHAIN_ID=5
VERIFY_ENS_CHAIN_ID=5 VERIFY_ENS_CHAIN_ID=5
@@ -32,11 +33,3 @@ DELETE_MESSAGE_ENABLED=1
TWO_MINUTES_SYNCING=1 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
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
+2 -4
View File
@@ -3,6 +3,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc 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
@@ -25,6 +26,7 @@ VERIFY_TRANSACTION_CHAIN_ID=5
VERIFY_ENS_CHAIN_ID=5 VERIFY_ENS_CHAIN_ID=5
TEST_STATEOFUS=1 TEST_STATEOFUS=1
BLANK_PREVIEW=0 BLANK_PREVIEW=0
MAX_IMAGES_BATCH=5
DATABASE_MANAGEMENT_ENABLED=1 DATABASE_MANAGEMENT_ENABLED=1
COMMUNITIES_ENABLED=1 COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1 COMMUNITIES_MANAGEMENT_ENABLED=1
@@ -33,7 +35,3 @@ TWO_MINUTES_SYNCING=1
ENABLE_QUO_PREVIEW=1 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
TEST_NETWORKS_ENABLED=1
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
+2 -4
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=mainnet_rpc 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=info LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1 MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -16,11 +17,8 @@ RPC_NETWORKS_ONLY=0
PARTITIONED_TOPIC=0 PARTITIONED_TOPIC=0
CONTRACT_NODES=1 CONTRACT_NODES=1
ENABLE_ROOT_ALERT=1 ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=5
BLANK_PREVIEW=0 BLANK_PREVIEW=0
COMMUNITIES_ENABLED=1 COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1 DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1 DELETE_MESSAGE_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
ENABLE_ALERT_BANNER=1
FLAG_WALLET_CONNECT_ENABLED=1
+2 -4
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=0
DEFAULT_NETWORK=mainnet_rpc 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= LOG_LEVEL=
MAILSERVER_CONFIRMATIONS_ENABLED=1 MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -17,7 +18,4 @@ 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
FAST_CREATE_COMMUNITY_ENABLED=0 COLLECTIBLES_ENABLED=1
TEST_NETWORKS_ENABLED=0
STATUS_PROXY_STAGE_NAME=prod
FLAG_WALLET_CONNECT_ENABLED=1
+2 -2
View File
@@ -1,4 +1,4 @@
module.exports = { module.exports = {
root: true, root: true,
extends: '@react-native', extends: '@react-native-community',
}; };
+3 -2
View File
@@ -2,7 +2,7 @@
name: Bug Report name: Bug Report
about: Bug Report about: Bug Report
title: '' title: ''
labels: ['bug', ':1234: low prio'] labels: bug
assignees: '' assignees: ''
--- ---
@@ -22,7 +22,8 @@ assignees: ''
### Reproduction ### Reproduction
1. 1) Open Status
2)
### Additional Information ### Additional Information
-30
View File
@@ -1,30 +0,0 @@
---
name: Wont fix Report
about: to facilitate future handling, identify and address non-urgent issues that won't be prioritized in the near future
title: ''
labels: likely_wont_fix
assignees: ''
---
## Problem
#### Expected behavior
#### Actual behavior
### Reproduction
1.
### Additional Information
- Status version: release
- Operating System: Android, iOS
[comment]: # (Please, add logs/notes if necessary)
-22
View File
@@ -63,26 +63,4 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
<!-- (PRs will only be accepted if squashed into single commit.) --> <!-- (PRs will only be accepted if squashed into single commit.) -->
### Before and after screenshots comparison
| Figma (if available) | iOS (if available) | Android (if available)
| --- | --- | --- |
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
status: ready <!-- Can be ready or wip --> status: ready <!-- Can be ready or wip -->
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
- Specify potentially impacted user flows in _Areas that maybe 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.
-->
+1
View File
@@ -5,6 +5,7 @@ project-board:
min-reviewers: 1 min-reviewers: 1
tested-pr-label-name: 'Tested - Issues' tested-pr-label-name: 'Tested - Issues'
contributor-column-name: 'CONTRIBUTOR' contributor-column-name: 'CONTRIBUTOR'
to-rebase-column-name: 'TO REBASE'
review-column-name: 'REVIEW' review-column-name: 'REVIEW'
test-column-name: 'E2E Tests' test-column-name: 'E2E Tests'
-19
View File
@@ -7,7 +7,6 @@
# Xcode # Xcode
# #
/ios/.xcode.env.local
/component-spec /component-spec
result/ result/
build/ build/
@@ -36,10 +35,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 +78,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 +122,6 @@ fastlane/README.md
# Clj # Clj
.cpcache/ .cpcache/
src/user.cljs
src/dev/user.cljs
# emacs # emacs
.dir-locals.el .dir-locals.el
@@ -193,12 +183,3 @@ test/appium/tests/users.py
## component-tests ## component-tests
*.log *.log
## local xcode env introduced in react-native 0.69
.xcode.env.local
## git hooks
lefthook.yml
## build time logs
/logs/*.log
-1
View File
@@ -1 +0,0 @@
{:clean {:ns-inner-blocks-indentation :keep}}
+3 -3
View File
@@ -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,
-15
View File
@@ -1,15 +0,0 @@
/*
# Format top-level js files.
!*.js
# Ignore all except src/js/**/*.js
!/src/
/src/*
!/src/js
!/src/js/**/*.js
# Ignore all except translations/en.json
!/translations/
/translations/*
!/translations/en.json
+3 -9
View File
@@ -1,13 +1,7 @@
module.exports = { module.exports = {
arrowParens: 'always', bracketSpacing: false,
printWidth: 120, bracketSameLine: true,
semi: true,
singleQuote: true, singleQuote: true,
tabWidth: 2,
trailingComma: 'all', trailingComma: 'all',
useTabs: false, tabWidth: 4,
// JSON sorting
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
plugins: ['prettier-plugin-sort-json'],
}; };
-12
View File
@@ -1,12 +0,0 @@
{
"editor.formatOnSave": true,
"clojure.format.enable": false,
"[clojure]": {
"editor.defaultFormatter": "rflagreca.vscode-clj-zprint"
},
"vscode-clj-zprint.IgnoreExternalFiles": false,
"vscode-clj-zprint.CommunityFormatting": false,
"vscode-clj-zprint.OptionsMap": "",
"vscode-clj-zprint.width": "",
"vscode-clj-zprint.Styles.UseOnlyTheseStyles": false
}
+9 -20
View File
@@ -1,10 +1,8 @@
;; -*- 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
:style
[;; community style https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
:community :community
;; no comma in map ;; no comma in map
@@ -12,40 +10,31 @@
:custom-justify :custom-justify
;; respect all newlines https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl ;; respect all newlines
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
:respect-nl :respect-nl
;; respect blank line https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl ;; respect blank line
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
:respect-bl :respect-bl
;; hang multiline left-hand-thing https://github.com/kkinnear/zprint/issues/273 ;; hang multiline left-hand-thing
;; https://github.com/kkinnear/zprint/issues/273
:multi-lhs-hang] :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/describe-only" :arg1-body
"h/test" :arg1-body "h/test" :arg1-body
"h/test-skip" :arg1-body
"h/test-only" :arg1-body
"test/async" :arg1-body
"test/use-fixtures" :arg1-body
"global.describe" :arg1-body "global.describe" :arg1-body
"global.test" :arg1-body "global.test" :arg1-body
"list-comp" :binding "list-comp" :binding
"defview" :arg1-body "defview" :arg1-body
"letsubs" :binding "letsubs" :binding
"with-let" "let" "with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body "testing" :arg1-body
"deftest-sub" :arg1-body "deftest-sub" :arg1-body
"deftest-event" :arg1-body
"test-async" :arg1-body
"wait-for" :arg1-body "wait-for" :arg1-body
"with-deps-check" :arg1-body "with-deps-check" :arg1-body
"schema/=>" :arg1-body
"->" [:noarg1-body "->" [:noarg1-body
{:list {:constant-pair? false :force-nl? false} {:list {:constant-pair? false :force-nl? false}
:next-inner-restore [[:list :constant-pair?]]}] :next-inner-restore [[:list :constant-pair?]]}]
@@ -54,7 +43,7 @@
"assoc-some" "assoc" "assoc-some" "assoc"
"conj-when" "conj" "conj-when" "conj"
"conj-some" "conj"} "conj-some" "conj"}
:remove {:fn-force-nl #{:noarg1-body}}
:style-map :style-map
{:no-comma {:map {:comma? false}} {:no-comma {:map {:comma? false}}
:custom-justify :custom-justify
+88 -195
View File
@@ -32,30 +32,31 @@ 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 # Our custom config is located in nix/nix.conf
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf export NIX_CONF_DIR = $(PWD)/nix
# 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,STATUS_GO_SRC_OVERRIDE
BUILD_TYPE,BUILD_NUMBER,COMMIT_HASH,\
ANDROID_GRADLE_OPTS,ANDROID_ABI_SPLIT,ANDROID_ABI_INCLUDE,\
STATUS_GO_SRC_OVERRIDE,STATUS_GO_IPFS_GATEWAY_URL
# 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
#---------------- #----------------
@@ -80,10 +81,6 @@ nix-gc-protected:
@echo -e "$(YELLOW)The following paths are protected:$(RESET)" && \ @echo -e "$(YELLOW)The following paths are protected:$(RESET)" && \
ls -1 $(_NIX_GCROOTS) | sed 's/^/ - /' ls -1 $(_NIX_GCROOTS) | sed 's/^/ - /'
nix-upgrade: SHELL := /bin/sh
nix-upgrade: ##@nix Upgrade Nix interpreter to current version.
nix/scripts/upgrade.sh
nix-gc: export TARGET := nix nix-gc: export TARGET := nix
nix-gc: nix-gc-protected ##@nix Garbage collect all packages older than 20 days from /nix/store nix-gc: nix-gc-protected ##@nix Garbage collect all packages older than 20 days from /nix/store
nix-store --gc nix-store --gc
@@ -104,7 +101,7 @@ nix-update-clojure: export TARGET := clojure
nix-update-clojure: ##@nix Update maven Nix expressions based on current clojure setup nix-update-clojure: ##@nix Update maven Nix expressions based on current clojure setup
nix/deps/clojure/generate.sh nix/deps/clojure/generate.sh
nix-update-gems: export TARGET := fastlane nix-update-gems: export TARGET := default
nix-update-gems: ##@nix Update Ruby gems in fastlane/Gemfile.lock and fastlane/gemset.nix nix-update-gems: ##@nix Update Ruby gems in fastlane/Gemfile.lock and fastlane/gemset.nix
fastlane/update.sh fastlane/update.sh
@@ -139,7 +136,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 +153,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 +191,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,30 +205,36 @@ 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 BUILD_ENV ?= prod release-ios: export BUILD_ENV ?= prod
release-ios: watchman-clean ios-clean jsbundle ##@build Build release for iOS release release-ios: watchman-clean ##@build Build release for iOS release
xcodebuild \ @git clean -dxf -f target/ios && \
-scheme StatusIm \ $(MAKE) jsbundle-ios && \
-configuration Release \ xcodebuild -workspace ios/StatusIm.xcworkspace -scheme StatusIm -configuration Release -destination 'generic/platform=iOS' -UseModernBuildSystem=N clean archive
-workspace ios/StatusIm.xcworkspace \
-destination 'generic/platform=iOS' \
-UseModernBuildSystem=N clean archive
jsbundle: SHELL := /bin/sh jsbundle-android: SHELL := /bin/sh
jsbundle: export BUILD_ENV ?= prod jsbundle-android: export TARGET := android
jsbundle: ##@build Build JavaScript and Clojurescript bundle for iOS and Android jsbundle-android: export BUILD_ENV ?= prod
nix/scripts/build.sh targets.mobile.jsbundle jsbundle-android: ##@jsbundle Compile JavaScript and Clojurescript into app directory
# Call nix-build to build the 'targets.mobile.android.jsbundle' attribute and copy the.js files to the project root
nix/scripts/build.sh targets.mobile.android.jsbundle && \
mv result/*.js ./
jsbundle-ios: export TARGET := ios
jsbundle-ios: export BUILD_ENV ?= prod
jsbundle-ios: ##@jsbundle Compile JavaScript and Clojure into index.ios.js
yarn shadow-cljs release mobile
#-------------- #--------------
# status-go lib # status-go lib
@@ -265,7 +262,7 @@ 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
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
@@ -273,27 +270,17 @@ run-re-frisk: ##@run Start re-frisk server
# 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.
# https://github.com/status-im/status-mobile/issues/18493
run-android: export ORG_GRADLE_PROJECT_hermesEnabled := 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: ##@run Build iOS app and start it in a simulator/device
run-ios: ##@run Build iOS app and start it in on the simulator ifneq ("$(SIMULATOR)", "")
@scripts/run-ios.sh "${SIMULATOR}" npx react-native run-ios --simulator="$(SIMULATOR)"
else
show-ios-devices: ##@other shows connected ios device and its name npx react-native run-ios
xcrun xctrace list devices endif
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios-device: export TARGET := ios
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
run-ios-device: ##@run iOS app and start it on the first connected iPhone
@scripts/run-ios-device.sh
#-------------- #--------------
# Tests # Tests
@@ -301,120 +288,72 @@ 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 := default
lint: export CLJ_LINTER_PRINT_WARNINGS ?= false
lint: ##@test Run code style checks lint: ##@test Run code style checks
@sh scripts/lint/re-frame-in-quo-components.sh && \ @sh scripts/lint-re-frame-in-quo-components.sh && \
sh scripts/lint/direct-require-component-outside-quo.sh && \ clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
sh scripts/lint/require-i18n-resource-first.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src $(if $(filter $(CLJ_LINTER_PRINT_WARNINGS),true),,| grep -v ': warning: ') && \
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \ ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
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 && \
node_modules/.bin/prettier --check .
# 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 := default
lint-fix: ##@test Run code style checks and fix issues 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 && \
sh scripts/lint/trailing-newline.sh --fix && \
node_modules/.bin/prettier --write .
shadow-server: export TARGET := clojure 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
test: export SHADOW_NS_REGEXP := .*-test$$
test: ##@test Run all Clojure tests
test: _test-clojure
# Note: we need to override the :output-to and :ns-regexp options because run-visual-test-ios: export TARGET := clojure
# shadow-cljs has a bug where it will not read from the env vars to expand the run-visual-test-ios: XCODE_DERIVED_DATA := $(HOME)/Library/Developer/Xcode/DerivedData
# configuration when the shadow-cljs mobile target is already running. run-visual-test-ios: APPLICATION_NAME := StatusIm-brfnruzfrkkycpbndmdoeyrigthc
test-watch-for-repl: export TARGET := default run-visual-test-ios: export TEST_BINARY_PATH := $(XCODE_DERIVED_DATA)/$(APPLICATION_NAME)/Build/Products/Debug-iphonesimulator/StatusIm.app
test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js run-visual-test-ios: ##@test Run tests once in NodeJS
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$ detox test --configuration ios.sim.debug
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 component-test-watch: export TARGET := clojure
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests\.contract-test).*-test$$ component-test-watch: export COMPONENT_TEST := true
test-unit: ##@test Run unit tests component-test-watch: export BABEL_ENV := test
test-unit: _test-clojure component-test-watch: ##@ Watch tests and re-run no changes to cljs files
yarn install
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js' -e cljs
test-integration: export SHADOW_OUTPUT_TO := target/integration_test/test.js component-test: export TARGET := clojure
test-integration: export SHADOW_NS_REGEXP := ^tests\.integration-test.*$$ component-test: export COMPONENT_TEST := true
test-integration: ##@test Run integration tests component-test: export BABEL_ENV := test
test-integration: _test-clojure component-test: ##@test Run component tests once in NodeJS
yarn install
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
test-component-watch: export TARGET := clojure
test-component-watch: export COMPONENT_TEST := true
test-component-watch: export BABEL_ENV := test
test-component-watch: export JEST_USE_SILENT_REPORTER := false
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
test-component: export TARGET := clojure
test-component: export COMPONENT_TEST := true
test-component: export BABEL_ENV := test
test-component: export JEST_USE_SILENT_REPORTER := false
test-component: ##@test Run component tests once in NodeJS
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
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
#-------------- #--------------
@@ -423,49 +362,22 @@ geth-connect: ##@other Connect to Geth on the device
adb forward tcp:8545 tcp:8545 && \ adb forward tcp:8545 tcp:8545 && \
build/bin/geth attach http://localhost:8545 build/bin/geth attach http://localhost:8545
ios-clean: SHELL := /bin/sh android-clean: export TARGET := gradle
ios-clean: ios-simulator-cache-clean
ios-clean: ##@prepare Clean iOS build artifacts
git clean -dxf -f target/ios
android-clean: SHELL := /bin/sh
android-clean: ##@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:4567 tcp:4567 && \ 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 :'
@@ -479,10 +391,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
#-------------- #--------------
@@ -492,18 +400,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)"
+23 -18
View File
@@ -2,11 +2,9 @@
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="80"/>](https://play.google.com/store/apps/details?id=im.status.ethereum) [<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="80"/>](https://play.google.com/store/apps/details?id=im.status.ethereum)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/>](https://f-droid.org/packages/im.status.ethereum/) [<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/>](https://f-droid.org/packages/im.status.ethereum/)
[<img src="doc/github_badge.png" alt="Get it on Github" height="80"/>](https://github.com/status-im/status-mobile/releases)
Join us in creating a browser, messenger, and gateway to a decentralized world. Status is a free (libre) open source mobile client targeting Android & iOS built entirely on [Ethereum](https://ethereum.org/) technologies. That's right, no middle men and `go-ethereum` running directly on your device.
[Get it on Github](https://github.com/status-im/status-mobile/releases)
Join us in creating a browser, messenger, and gateway to a decentralized world. Status is a free (libre) open source mobile client targeting Android & iOS built entirely on [Ethereum](https://ethereum.org/) technologies. That's right, no middlemen and `go-ethereum` running directly on your device.
[![Getting started with Status](https://i.imgur.com/C0aZZEL.jpg)](https://www.youtube.com/watch?v=oDCSEmS9c3o "Getting started with Status") [![Getting started with Status](https://i.imgur.com/C0aZZEL.jpg)](https://www.youtube.com/watch?v=oDCSEmS9c3o "Getting started with Status")
@@ -14,49 +12,52 @@ Join us in creating a browser, messenger, and gateway to a decentralized world.
We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems. We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems.
We want to take responsibility for our data, and the way we conduct ourselves privately and promote this way of life to a mass audience. We want to take responsibility for our data, the way we conduct ourselves privately and promote this way of life to a mass audience.
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provide us with a path forward. We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
If this interests you, **help us make Status a reality** - anyone can contribute and we need everyone at any skill level to participate. If this interests you, **help us make Status a reality** - anyone can contribute and we need everyone at any skill level to participate.
## How to Contribute? ## How to Contribute?
Go straight to the [docs](doc/) and choose what interests you: Go straight to the [docs](https://status.im/docs) or [join our chat](https://join.status.im/chat/public/status) and choose what interests you:
- **Developer** Developers are the heart of software and to keep Status beating - **Developer** Developers are the heart of software and to keep Status beating
we need all the help we can get! If you're looking to code in ClojureScript or we need all the help we can get! If you're looking to code in ClojureScript or
Golang then Status is the project for you! We use React Native and there is even Golang then Status is the project for you! We use React Native and there is even
some Java/Objective-C too! Want to learn more about it? Start by reading our some Java/Objective-C too! Want to learn more about it? Start by reading our
[Developer Introduction](doc/starting-guide.md) which guides you [Developer Introduction](https://status.im/developer_tools/) which guides you
through the technology stack and start browsing [beginner through the technology stack and start browsing [beginner
issues](https://github.com/status-im/status-mobile/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good%20first%20issue%22%20). issues](https://github.com/status-im/status-mobile/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good%20first%20issue%22%20).
Then you can read how to [Build Then you can read how to [Build
Status](doc/starting-guide.md), which talks about managing Status](https://status.im/technical/build_status/), which talks about managing
project dependencies, coding guidelines and testing procedures. project dependencies, coding guidelines and testing procedures. The [doc/](doc/)
Check out our [coding guidelines](doc/new-guidelines.md). directory also has valuable information for contributors.
- **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 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 & Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, head over to our [docs](https://status.im/docs) and see how you can improve what we have.
- **Blog Writing** - **Blog Writing**
Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page. Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page. [Jump into our chat](https://join.status.im/chat/public/status) and discuss with the team how you can contribute!
- **Testers** - **Testers**
It's bug-hunting season! Status is currently under active development and there is sure to be a bunch of learning, [build status from scratch](doc/starting-guide.md) or if an android user checks out our [nightly builds](https://status.im/nightly). You can shake your phone to submit bug reports, or start browsing our [Github Issues](https://github.com/status-im/status-mobile/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy! It's bug hunting season! Status is currently under active development and there is sure to be a bunch of learning, [build status from scratch](https://status.im/technical/build_status/) or if an android user check out our [nightly builds](https://status.im/nightly). You can shake your phone to submit bug reports, or start browsing our [Github Issues](https://github.com/status-im/status-mobile/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy!
- **Security** - **Security**
Status is a visual interface to make permanent changes on the Blockchain, it handles crypto-tokens that have real value and allows 3rd party code execution. Security is paramount to its success. You are given permission to break Status as hard as you can, as long as you share your findings with the community! Status is a visual interface to make permanent changes on the Blockchain, it handles crypto-tokens that have real value and allows 3rd party code execution. Security is paramount to its success. You are given permission to break Status as hard as you can, as long as you share your findings with the community!
- **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)
## Status API
View our [API Docs](https://status.im/developer_tools/status_web_api.html) and learn how to integrate your DApp into Status. You can read more about how to add your DApp to Status [here](https://status.im/developer_tools/add_your_dapp.html).
## 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
@@ -67,8 +68,12 @@ Without the dedication of these outstanding individuals, Status would not exist.
## Contact us ## Contact us
Feel free to email us at [support@status.im](mailto:support@status.im). Feel free to email us at [support@status.im](mailto:support@status.im) or better yet, [join our chat](https://join.status.im/chat/public/status).
## License ## License
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-mobile/blob/develop/LICENSE.md) Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-mobile/blob/develop/LICENSE.md)
## Testing Supported by
[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)](https://www.browserstack.com/automate/public-build/SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)
+1 -1
View File
@@ -25,7 +25,7 @@
### Redesign ### Redesign
* quo, Switcher Navigation by @Parveshdhull in https://github.com/status-im/status-mobile/pull/13167 * Quo2, Switcher Navigation by @Parveshdhull in https://github.com/status-im/status-mobile/pull/13167
* Switcher and Bottom Tabs Animations and UI Performance Improvements by @Parveshdhull in https://github.com/status-im/status-mobile/pull/13470 * Switcher and Bottom Tabs Animations and UI Performance Improvements by @Parveshdhull in https://github.com/status-im/status-mobile/pull/13470
* feat: add token tag component (#13599) by @J-Son89 in https://github.com/status-im/status-mobile/pull/13644 * feat: add token tag component (#13599) by @J-Son89 in https://github.com/status-im/status-mobile/pull/13644
* [13565] icon-avatar component by @ibrkhalil in https://github.com/status-im/status-mobile/pull/13692 * [13565] icon-avatar component by @ibrkhalil in https://github.com/status-im/status-mobile/pull/13692
+1 -1
View File
@@ -1 +1 @@
2.29.0 1.21.0
+140 -91
View File
@@ -1,68 +1,117 @@
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"],
// bundleInPr: true,
// The name of the generated asset file containing your JS bundle inputExcludes: ["android/**", "ios/**", "react-native/**", "src/**", "test/**"]
// bundleAssetName = "MyApplication.android.bundle" ]
//
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
// entryFile = file("../js/MyApplication.android.js")
//
// A list of extra flags to pass to the 'bundle' commands.
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
// extraPackagerArgs = []
/* 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:+'`
@@ -81,7 +130,7 @@ 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);
def getCommitHash = { -> def getCommitHash = { ->
if (project.hasProperty("commitHash")) { if (project.hasProperty("commitHash")) {
@@ -107,7 +156,6 @@ def getVersionCode = { ->
def getVersionName = { -> def getVersionName = { ->
new ByteArrayOutputStream().withStream { stdOut -> new ByteArrayOutputStream().withStream { stdOut ->
// TODO: probably not used, cleanup
if (project.hasProperty("releaseVersion")) { if (project.hasProperty("releaseVersion")) {
return project.releaseVersion return project.releaseVersion
} }
@@ -135,29 +183,13 @@ def getEnvOrConfig = { varName ->
} }
android { android {
ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdk rootProject.ext.compileSdkVersion
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
}
// 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_1_8
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_1_8
} }
namespace "im.status.ethereum"
defaultConfig { defaultConfig {
applicationId "im.status.ethereum" applicationId "im.status.ethereum"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
@@ -174,7 +206,6 @@ android {
} }
} }
} }
/** /**
* 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
@@ -206,12 +237,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 false universalApk true
} }
} }
signingConfigs { signingConfigs {
@@ -232,7 +267,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
} }
@@ -246,7 +280,6 @@ android {
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 ->
@@ -262,7 +295,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
@@ -274,34 +306,51 @@ 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 "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
implementation "androidx.core:core-splashscreen:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
// TODO Uncomment once Flipper does not cause webview crashes in Debug mode
// debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
// exclude group:'com.facebook.flipper'
// }
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
if (enableHermes) { if (enableHermes) {
implementation("com.facebook.react:hermes-android") def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
prImplementation files(hermesPath + "hermes-release.aar")
} else { } else {
// https://github.com/status-im/status-mobile/issues/18493 implementation jscFlavor
// we don't use hermes for debug builds because it crashes too often
implementation(jscFlavor)
} }
// react-native-screens // react-native-screens
implementation("androidx.appcompat:appcompat:1.1.0-rc01") implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02") implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
implementation("androidx.multidex:multidex:2.0.1") // required by status-mobile/android/app/src/main/java/im/status/ethereum/MainApplication.java
implementation 'androidx.multidex:multidex:2.0.1' // 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.2.0'
implementation("com.facebook.fresco:animated-gif:2.5.0") implementation 'com.facebook.fresco:animated-gif:2.2.0'
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0") implementation "com.squareup.okhttp3:okhttp-tls:3.12.12"
implementation("com.google.prefab:cli:2.0.0")
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
} }
def getLocalNDKDir = { -> def getLocalNDKDir = { ->
def rootDir = project.rootDir def rootDir = project.rootDir
def localProperties = new File(rootDir, "local.properties") def localProperties = new File(rootDir, "local.properties")
-12
View File
@@ -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 { *; }
@@ -79,12 +76,3 @@
**[] $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.** {*;}
+1 -1
View File
@@ -3,7 +3,7 @@
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"/>
@@ -0,0 +1,73 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package im.status.ethereum;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
// import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
// import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
// TODO Uncomment once Flipper does not cause webview crashes in Debug mode
// NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
// NetworkingModule.setCustomClientBuilder(
// new NetworkingModule.CustomClientBuilder() {
// @Override
// public void apply(OkHttpClient.Builder builder) {
// builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
// }
// });
// client.addPlugin(networkFlipperPlugin);
client.start();
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceManager.ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
reactContext.runOnNativeModulesQueueThread(
new Runnable() {
@Override
public void run() {
client.addPlugin(new FrescoFlipperPlugin());
}
});
}
});
} else {
client.addPlugin(new FrescoFlipperPlugin());
}
}
}
}
+11 -51
View File
@@ -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,15 +29,10 @@
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"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true">
android:extractNativeLibs="true"
android:requestLegacyExternalStorage="true">
<!-- After upgrading Android Gradle Plugin to 4.2.0 and above we must get rid of `extractNativeLibs="true"`
and use`useLegacyPackaging` flag in our app's `build.gradle`-->
<meta-data android:name="commitHash" android:value="${commitHash}"/> <meta-data android:name="commitHash" android:value="${commitHash}"/>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
@@ -53,7 +41,7 @@
android:theme="@style/Theme.AppSplash" android:theme="@style/Theme.AppSplash"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:resizeableActivity="false" android:resizeableActivity="false"
android:launchMode="singleTask"> android:launchMode="singleTask">
<intent-filter> <intent-filter>
@@ -71,47 +59,19 @@
<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="join.status.im" />
<data android:scheme="http" android:host="status.app" /> <data android:scheme="https" android:host="join.status.im" />
<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" />
<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" />
<data android:scheme="status-app" /> <data android:scheme="status-im" />
<data android:scheme="ethereum" /> <data android:scheme="ethereum" />
</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.facebook.react.ReactFragmentActivity;
import com.reactnativenavigation.NavigationActivity;
import com.facebook.react.modules.core.PermissionListener;
import androidx.core.splashscreen.SplashScreen;
import java.util.Properties;
import im.status.ethereum.module.StatusThreadPoolExecutor;
import im.status.ethereum.MainApplication;
public class MainActivity extends NavigationActivity
implements ActivityCompat.OnRequestPermissionsResultCallback{
@Nullable private PermissionListener mPermissionListener;
private boolean keepSplash = true;
private final int SPLASH_DELAY = 3200;
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,107 @@
package im.status.ethereum;
import androidx.multidex.MultiDexApplication;
import android.util.Log;
import android.content.Context;
import android.webkit.WebView;
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.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();
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
OkHttpClientProvider.setOkHttpClientFactory(new StatusOkHttpClientFactory());
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1");
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("im.status.ethereum.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
@@ -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()
}
}
}
@@ -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,44 @@
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 {
public OkHttpClient createNewNetworkModuleClient() {
String certPem = StatusPackage.getImageTLSCert();
X509Certificate cert;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certPem.getBytes()));
} catch(Exception e) {
Log.e("StatusOkHttpClientFactory", "Could not parse certificate");
cert = null;
}
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
.addPlatformTrustedCertificates()
.addTrustedCertificate(cert)
.build();
return OkHttpClientProvider.createClientBuilder()
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager())
.build();
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 940 B

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 B

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

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>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More