Compare commits
177
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2dd07726c | ||
|
|
c99a967dec | ||
|
|
ea0c9e03cc | ||
|
|
c35c8609f8 | ||
|
|
daa86aaef9 | ||
|
|
571939ae07 | ||
|
|
74d2570185 | ||
|
|
e1f1e216a7 | ||
|
|
7daabf38a3 | ||
|
|
a90c195950 | ||
|
|
ffea7bbda9 | ||
|
|
6d5a064f1e | ||
|
|
cdb1bd2480 | ||
|
|
d96bab2511 | ||
|
|
1e1adfc5ea | ||
|
|
e4a750a0fd | ||
|
|
fb4f42d17b | ||
|
|
e456b19c44 | ||
|
|
7482a16628 | ||
|
|
d88b5ce803 | ||
|
|
d0480dbb7c | ||
|
|
1e3838c5ee | ||
|
|
30459be088 | ||
|
|
6c1be43eaf | ||
|
|
1f9267704a | ||
|
|
7e47e7db1e | ||
|
|
4c9565b080 | ||
|
|
b372baf3db | ||
|
|
70b8fcdfe2 | ||
|
|
128cc28597 | ||
|
|
c51d6defe2 | ||
|
|
9faa9b69b3 | ||
|
|
3a4a13b281 | ||
|
|
62fcd7cf0f | ||
|
|
2d5cca836a | ||
|
|
9296205ce5 | ||
|
|
15657ad1b2 | ||
|
|
c2e5a53a4e | ||
|
|
84c703c303 | ||
|
|
5ba64a5890 | ||
|
|
81f8ff8e14 | ||
|
|
8c403004b7 | ||
|
|
cabfdfa8e7 | ||
|
|
40d77685dd | ||
|
|
75ecc1eab1 | ||
|
|
11d66e5bc2 | ||
|
|
9d5f6d0b06 | ||
|
|
48c83ef759 | ||
|
|
c84fc71bf1 | ||
|
|
550602db12 | ||
|
|
5932f7dc99 | ||
|
|
b89dce3c2a | ||
|
|
8aba451be8 | ||
|
|
82dd805755 | ||
|
|
6e30d9faa8 | ||
|
|
070869b705 | ||
|
|
9dfa1069e5 | ||
|
|
99dd374c87 | ||
|
|
bac5ace90a | ||
|
|
34cb7d19e2 | ||
|
|
a98bbf6a71 | ||
|
|
8116f7a7b1 | ||
|
|
b3fbed1a1b | ||
|
|
4826bedba4 | ||
|
|
b81ac07636 | ||
|
|
2da2dfdad7 | ||
|
|
1036bff41b | ||
|
|
e15b9a224c | ||
|
|
82ab32c028 | ||
|
|
3541485338 | ||
|
|
8c82a84aee | ||
|
|
447945f46e | ||
|
|
16b2c90040 | ||
|
|
a210d59c4f | ||
|
|
fe0c5c2da7 | ||
|
|
8c91fbdd49 | ||
|
|
93e0c1fc5e | ||
|
|
9c7d215217 | ||
|
|
4668d6a285 | ||
|
|
6c9c92efc7 | ||
|
|
eff252c7c0 | ||
|
|
ab12c8a17d | ||
|
|
8b21d6ab53 | ||
|
|
36fa4bdb62 | ||
|
|
ed10ed70f7 | ||
|
|
8c089bb334 | ||
|
|
45b09603d2 | ||
|
|
857cb47ceb | ||
|
|
4782b3eb2a | ||
|
|
1a5008bcda | ||
|
|
c5c7f2eb27 | ||
|
|
25072cff9f | ||
|
|
e38cb0dee6 | ||
|
|
ba4a8b7d81 | ||
|
|
882e40d99f | ||
|
|
c304b1b623 | ||
|
|
1da39e064d | ||
|
|
3899368aa0 | ||
|
|
5ff1c8f1e4 | ||
|
|
7289940653 | ||
|
|
a253f8cedb | ||
|
|
daf52102ce | ||
|
|
fa20d4d9c3 | ||
|
|
dd26fcf42c | ||
|
|
8ac9cc08e1 | ||
|
|
c1230319e1 | ||
|
|
1e48442d67 | ||
|
|
94fbbbcb3c | ||
|
|
4dfd616583 | ||
|
|
85d00e47af | ||
|
|
438fd7a512 | ||
|
|
ee5f73f5ee | ||
|
|
b49c0ae58a | ||
|
|
f474edf67d | ||
|
|
dfd90617bf | ||
|
|
9782ba2ac3 | ||
|
|
f0e0c95fe0 | ||
|
|
ef7d977299 | ||
|
|
70a5ed255f | ||
|
|
be1347346c | ||
|
|
803e83ae02 | ||
|
|
64748c939b | ||
|
|
64fb344197 | ||
|
|
f27b402205 | ||
|
|
b22744f81e | ||
|
|
174e44c77d | ||
|
|
35c5d5ae6a | ||
|
|
ae00ecb3e0 | ||
|
|
8687282d63 | ||
|
|
04a97faa43 | ||
|
|
91d3cd8da8 | ||
|
|
e1a7146f4c | ||
|
|
5dc1bfe03b | ||
|
|
2d8ba41d89 | ||
|
|
457ed15e0b | ||
|
|
c11cf22bbb | ||
|
|
6ffdaa4e25 | ||
|
|
f56bd54fd3 | ||
|
|
394648b377 | ||
|
|
22a606cbab | ||
|
|
1b30b3be80 | ||
|
|
10434b53e0 | ||
|
|
0472523a7f | ||
|
|
770963447a | ||
|
|
874aa9866d | ||
|
|
32a3f85694 | ||
|
|
b88bbda3c5 | ||
|
|
fad5119ceb | ||
|
|
3697f63ab0 | ||
|
|
ba8cf8e863 | ||
|
|
ce1d2c4ed8 | ||
|
|
813c60f9e1 | ||
|
|
28a81f2dd8 | ||
|
|
826410b687 | ||
|
|
1aa7594c41 | ||
|
|
5ff1d70357 | ||
|
|
2a95f7cfac | ||
|
|
4654c4a543 | ||
|
|
baf3b8c9ed | ||
|
|
c6ff90954f | ||
|
|
c37498a6b2 | ||
|
|
c1b0f3ae98 | ||
|
|
5007dc757f | ||
|
|
b09f3fa6da | ||
|
|
b11c817392 | ||
|
|
247674b280 | ||
|
|
07ea097bb4 | ||
|
|
23d3a2db2a | ||
|
|
a85ca5bd3d | ||
|
|
0f036ca9c4 | ||
|
|
c19128e8b1 | ||
|
|
8d615801d1 | ||
|
|
4f6e1897fe | ||
|
|
93b5f8d180 | ||
|
|
0e607dc293 | ||
|
|
9ced0e4131 | ||
|
|
55ee800e18 |
-185
@@ -1,185 +0,0 @@
|
||||
legacy.status-im.utils.build/warning-handler
|
||||
legacy.status-im.utils.build/get-current-sha
|
||||
status-im.constants/spacing-char
|
||||
status-im.constants/arg-wrapping-char
|
||||
legacy.status-im.ios.core/init
|
||||
legacy.status-im.ui.components.camera/aspects
|
||||
legacy.status-im.ui.components.camera/capture-targets
|
||||
legacy.status-im.ui.components.camera/set-torch
|
||||
legacy.status-im.ui.components.camera/request-access-ios
|
||||
legacy.status-im.chat.models.message-content/stylings
|
||||
legacy.status-im.chat.models.message-content/actions
|
||||
legacy.status-im.chat.models.message-content/blank-string
|
||||
legacy.status-im.chat.models.message-content/sorted-ranges
|
||||
legacy.status-im.ethereum.mnemonic/words->passphrase
|
||||
native-module.core/listener
|
||||
native-module.core/multiaccount-reset
|
||||
native-module.core/extract-group-membership-signatures
|
||||
native-module.core/sign-group-membership
|
||||
native-module.core/update-mailservers
|
||||
legacy.status-im.ethereum.abi-spec/bytes-to-hex
|
||||
legacy.status-im.android.core/init
|
||||
legacy.status-im.chat.models.message/transport-keys
|
||||
legacy.status-im.utils.datetime/week
|
||||
legacy.status-im.utils.datetime/time-ago
|
||||
legacy.status-im.utils.datetime/format-date
|
||||
legacy.status-im.utils.datetime/get-ordinal-date
|
||||
reagent.dom/render
|
||||
reagent.dom/unmount-component-at-node
|
||||
reagent.dom/dom-node
|
||||
reagent.dom/force-update-all
|
||||
legacy.status-im.multiaccounts.create.core/get-new-key-code
|
||||
legacy.status-im.ethereum.decode/string
|
||||
legacy.status-im.ui.screens.network.views/mainnet?
|
||||
legacy.status-im.data-store.chats/event->string
|
||||
legacy.status-im.mailserver.constants/seven-days
|
||||
legacy.status-im.mailserver.constants/connection-timeout
|
||||
legacy.status-im.hardwallet.card/install-applet
|
||||
legacy.status-im.hardwallet.card/install-cash-applet
|
||||
legacy.status-im.multiaccount.login.data-test/all-contacts
|
||||
legacy.status-im.multiaccount.login.data-test/multiaccounts
|
||||
legacy.status-im.multiaccount.login.data-test/get-chats
|
||||
legacy.status-im.multiaccount.login.data-test/transport
|
||||
legacy.status-im.multiaccount.login.data-test/topics
|
||||
legacy.status-im.utils.utils/clear-timeout
|
||||
legacy.status-im.utils.handlers/logged-in
|
||||
legacy.status-im.multiaccounts.model/credentials
|
||||
legacy.status-im.multiaccounts.login.core/contract-fleet?
|
||||
legacy.status-im.multiaccounts.login.core/fetch-nodes
|
||||
status-im.config/rpc-networks-only?
|
||||
status-im.config/waku-enabled?
|
||||
legacy.status-im.utils.pairing/has-paired-installations?
|
||||
legacy.status-im.tribute-to-talk.core-test/user-cofx
|
||||
mocks.js-dependencies/action-button
|
||||
mocks.js-dependencies/camera
|
||||
mocks.js-dependencies/dismiss-keyboard
|
||||
mocks.js-dependencies/emoji-picker
|
||||
mocks.js-dependencies/i18n
|
||||
mocks.js-dependencies/qr-code
|
||||
mocks.js-dependencies/svg
|
||||
mocks.js-dependencies/icons
|
||||
mocks.js-dependencies/webview
|
||||
mocks.js-dependencies/desktop-linking
|
||||
mocks.js-dependencies/desktop-shortcuts
|
||||
mocks.js-dependencies/snoopy
|
||||
mocks.js-dependencies/snoopy-filter
|
||||
mocks.js-dependencies/snoopy-bars
|
||||
mocks.js-dependencies/snoopy-buffer
|
||||
mocks.js-dependencies/desktop-menu
|
||||
mocks.js-dependencies/desktop-config
|
||||
mocks.js-dependencies/react-native-navigation-twopane
|
||||
mocks.js-dependencies/react-native-screens
|
||||
mocks.js-dependencies/react-native-shake
|
||||
mocks.js-dependencies/back-handler
|
||||
mocks.js-dependencies/react
|
||||
mocks.js-dependencies/react-navigation-native
|
||||
mocks.js-dependencies/react-navigation-stack
|
||||
mocks.js-dependencies/react-navigation-bottom-tabs
|
||||
mocks.js-dependencies/react-native-haptic-feedback
|
||||
mocks.js-dependencies/mock
|
||||
quo.previews.main/init
|
||||
legacy.status-im.chat.models.message-list-test/descending-range
|
||||
legacy.status-im.chat.models.message-list-test/random-range
|
||||
legacy.status-im.ethereum.eip165/supports?
|
||||
legacy.status-im.utils.hex/valid-hex?
|
||||
legacy.status-im.multiaccounts.core/chat-send?
|
||||
legacy.status-im.hardwallet.simulated-keycard/install-cash-applet
|
||||
legacy.status-im.hardwallet.simulated-keycard/sign-typed-data
|
||||
legacy.status-im.utils.core/safe-read-message-content
|
||||
legacy.status-im.ui.components.react/native-modules
|
||||
legacy.status-im.ui.components.react/progress-bar
|
||||
react-native.fs/move-file
|
||||
react-native.fs/read-dir
|
||||
react-native.fs/mkdir
|
||||
react-native.fs/unlink
|
||||
react-native.fs/file-exists?
|
||||
legacy.status-im.ui.components.colors/white
|
||||
legacy.status-im.ui.components.colors/black
|
||||
legacy.status-im.ui.components.core/animated-header
|
||||
legacy.status-im.ui.components.core/safe-area-provider
|
||||
legacy.status-im.ui.components.core/safe-area-consumer
|
||||
legacy.status-im.ui.components.core/safe-area-view
|
||||
legacy.status-im.utils.universal-links.core/open!
|
||||
legacy.status-im.transport.filters.core-test/member-2
|
||||
legacy.status-im.ui.screens.chat.ttt/one-to-one-chat-description-container
|
||||
legacy.status-im.ethereum.ens/ttl
|
||||
legacy.status-im.ethereum.ens/addr-hash
|
||||
legacy.status-im.ethereum.ens/name-hash
|
||||
legacy.status-im.ethereum.ens/ABI-hash
|
||||
legacy.status-im.ethereum.ens/pubkey-hash
|
||||
legacy.status-im.network.core/get-network
|
||||
status-im.constants/desktop-content-types
|
||||
status-im.constants/blocks-per-hour
|
||||
status-im.constants/one-earth-day
|
||||
status-im.constants/left-pane-min-width
|
||||
status-im.constants/system
|
||||
status-im.constants/contact-discovery
|
||||
status-im.constants/send-transaction-failed-parse-response
|
||||
status-im.constants/send-transaction-failed-parse-params
|
||||
status-im.constants/send-transaction-no-account-selected
|
||||
status-im.constants/send-transaction-invalid-tx-sender
|
||||
status-im.constants/web3-get-logs
|
||||
status-im.constants/web3-transaction-receipt
|
||||
status-im.constants/web3-new-filter
|
||||
status-im.constants/web3-new-pending-transaction-filter
|
||||
status-im.constants/web3-new-block-filter
|
||||
status-im.constants/web3-uninstall-filter
|
||||
status-im.constants/web3-get-filter-changes
|
||||
status-im.constants/web3-shh-post
|
||||
status-im.constants/web3-shh-new-identity
|
||||
status-im.constants/web3-shh-has-identity
|
||||
status-im.constants/web3-shh-new-group
|
||||
status-im.constants/web3-shh-add-to-group
|
||||
status-im.constants/web3-shh-new-filter
|
||||
status-im.constants/web3-shh-uninstall-filter
|
||||
status-im.constants/web3-shh-get-filter-changes
|
||||
status-im.constants/web3-shh-get-messages
|
||||
status-im.constants/status-create-address
|
||||
status-im.constants/event-transfer-hash
|
||||
status-im.constants/regx-rtl-characters
|
||||
status-im.constants/desktop-msg-chars-hard-limit
|
||||
status-im.constants/debug-metrics
|
||||
status-im.constants/scan-qr-code
|
||||
status-im.constants/ipfs-proto-code
|
||||
status-im.constants/swarm-proto-code
|
||||
legacy.status-im.multiaccounts.update.publisher/publish-update!
|
||||
legacy.status-im.utils.async/task-queue
|
||||
legacy.status-im.utils.async/async-periodic-run!
|
||||
legacy.status-im.desktop.core/app-root
|
||||
legacy.status-im.desktop.core/init
|
||||
legacy.status-im.chat.models-test/test-db
|
||||
legacy.status-im.ui.components.spacing/padding-vertical
|
||||
legacy.status-im.utils.money/percent-change
|
||||
utils.debounce/clear-all
|
||||
legacy.status-im.transport.db/create-chat
|
||||
legacy.status-im.utils.priority-map/priority-map
|
||||
legacy.status-im.utils.priority-map/priority-map-by
|
||||
legacy.status-im.utils.priority-map/priority-map-keyfn
|
||||
legacy.status-im.utils.priority-map/empty-message-map
|
||||
legacy.status-im.wallet.choose-recipient.core/use-default-eth-gas
|
||||
legacy.status-im.ui.components.animation/decay
|
||||
legacy.status-im.ui.components.animation/remove-all-listeners
|
||||
legacy.status-im.ui.components.animation/stop-animation
|
||||
legacy.status-im.ui.components.animation/animated
|
||||
legacy.status-im.ui.components.animation/add
|
||||
legacy.status-im.ui.components.animation/subtract
|
||||
legacy.status-im.ui.components.animation/get-layout
|
||||
legacy.status-im.wallet.transactions-test/uri-query-data
|
||||
legacy.status-im.utils.name/shortened-name
|
||||
legacy.status-im.ui.components.button.haptic/trigger
|
||||
legacy.status-im.contact.db/filter-dapps
|
||||
legacy.status-im.contact.db/filter-group-contacts
|
||||
legacy.status-im.contact.db/legacy-pending?
|
||||
legacy.status-im.utils.transducers-test/preview-call-1
|
||||
legacy.status-im.utils.transducers-test/preview-call-2
|
||||
legacy.status-im.utils.types/to-string
|
||||
legacy.status-im.chat.db/datemark?
|
||||
legacy.status-im.chat.db/gap?
|
||||
legacy.status-im.chat.db/map->sorted-seq
|
||||
legacy.status-im.utils.snoopy/status-module-filter
|
||||
legacy.status-im.utils.snoopy/websocket-filter
|
||||
legacy.status-im.utils.snoopy/touches-filter
|
||||
legacy.status-im.utils.snoopy/native-animation-filter
|
||||
legacy.status-im.utils.snoopy/keyboard-observer-filter
|
||||
legacy.status-im.utils.multihash/hex
|
||||
legacy.status-im.utils.multihash/decode-array
|
||||
+28
-3
@@ -4,7 +4,7 @@
|
||||
legacy.status-im.utils.views/letsubs clojure.core/let
|
||||
reagent.core/with-let clojure.core/let
|
||||
legacy.status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||
utils.re-frame/defn clojure.core/defn
|
||||
quo.react/with-deps-check clojure.core/fn
|
||||
quo.previews.preview/list-comp clojure.core/for
|
||||
legacy.status-im.utils.styles/def clojure.core/def
|
||||
@@ -13,7 +13,29 @@
|
||||
test-helpers.unit/deftest-event clojure.core/defn
|
||||
|
||||
taoensso.tufte/defnp clojure.core/defn}
|
||||
:linters {:case-duplicate-test {:level :error}
|
||||
:linters {:clojure-lsp/unused-public-var {:exclude-when-defined-by #{utils.re-frame/defn}
|
||||
:exclude #{
|
||||
;; even if we are not
|
||||
;; using color now, we
|
||||
;; will need it later
|
||||
quo.foundations.colors
|
||||
|
||||
;; same for funcs from
|
||||
;; native-module
|
||||
native-module.core
|
||||
|
||||
;; some funcs used
|
||||
;; temporarily during
|
||||
;; development
|
||||
test-helpers.component
|
||||
test-helpers.unit
|
||||
|
||||
;; not sure if unused
|
||||
;; functions here should
|
||||
;; be removed:
|
||||
keycard.keycard
|
||||
react-native.fs}}
|
||||
:case-duplicate-test {:level :error}
|
||||
:case-quoted-test {:level :error}
|
||||
:case-symbol-test {:level :error}
|
||||
:clj-kondo-config {:level :error}
|
||||
@@ -40,7 +62,8 @@
|
||||
:equals-true {:level :error}
|
||||
:inline-def {:level :error}
|
||||
:invalid-arity {:skip-args [legacy.status-im.utils.fx/defn
|
||||
utils.re-frame/defn]}
|
||||
utils.re-frame/defn
|
||||
utils.re-frame/merge]}
|
||||
:loop-without-recur {:level :error}
|
||||
:minus-one {:level :error}
|
||||
:misplaced-docstring {:level :error}
|
||||
@@ -53,6 +76,8 @@
|
||||
:redundant-do {:level :error}
|
||||
:redundant-let {:level :error}
|
||||
:refer-all {:level :error}
|
||||
;; ignore error in config itself saying that `:shadowed-fn-param` is unknown
|
||||
#_{:clj-kondo/ignore [:clj-kondo-config]}
|
||||
:shadowed-fn-param {:level :error}
|
||||
:shadowed-var {:level :error
|
||||
;; We temporarily use :include to define an
|
||||
|
||||
@@ -36,3 +36,5 @@ SHOW_NOT_IMPLEMENTED_FEATURES=0
|
||||
ENABLE_ALERT_BANNER=0
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
API_LOGGING_ENABLED=1
|
||||
SENTRY_ENABLED=0
|
||||
SENTRY_ENVIRONMENT=ci-main
|
||||
|
||||
@@ -40,3 +40,5 @@ ENABLE_ALERT_BANNER=0
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
MOBILE_DATA_SYNCING_TOGGLE_ENABLE=0
|
||||
API_LOGGING_ENABLED=1
|
||||
SENTRY_ENABLED=0
|
||||
SENTRY_ENVIRONMENT=ci-main
|
||||
|
||||
@@ -37,3 +37,6 @@ TEST_NETWORKS_ENABLED=1
|
||||
ENABLE_ALERT_BANNER=1
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
API_LOGGING_ENABLED=1
|
||||
SENTRY_ENABLED=0
|
||||
SENTRY_ENVIRONMENT=ci-main
|
||||
GOOGLE_FREE=0
|
||||
|
||||
+4
-2
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -23,4 +23,6 @@ FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
TEST_NETWORKS_ENABLED=0
|
||||
ENABLE_ALERT_BANNER=1
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
API_LOGGING_ENABLED=0
|
||||
API_LOGGING_ENABLED=1
|
||||
SENTRY_ENABLED=1
|
||||
SENTRY_ENVIRONMENT=ci-nightly
|
||||
|
||||
+3
-1
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=0
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=
|
||||
LOG_LEVEL=error
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
MAINNET_WARNING_ENABLED=1
|
||||
PFS_ENCRYPTION_ENABLED=1
|
||||
@@ -21,3 +21,5 @@ TEST_NETWORKS_ENABLED=0
|
||||
STATUS_PROXY_STAGE_NAME=prod
|
||||
FLAG_WALLET_CONNECT_ENABLED=1
|
||||
API_LOGGING_ENABLED=0
|
||||
SENTRY_ENABLED=1
|
||||
SENTRY_ENVIRONMENT=production
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
[comment]: # (Please replace ... with your information. Remove < and >)
|
||||
[comment]: # (To auto-close issue on merge, please insert the related issue number after # i.e fixes #566)
|
||||
|
||||
If you submit PR for issue with bounty then write here Fixes #NN where NN is issue number
|
||||
|
||||
*otherwise*
|
||||
|
||||
fixes #...
|
||||
|
||||
### Summary
|
||||
|
||||
## Summary
|
||||
[comment]: # (Summarise the problem and how the pull request solves it)
|
||||
...
|
||||
|
||||
<!-- (Optional, remove if no changes to documentation) -->
|
||||
Documentation change PR (review please): https://github.com/status-im/status.im/pull/xxx
|
||||
## Review notes
|
||||
[comment]: # (Optional. Specify if something in particular should be looked at, or ignored, during review)
|
||||
|
||||
### Review notes
|
||||
<!-- (Optional. Specify if something in particular should be looked at, or ignored, during review) -->
|
||||
## Testing notes
|
||||
[comment]: # (Optional)
|
||||
|
||||
### Testing notes
|
||||
<!-- (Optional) -->
|
||||
|
||||
#### Platforms
|
||||
<!-- (Optional. Specify which platforms should be tested) -->
|
||||
### Platforms
|
||||
[comment]: # (Optional. Specify which platforms should be tested)
|
||||
|
||||
- Android
|
||||
- iOS
|
||||
- macOS
|
||||
- Linux
|
||||
- Windows
|
||||
|
||||
#### Areas that maybe impacted
|
||||
<!-- (Optional. Specify if some specific areas has to be tested, for example 1-1 chats) -->
|
||||
### Areas that may be impacted
|
||||
[comment]: # (Optional. Specify if some specific areas need to be tested, such as 1-1 chats)
|
||||
|
||||
##### Functional
|
||||
#### Functional
|
||||
|
||||
- 1-1 chats
|
||||
- public chats
|
||||
@@ -48,32 +35,27 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
|
||||
- fleet
|
||||
- bootnodes
|
||||
|
||||
##### Non-functional
|
||||
#### Non-functional
|
||||
|
||||
- battery performance
|
||||
- CPU performance / speed of the app
|
||||
- network consumption
|
||||
|
||||
### Steps to test
|
||||
<!-- (Specify exact steps to test if there are such) -->
|
||||
## Steps to test
|
||||
[comment]: # (Specify exact steps to test if there are such)
|
||||
|
||||
- Open Status
|
||||
- ...
|
||||
- Step 3, etc.
|
||||
|
||||
<!-- (PRs will only be accepted if squashed into single commit.) -->
|
||||
|
||||
### Before and after screenshots comparison
|
||||
[comment]: # (Can be ready or wip)
|
||||
status: ready
|
||||
|
||||
| Figma (if available) | iOS (if available) | Android (if available)
|
||||
| --- | --- | --- |
|
||||
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
|
||||
|
||||
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*.
|
||||
- Specify potentially impacted user flows in _Areas that may be impacted*.
|
||||
- Ensure that _Steps to test_ is filled in.
|
||||
|
||||
### Risk
|
||||
|
||||
@@ -43,8 +43,6 @@ export NODE_OPTIONS += --openssl-legacy-provider
|
||||
# The path can be anything, but home is usually safest.
|
||||
export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
|
||||
# Our custom config is located in nix/nix.conf
|
||||
export NIX_USER_CONF_FILES = $(PWD)/nix/nix.conf
|
||||
# Location of symlinks to derivations that should not be garbage collected
|
||||
export _NIX_GCROOTS = ./.nix-gcroots
|
||||
# Defines which variables will be kept for Nix pure shell, use semicolon as divider
|
||||
@@ -211,7 +209,9 @@ build-fdroid: export BUILD_ENV = prod
|
||||
build-fdroid: export BUILD_TYPE = release
|
||||
build-fdroid: export ANDROID_ABI_SPLIT = false
|
||||
build-fdroid: export ANDROID_ABI_INCLUDE = armeabi-v7a;arm64-v8a;x86;x86_64
|
||||
build-fdroid: export ANDROID_STORE = fdroid
|
||||
build-fdroid: ##@build Build release for F-Droid
|
||||
@scripts/google-free.sh
|
||||
@scripts/build-android.sh
|
||||
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
@@ -269,9 +269,11 @@ run-metro: export TARGET := clojure
|
||||
run-metro: ##@run Start Metro to build React Native changes
|
||||
@scripts/run-metro.sh
|
||||
|
||||
export RE_FRISK_PORT ?= 4567
|
||||
|
||||
run-re-frisk: export TARGET := clojure
|
||||
run-re-frisk: ##@run Start re-frisk server
|
||||
yarn shadow-cljs run re-frisk-remote.core/start
|
||||
yarn shadow-cljs run re-frisk-remote.core/start ${RE_FRISK_PORT}
|
||||
|
||||
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
||||
run-android: export TARGET := android
|
||||
@@ -445,7 +447,7 @@ android-ports: export RCT_METRO_PORT ?= 8081
|
||||
android-ports: ##@other Add proxies to Android Device/Simulator
|
||||
adb reverse tcp:$(RCT_METRO_PORT) tcp:$(RCT_METRO_PORT) && \
|
||||
adb reverse tcp:3449 tcp:3449 && \
|
||||
adb reverse tcp:4567 tcp:4567 && \
|
||||
adb reverse tcp:$(RE_FRISK_PORT) tcp:$(RE_FRISK_PORT) && \
|
||||
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
|
||||
adb forward tcp:5561 tcp:5561
|
||||
|
||||
|
||||
@@ -143,6 +143,10 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_17
|
||||
}
|
||||
// Disable default lint checks to remove redundant lintVitalReportRelease task
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
|
||||
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
|
||||
externalNativeBuild {
|
||||
@@ -335,3 +339,8 @@ task hemroidBuild(type: Exec) {
|
||||
preBuild.dependsOn hemroidBuild
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
def googleServicesConfigFile = "./googleServices.gradle";
|
||||
if (project.file(googleServicesConfigFile).exists()) {
|
||||
apply from: file(googleServicesConfigFile)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "854811651919",
|
||||
"firebase_url": "https://status-react-app.firebaseio.com",
|
||||
"project_id": "status-react-app",
|
||||
"storage_bucket": "status-react-app.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:854811651919:android:11ee7444ded8a00a",
|
||||
"android_client_info": {
|
||||
"package_name": "im.status.ethereum"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAOF4W1j8GYeXzzVKRfNKlXywD6bx0rJtQ"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "854811651919-30s20e3l0me0ins0vc4185jbnj7ja49o.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "im.status.ethereum"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:854811651919:android:15dbe4af1e06ca3e005f3a",
|
||||
"android_client_info": {
|
||||
"package_name": "im.status.ethereum.debug"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAOF4W1j8GYeXzzVKRfNKlXywD6bx0rJtQ"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "854811651919-30s20e3l0me0ins0vc4185jbnj7ja49o.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "im.status.ethereum"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:854811651919:android:1d0d69fe8c1bb89b005f3a",
|
||||
"android_client_info": {
|
||||
"package_name": "im.status.ethereum.pr"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAOF4W1j8GYeXzzVKRfNKlXywD6bx0rJtQ"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "854811651919-gua52csicclb5p9gr4eeu33ukk0aaphj.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
},
|
||||
{
|
||||
"client_id": "854811651919-30s20e3l0me0ins0vc4185jbnj7ja49o.apps.googleusercontent.com",
|
||||
"client_type": 2,
|
||||
"ios_info": {
|
||||
"bundle_id": "im.status.ethereum"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Exclude google library so we can publish to external android stores
|
||||
*/
|
||||
|
||||
def googleFree = project.env.get("GOOGLE_FREE", 0) == '1'
|
||||
|
||||
if (!googleFree) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
if (googleFree) {
|
||||
implementation(project(':react-native-firebase_app')) {
|
||||
exclude group: 'com.google.firebase'
|
||||
exclude group: 'com.google.gms'
|
||||
}
|
||||
|
||||
implementation(project(':react-native-firebase_messaging')) {
|
||||
exclude group: 'com.google.firebase'
|
||||
exclude group: 'com.google.gms'
|
||||
}
|
||||
} else {
|
||||
implementation 'com.google.firebase:firebase-messaging:24.1.0'
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,12 @@
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_provider_paths" />
|
||||
</provider>
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/notification_icon" />
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_color"
|
||||
android:resource="@color/notification_icon_color" tools:replace="android:resource" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package im.status.ethereum;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/** @author Kevin Kowalewski */
|
||||
public class RootUtil {
|
||||
|
||||
public static boolean isDeviceRooted() {
|
||||
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
|
||||
}
|
||||
|
||||
private static boolean checkRootMethod1() {
|
||||
String buildTags = android.os.Build.TAGS;
|
||||
return buildTags != null && buildTags.contains("test-keys");
|
||||
}
|
||||
|
||||
private static boolean checkRootMethod2() {
|
||||
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
|
||||
"/system/bin/failsafe/su", "/data/local/su" };
|
||||
for (String path : paths) {
|
||||
if (new File(path).exists()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkRootMethod3() {
|
||||
Process process = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
return in.readLine() != null;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
} finally {
|
||||
if (process != null) process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package im.status.ethereum
|
||||
|
||||
import android.os.Build
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
|
||||
object RootUtil {
|
||||
|
||||
fun isDeviceRooted(): Boolean =
|
||||
checkRootMethod1() || checkRootMethod2() || checkRootMethod3()
|
||||
|
||||
private fun checkRootMethod1(): Boolean =
|
||||
Build.TAGS?.contains("test-keys") ?: false
|
||||
|
||||
private fun checkRootMethod2(): Boolean {
|
||||
val paths = arrayOf(
|
||||
"/system/app/Superuser.apk",
|
||||
"/sbin/su",
|
||||
"/system/bin/su",
|
||||
"/system/xbin/su",
|
||||
"/data/local/xbin/su",
|
||||
"/data/local/bin/su",
|
||||
"/system/sd/xbin/su",
|
||||
"/system/bin/failsafe/su",
|
||||
"/data/local/su"
|
||||
)
|
||||
return paths.any { File(it).exists() }
|
||||
}
|
||||
|
||||
private fun checkRootMethod3(): Boolean {
|
||||
var process: Process? = null
|
||||
return try {
|
||||
process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
|
||||
BufferedReader(InputStreamReader(process.inputStream)).readLine() != null
|
||||
} catch (t: Throwable) {
|
||||
false
|
||||
} finally {
|
||||
process?.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,5 @@
|
||||
<color name="alert_text">#000000</color>
|
||||
<color name="splash_background">#09101C</color>
|
||||
<color name="splash_status_bar_color">#ffffff</color>
|
||||
<color name="notification_icon_color">#4360DF</color>
|
||||
</resources>
|
||||
|
||||
@@ -31,6 +31,7 @@ buildscript {
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
||||
classpath("com.google.gms:google-services:4.4.2")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.19' }
|
||||
agent { label 'linux && x86_64 && nix-2.24' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
@@ -41,6 +41,7 @@ pipeline {
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
SENTRY_PRODUCTION = "${utils.isReleaseBuild() ? 'true' : 'false'}"
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
@@ -134,4 +134,3 @@ def updateBucketJSON(urls, fileName) {
|
||||
writeFile(file: filePath, text: contentJson)
|
||||
return s5cmd.upload(filePath)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+3
-2
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos && arm64 && nix-2.19 && xcode-15.1' }
|
||||
agent { label 'macos && arm64 && nix-2.24 && xcode-16.2' }
|
||||
|
||||
parameters {
|
||||
string(
|
||||
@@ -41,6 +41,7 @@ pipeline {
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
BUNDLE_PATH = "${HOME}/.bundle"
|
||||
SENTRY_PRODUCTION = "${utils.isReleaseBuild() ? 'true' : 'false'}"
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux && x86_64 && nix-2.19' }
|
||||
agent { label 'linux && x86_64 && nix-2.24' }
|
||||
|
||||
options {
|
||||
timestamps()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -73,9 +73,9 @@ pipeline {
|
||||
passwordVariable: 'TESTRAIL_PASS'
|
||||
),
|
||||
usernamePassword(
|
||||
credentialsId: 'sauce-labs-api',
|
||||
usernameVariable: 'SAUCE_USERNAME',
|
||||
passwordVariable: 'SAUCE_ACCESS_KEY'
|
||||
credentialsId: 'lambda-test-api',
|
||||
usernameVariable: 'LAMBDA_TEST_USERNAME',
|
||||
passwordVariable: 'LAMBDA_TEST_ACCESS_KEY'
|
||||
),
|
||||
string(
|
||||
credentialsId: 'etherscan-api-key',
|
||||
@@ -95,8 +95,7 @@ pipeline {
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 8 \
|
||||
--rerun_count=2 \
|
||||
--numprocesses 9 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m \"nightly\" \
|
||||
@@ -110,21 +109,6 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
sauce('sauce-labs-cred') {
|
||||
saucePublisher()
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
script {
|
||||
junit(
|
||||
testDataPublishers: [[$class: 'SauceOnDemandReportPublisher', jobVisibility: 'public']],
|
||||
testResults: 'test/appium/tests/*.xml'
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup {
|
||||
sh 'make purge'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
|
||||
@@ -111,9 +111,9 @@ pipeline {
|
||||
passwordVariable: 'TESTRAIL_PASS'
|
||||
),
|
||||
usernamePassword(
|
||||
credentialsId: 'sauce-labs-api',
|
||||
usernameVariable: 'SAUCE_USERNAME',
|
||||
passwordVariable: 'SAUCE_ACCESS_KEY'
|
||||
credentialsId: 'lambda-test-api',
|
||||
usernameVariable: 'LAMBDA_TEST_USERNAME',
|
||||
passwordVariable: 'LAMBDA_TEST_ACCESS_KEY'
|
||||
),
|
||||
string(
|
||||
credentialsId: 'etherscan-api-key',
|
||||
@@ -133,8 +133,7 @@ pipeline {
|
||||
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
|
||||
sh """
|
||||
python3 -m pytest \
|
||||
--numprocesses 8 \
|
||||
--rerun_count=2 \
|
||||
--numprocesses 9 \
|
||||
--testrail_report=True \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path} \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
@@ -109,10 +109,19 @@ pipeline {
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
sshagent(credentials: ['nix-cache-ssh']) {
|
||||
nix.shell("""
|
||||
nix.shell(
|
||||
"""
|
||||
find /nix/store/ -mindepth 1 -maxdepth 1 -type d \
|
||||
-not -name '*.links' -and -not -name '*-status-mobile-*' \
|
||||
| xargs nix copy --to ${NIX_SSH_REMOTE}
|
||||
-not -name "*.links" -and -not -name "*-status-mobile-*" \
|
||||
-and -not -name "tmp-*" \
|
||||
-print0 | xargs -0 nix-store -qR | sort -u > "${WORKSPACE_TMP}"/store-paths.txt
|
||||
""",
|
||||
pure: false
|
||||
)
|
||||
nix.shell(
|
||||
"""
|
||||
nix-store --export < "${WORKSPACE_TMP}"/store-paths.txt | \\
|
||||
ssh ${env.NIX_SSHOPTS} ${params.NIX_CACHE_USER}@${params.NIX_CACHE_HOST} ${env.NIX_STORE_CMD} --import
|
||||
""",
|
||||
pure: false
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.20'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- [Patching](patching.md)
|
||||
- [Creating a pixel perfect UI](pixel-perfection.md)
|
||||
- [Contributing to status-go](status-go-changes.md)
|
||||
- [Status Backend Server](use-status-backend-server.md)
|
||||
- [Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf))
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -127,6 +127,71 @@ You can provide `--storage-opt size=30G` flag if Docker complains about running
|
||||
|
||||
You should also run `lint` and `rewritemeta` for the App ID to verify and fix the YAML metadata formatting.
|
||||
|
||||
# Scanning Builds Locally
|
||||
|
||||
Based on the documentation provided here: https://gitlab.com/fdroid/wiki/-/wikis/Tips-for-fdroiddata-contributors/Setting-up-app-submission-development-environment-locally
|
||||
|
||||
We can locally scan our source code and pre-built APKS by using the FDroid CLI tool. We can prepare a FDroid environment by
|
||||
following [the steps mentioned in these instructions](https://gitlab.com/fdroid/wiki/-/wikis/Tips-for-fdroiddata-contributors/Setting-up-app-submission-development-environment-locally).
|
||||
* Note, at the time of writing (March 2025), the easiest way to follow these instructions involved:
|
||||
* Creating a new empty directory outside of the status-mobile repository.
|
||||
* For this example, let's refer to this directory as `status-fdroid-server`
|
||||
* Then git cloning the two referenced git repos inside the `status-fdroid-server` directory:
|
||||
```shell
|
||||
git clone https://gitlab.com/fdroid/fdroiddata.git --depth=1
|
||||
git clone https://gitlab.com/fdroid/fdroidserver.git --depth=1
|
||||
```
|
||||
* Then create a subdirectory inside `status-fdroid-server` named `apks`
|
||||
* Then create a subdirectory inside `status-fdroid-server` named `scripts`
|
||||
* Create a file inside the `scripts` folder named `env.sh`
|
||||
```shell
|
||||
source /etc/profile.d/bsenv.sh
|
||||
export GRADLE_USER_HOME=$home_vagrant/.gradle
|
||||
export fdroid="sudo --preserve-env --user vagrant
|
||||
env PATH=$fdroidserver:$PATH
|
||||
env PYTHONPATH=$fdroidserver:$fdroidserver/examples
|
||||
env PYTHONUNBUFFERED=true
|
||||
env TERM=$TERM
|
||||
env HOME=$home_vagrant
|
||||
fdroid"
|
||||
|
||||
export build=im.status.ethereum
|
||||
```
|
||||
* Create a file inside the `scripts` folder named `prep.sh`
|
||||
```shell
|
||||
apt-get update && apt-get install -y make xz-utils
|
||||
```
|
||||
* Create a file inside the `scripts` folder named `run.sh`
|
||||
```shell
|
||||
docker run --rm -i -t --privileged --pid=host --entrypoint "/bin/bash" \
|
||||
-v ${ANDROID_SDK_ROOT}:/opt/android-sdk:Z \
|
||||
-v $(pwd)/fdroidserver:/home/vagrant/fdroidserver:Z \
|
||||
-v $(pwd)/scripts:/scripts:z \
|
||||
-v $(pwd)/fdroiddata:/build:z \
|
||||
-v $(pwd)/apks:/apks:z \
|
||||
registry.gitlab.com/fdroid/fdroidserver:buildserver
|
||||
```
|
||||
* Create a file inside the `scripts` folder named `latest-version-code.sh`
|
||||
```shell
|
||||
prefix="versionCode: "
|
||||
resultLine=$(grep $prefix ./metadata/$build.yml | tail -n 1)
|
||||
echo $resultLine | sed -e "s/^$prefix//"
|
||||
```
|
||||
* Then inside a terminal shell run the following command:
|
||||
* `env ANDROID_SDK_ROOT=<insert sdk directory> sh scripts/run.sh`
|
||||
* Ensure you replace `<insert sdk directory>` with the path to Android SDK folder.
|
||||
* On macOS, the value could be: `$HOME/Library/Android/sdk`
|
||||
* Once inside the Docker shell environment run the following commands:
|
||||
* `sh /scripts/prep.sh`
|
||||
* This command should install `xz` utils packages for installing the Nix package manager.
|
||||
* `source /scripts/env.sh`
|
||||
* This command should populate the Docker shell environment with the `$fdroid` command.
|
||||
* Next we can run `cd /build` to enter the `fdroiddata` directory that has been mounted inside the docker environment.
|
||||
* And now we can run `$fdroid scanner $build:$(sh /scripts/latest-version-code.sh)` to scan the latest version of the status app that has been registered in the `fdroiddata/metadata/im.status.ethereum.yml` file.
|
||||
* Alternatively, we can also copy an APK into the `apks` folder and run `$fdroid scanner /apks/<insert-apk-file-name>`.
|
||||
* Ensure that you replace the `<insert-apk-file-name>` with the correct name of the pre-built APK.
|
||||
* For example, after running `make release-fdroid`, you can copy the `app-arm64-v8a-release-unsigned.apk` file into the `apks` folder and run `$fdroid scanner /apks/app-arm64-v8arelease-unsigned.apk` inside the docker shell environment.
|
||||
|
||||
# Details
|
||||
|
||||
The original research was done in [#8512](https://github.com/status-im/status-mobile/issues/8512).
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: محفظة تشفير اجتماعية
|
||||
Status: محفظة إيثريوم كريبتو
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Social Crypto Wallet
|
||||
Status: Ethereum Crypto Wallet
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Billetera social cripto
|
||||
Status: Billetera Ethereum
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status : Portef. crypto social
|
||||
Status: Portefeuille Ethereum
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: ソーシャル クリプト ウォレット
|
||||
Status: イーサリアム クリプト ウォレット
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: 소셜 크립토 지갑
|
||||
Status: 이더리움 크립토 지갑
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Carteira social cripto
|
||||
Status: Carteira Ethereum
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Криптокошелек
|
||||
Status: Ethereum Криптокошелек
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Sosyal Kripto Cüzdanı
|
||||
Status Ethereum Kripto Cüzdanı
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: Криптогаманець
|
||||
Status Ethereum Криптогаманець
|
||||
|
||||
@@ -1 +1 @@
|
||||
Status: 可以社交的加密货币钱包
|
||||
Status: 以太坊加密钱包
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyAm5D6giymR_2llh-8SbCRL3oPxX_v3EZs</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>854811651919</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>im.status.ethereum</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>status-react-app</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>status-react-app.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:854811651919:ios:11ee7444ded8a00a</string>
|
||||
<key>DATABASE_URL</key>
|
||||
<string>https://status-react-app.firebaseio.com</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -64,6 +64,9 @@ abstract_target 'Status' do
|
||||
pod "Keycard", git: "https://github.com/status-im/Keycard.swift.git", tag: '3.1.1'
|
||||
pod 'secp256k1', git: "https://github.com/status-im/secp256k1.swift.git", submodules: true
|
||||
|
||||
pod 'FirebaseCore', :modular_headers => true
|
||||
pod 'GoogleUtilities', :modular_headers => true
|
||||
|
||||
target 'StatusIm' do
|
||||
|
||||
target 'StatusImTests' do
|
||||
|
||||
+137
-20
@@ -11,8 +11,78 @@ PODS:
|
||||
- React-Core (= 0.73.5)
|
||||
- React-jsi (= 0.73.5)
|
||||
- ReactCommon/turbomodule/core (= 0.73.5)
|
||||
- Firebase/CoreOnly (11.7.0):
|
||||
- FirebaseCore (~> 11.7.0)
|
||||
- Firebase/Messaging (11.7.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 11.7.0)
|
||||
- FirebaseCore (11.7.0):
|
||||
- FirebaseCoreInternal (~> 11.7.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/Logger (~> 8.0)
|
||||
- FirebaseCoreExtension (11.7.0):
|
||||
- FirebaseCore (~> 11.7.0)
|
||||
- FirebaseCoreInternal (11.7.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 8.0)"
|
||||
- FirebaseInstallations (11.7.0):
|
||||
- FirebaseCore (~> 11.7.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- FirebaseMessaging (11.7.0):
|
||||
- FirebaseCore (~> 11.7.0)
|
||||
- FirebaseInstallations (~> 11.0)
|
||||
- GoogleDataTransport (~> 10.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 8.0)
|
||||
- GoogleUtilities/Reachability (~> 8.0)
|
||||
- GoogleUtilities/UserDefaults (~> 8.0)
|
||||
- nanopb (~> 3.30910.0)
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- GoogleDataTransport (10.1.0):
|
||||
- nanopb (~> 3.30910.0)
|
||||
- PromisesObjC (~> 2.4)
|
||||
- GoogleUtilities (8.0.2):
|
||||
- GoogleUtilities/AppDelegateSwizzler (= 8.0.2)
|
||||
- GoogleUtilities/Environment (= 8.0.2)
|
||||
- GoogleUtilities/Logger (= 8.0.2)
|
||||
- GoogleUtilities/MethodSwizzler (= 8.0.2)
|
||||
- GoogleUtilities/Network (= 8.0.2)
|
||||
- "GoogleUtilities/NSData+zlib (= 8.0.2)"
|
||||
- GoogleUtilities/Privacy (= 8.0.2)
|
||||
- GoogleUtilities/Reachability (= 8.0.2)
|
||||
- GoogleUtilities/SwizzlerTestHelpers (= 8.0.2)
|
||||
- GoogleUtilities/UserDefaults (= 8.0.2)
|
||||
- GoogleUtilities/AppDelegateSwizzler (8.0.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Environment (8.0.2):
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Logger (8.0.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/MethodSwizzler (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Network (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (8.0.2)":
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/Privacy (8.0.2)
|
||||
- GoogleUtilities/Reachability (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- GoogleUtilities/SwizzlerTestHelpers (8.0.2):
|
||||
- GoogleUtilities/MethodSwizzler
|
||||
- GoogleUtilities/UserDefaults (8.0.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Privacy
|
||||
- hermes-engine (0.73.5):
|
||||
- hermes-engine/Pre-built (= 0.73.5)
|
||||
- hermes-engine/Pre-built (0.73.5)
|
||||
@@ -23,15 +93,24 @@ PODS:
|
||||
- secp256k1
|
||||
- SSZipArchive
|
||||
- libevent (2.1.12)
|
||||
- libwebp (1.2.4):
|
||||
- libwebp/demux (= 1.2.4)
|
||||
- libwebp/mux (= 1.2.4)
|
||||
- libwebp/webp (= 1.2.4)
|
||||
- libwebp/demux (1.2.4):
|
||||
- libwebp (1.3.2):
|
||||
- libwebp/demux (= 1.3.2)
|
||||
- libwebp/mux (= 1.3.2)
|
||||
- libwebp/sharpyuv (= 1.3.2)
|
||||
- libwebp/webp (= 1.3.2)
|
||||
- libwebp/demux (1.3.2):
|
||||
- libwebp/webp
|
||||
- libwebp/mux (1.2.4):
|
||||
- libwebp/mux (1.3.2):
|
||||
- libwebp/demux
|
||||
- libwebp/webp (1.2.4)
|
||||
- libwebp/sharpyuv (1.3.2)
|
||||
- libwebp/webp (1.3.2):
|
||||
- libwebp/sharpyuv
|
||||
- nanopb (3.30910.0):
|
||||
- nanopb/decode (= 3.30910.0)
|
||||
- nanopb/encode (= 3.30910.0)
|
||||
- nanopb/decode (3.30910.0)
|
||||
- nanopb/encode (3.30910.0)
|
||||
- PromisesObjC (2.4.0)
|
||||
- RCT-Folly (2022.05.16.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
@@ -917,7 +996,7 @@ PODS:
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- react-native-compat (2.11.2):
|
||||
- react-native-compat (2.17.3):
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
@@ -1146,21 +1225,29 @@ PODS:
|
||||
- React-Core
|
||||
- SDWebImage (~> 5.11.1)
|
||||
- SDWebImageWebPCoder (~> 0.8.4)
|
||||
- RNFBApp (21.7.2):
|
||||
- Firebase/CoreOnly (= 11.7.0)
|
||||
- React-Core
|
||||
- RNFBMessaging (21.7.2):
|
||||
- Firebase/Messaging (= 11.7.0)
|
||||
- FirebaseCoreExtension
|
||||
- React-Core
|
||||
- RNFBApp
|
||||
- RNFS (2.16.6):
|
||||
- React
|
||||
- RNGestureHandler (2.14.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- RNImageCropPicker (0.40.0):
|
||||
- RNImageCropPicker (0.41.2):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.40.0)
|
||||
- TOCropViewController
|
||||
- RNImageCropPicker/QBImagePickerController (0.40.0):
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.41.2)
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- RNImageCropPicker/QBImagePickerController (0.41.2):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- TOCropViewController
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- RNKeychain (8.1.2):
|
||||
- React-Core
|
||||
- RNLinearGradient (3.0.0-alpha.1):
|
||||
@@ -1189,7 +1276,7 @@ PODS:
|
||||
- secp256k1 (0.1.6)
|
||||
- SocketRocket (0.6.1)
|
||||
- SSZipArchive (2.4.3)
|
||||
- TOCropViewController (2.6.1)
|
||||
- TOCropViewController (2.7.4)
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -1198,7 +1285,9 @@ DEPENDENCIES:
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- FirebaseCore
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- GoogleUtilities
|
||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||
- Keycard (from `https://github.com/status-im/Keycard.swift.git`, tag `3.1.1`)
|
||||
- libevent (~> 2.1.12)
|
||||
@@ -1272,6 +1361,8 @@ DEPENDENCIES:
|
||||
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
|
||||
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
|
||||
- RNFastImage (from `../node_modules/react-native-fast-image`)
|
||||
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
|
||||
- "RNFBMessaging (from `../node_modules/@react-native-firebase/messaging`)"
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||
@@ -1289,10 +1380,20 @@ DEPENDENCIES:
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- BigInt
|
||||
- Firebase
|
||||
- FirebaseCore
|
||||
- FirebaseCoreExtension
|
||||
- FirebaseCoreInternal
|
||||
- FirebaseInstallations
|
||||
- FirebaseMessaging
|
||||
- fmt
|
||||
- GoogleDataTransport
|
||||
- GoogleUtilities
|
||||
- HMSegmentedControl
|
||||
- libevent
|
||||
- libwebp
|
||||
- nanopb
|
||||
- PromisesObjC
|
||||
- SDWebImage
|
||||
- SDWebImageWebPCoder
|
||||
- SocketRocket
|
||||
@@ -1455,6 +1556,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-community/push-notification-ios"
|
||||
RNFastImage:
|
||||
:path: "../node_modules/react-native-fast-image"
|
||||
RNFBApp:
|
||||
:path: "../node_modules/@react-native-firebase/app"
|
||||
RNFBMessaging:
|
||||
:path: "../node_modules/@react-native-firebase/messaging"
|
||||
RNFS:
|
||||
:path: "../node_modules/react-native-fs"
|
||||
RNGestureHandler:
|
||||
@@ -1489,7 +1594,7 @@ CHECKOUT OPTIONS:
|
||||
:git: https://github.com/status-im/Keycard.swift.git
|
||||
:tag: 3.1.1
|
||||
secp256k1:
|
||||
:commit: 46a1fa30d9b8babeae85ff519050f42394ab5fcc
|
||||
:commit: 4ab977cc2b2d7319be858bcb30a5d189bb149884
|
||||
:git: https://github.com/status-im/secp256k1.swift.git
|
||||
:submodules: true
|
||||
|
||||
@@ -1500,13 +1605,23 @@ SPEC CHECKSUMS:
|
||||
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
||||
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
||||
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
||||
Firebase: a64bf6a8546e6eab54f1c715cd6151f39d2329f4
|
||||
FirebaseCore: 3227e35f4197a924206fbcdc0349325baf4f5de4
|
||||
FirebaseCoreExtension: 206c1b399f0d103055207c16f299b28e3dbd1949
|
||||
FirebaseCoreInternal: d6c17dafc8dc33614733a8b52df78fcb4394c881
|
||||
FirebaseInstallations: 9347e719c3d52d8d7b9074b2c32407dd027305e9
|
||||
FirebaseMessaging: 00ece041b71ddb52a2862ffdee73fb6e9824bd0c
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: c0eca6ffed0a6fde1965ef26dcc7bf528f052af4
|
||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: 3bd24405b9a875b3b3cf1ab1be69b5c30c5f28bc
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
|
||||
RCTRequired: 2544c0f1081a5fa12e108bb8cb40e5f4581ccd87
|
||||
RCTTypeSafety: 50efabe2b115c11ed03fbf3fd79e2f163ddb5d7c
|
||||
@@ -1533,7 +1648,7 @@ SPEC CHECKSUMS:
|
||||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: b2b140d3d65077a1d5d26be62d9415f895592344
|
||||
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
|
||||
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
|
||||
react-native-compat: fd639220cca206df6c74b95df56a1809d78ba5a3
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
|
||||
@@ -1575,9 +1690,11 @@ SPEC CHECKSUMS:
|
||||
RNCMaskedView: 71fc32d971f03b7f03d6ab6b86b730c4ee64f5b6
|
||||
RNCPushNotificationIOS: c145c6253ea016e5efeff604f2720736b4a596f7
|
||||
RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7
|
||||
RNFBApp: a5395f4df3ea5d19697bdc99f5a0400903e5fff6
|
||||
RNFBMessaging: 3a01ad804d6cef7266794b922545b03161672a27
|
||||
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||
RNGestureHandler: 15c6ef51acba34c49ff03003806cf5dd6098f383
|
||||
RNImageCropPicker: 486e2f7e2b0461ce24321f751410dce1b3b49e6d
|
||||
RNImageCropPicker: 771e2ca319d2cf92e04ebf334ece892ee9a6728f
|
||||
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
|
||||
RNLinearGradient: ccaaebce083b54180da61d992e7fa56abfe000d6
|
||||
RNPermissions: 08e619529cced22695f4b6d0efcc0a233e278903
|
||||
@@ -1590,9 +1707,9 @@ SPEC CHECKSUMS:
|
||||
secp256k1: f61d67e6fdcb85fd727acf1bf35ace6036db540c
|
||||
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7
|
||||
|
||||
PODFILE CHECKSUM: 81a66b45adddb083171ade882c343deb4faf2a8b
|
||||
PODFILE CHECKSUM: 400957dfadcde0f24ad69c3c4ec326cb0f274341
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */; };
|
||||
2BE1270E2D59242300023E5E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2BE1270D2D59242300023E5E /* GoogleService-Info.plist */; };
|
||||
2BE1270F2D59242300023E5E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2BE1270D2D59242300023E5E /* GoogleService-Info.plist */; };
|
||||
2BE127102D59242300023E5E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2BE1270D2D59242300023E5E /* GoogleService-Info.plist */; };
|
||||
2D32CCEDFF64E1C3F1FB79AF /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6081A369F49E04EC54F77E1B /* libPods-Status-StatusIm-StatusImTests.a */; };
|
||||
3870E1E692E24133A80B07DE /* Inter-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */; };
|
||||
393D26E3080B443A998F4A2F /* Inter-Italic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */; };
|
||||
@@ -116,6 +119,7 @@
|
||||
1426DF592BA248FC81D955CB /* Inter-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Regular.otf"; path = "../resources/fonts/Inter-Regular.otf"; sourceTree = "<group>"; };
|
||||
203C46547A6E99D27529A8AA /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
24F63BCFEB33B4C969305A46 /* Pods-Status-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2BE1270D2D59242300023E5E /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
344F43B59CCE090C3271FF08 /* Pods-Status-StatusIm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3A2626CE245C3F2200D5F94B /* Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dummy.swift; sourceTree = "<group>"; };
|
||||
3A6406FB24A3ADF90046ED37 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@@ -268,6 +272,7 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2BE1270D2D59242300023E5E /* GoogleService-Info.plist */,
|
||||
65F6941825780A4F00A45E76 /* Bridge.swift */,
|
||||
3AAD2AB624A3A5F10075D594 /* StatusImPR */,
|
||||
13B07FAE1A68108700A75B9A /* StatusIm */,
|
||||
@@ -483,6 +488,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2BE1270F2D59242300023E5E /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -499,6 +505,7 @@
|
||||
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */,
|
||||
3ABC7AF8245FF85900612C45 /* InterStatus-Regular.otf in Resources */,
|
||||
393D26E3080B443A998F4A2F /* Inter-Italic.otf in Resources */,
|
||||
2BE1270E2D59242300023E5E /* GoogleService-Info.plist in Resources */,
|
||||
D1786306E0184916B11F4C37 /* Inter-Medium.otf in Resources */,
|
||||
57C854A7993C47A3B1AECD32 /* Inter-MediumItalic.otf in Resources */,
|
||||
70ADBB5ECF934DCF8A0E4919 /* Inter-Regular.otf in Resources */,
|
||||
@@ -521,6 +528,7 @@
|
||||
3AAD2ACE24A3A60E0075D594 /* InterStatus-Regular.otf in Resources */,
|
||||
3AAD2ACF24A3A60E0075D594 /* Inter-Italic.otf in Resources */,
|
||||
3AAD2AD024A3A60E0075D594 /* Inter-Medium.otf in Resources */,
|
||||
2BE127102D59242300023E5E /* GoogleService-Info.plist in Resources */,
|
||||
3AAD2AD124A3A60E0075D594 /* Inter-MediumItalic.otf in Resources */,
|
||||
3AAD2AD224A3A60E0075D594 /* Inter-Regular.otf in Resources */,
|
||||
C1715FFC29C0BCE80088FA8B /* launch-icon.png in Resources */,
|
||||
@@ -572,17 +580,37 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -614,17 +642,37 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -728,17 +776,37 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -1285,17 +1353,13 @@
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
OTHER_CFLAGS = "$(inherited) ";
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
" ",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
@@ -1376,17 +1440,13 @@
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_CFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
OTHER_CFLAGS = "$(inherited) ";
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-DFOLLY_NO_CONFIG",
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
"-DFOLLY_CFG_NO_COROUTINES=1",
|
||||
" ",
|
||||
);
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import <Firebase.h>
|
||||
#import <ReactNativeNavigation/ReactNativeNavigation.h>
|
||||
|
||||
#import <asl.h>
|
||||
@@ -45,6 +46,7 @@ extern "C" NSString* StatusgoImageServerTLSCert();
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[FIRApp configure];
|
||||
|
||||
if (!self.bridge) {
|
||||
self.bridge = [self createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>remote-notification</string>
|
||||
<string>fetch</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>launch-image-universal</string>
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>remote-notification</string>
|
||||
<string>fetch</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>launch-image-universal</string>
|
||||
|
||||
+1
-1
Submodule legal-docs updated: 3943b281b0...144f64af0d
-18
@@ -203,24 +203,6 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun verify(address: String, password: String, callback: Callback) {
|
||||
val absRootDirPath = utils.getNoBackupDirectory()
|
||||
val newKeystoreDir = utils.pathCombine(absRootDirPath, "keystore")
|
||||
|
||||
val jsonParams = JSONObject()
|
||||
jsonParams.put("keyStoreDir", newKeystoreDir)
|
||||
jsonParams.put("address", address)
|
||||
jsonParams.put("password", password)
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "VerifyAccountPasswordV2",
|
||||
requestBody = jsonParams.toString(),
|
||||
statusgoFunction = { Statusgo.verifyAccountPasswordV2(jsonParams.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun verifyDatabasePassword(keyUID: String, password: String, callback: Callback) {
|
||||
val jsonParams = JSONObject()
|
||||
|
||||
-297
@@ -1,297 +0,0 @@
|
||||
package im.status.ethereum.module;
|
||||
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import android.util.Log;
|
||||
import statusgo.Statusgo;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import java.util.function.Function;
|
||||
import android.app.Activity;
|
||||
import android.view.WindowManager;
|
||||
import android.os.Build;
|
||||
import android.view.Window;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
public class EncryptionUtils extends ReactContextBaseJavaModule {
|
||||
private static final String TAG = "EncryptionUtils";
|
||||
|
||||
private ReactApplicationContext reactContext;
|
||||
private Utils utils;
|
||||
|
||||
public EncryptionUtils(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
this.utils = new Utils(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "EncryptionUtils";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
private void initKeystore(final String keyUID, final Callback callback) throws JSONException {
|
||||
Log.d(TAG, "initKeystore");
|
||||
|
||||
final String commonKeydir = this.utils.pathCombine(this.utils.getNoBackupDirectory(), "/keystore");
|
||||
final String keydir = this.utils.pathCombine(commonKeydir, keyUID);
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"InitKeystore",
|
||||
keydir,
|
||||
() -> Statusgo.initKeystore(keydir),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) throws JSONException {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("keyUID", keyUID);
|
||||
params.put("oldPassword", password);
|
||||
params.put("newPassword", newPassword);
|
||||
String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ChangeDatabasePasswordV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.changeDatabasePasswordV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String keycardUID, final String password,
|
||||
final String newPassword, final Callback callback) throws JSONException {
|
||||
final String keyStoreDir = this.utils.getKeyStorePath(keyUID);
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("keyUID", keyUID);
|
||||
params.put("account", new JSONObject(accountData));
|
||||
params.put("settings", new JSONObject(options));
|
||||
params.put("keycardUID", keycardUID);
|
||||
params.put("oldPassword", password);
|
||||
params.put("newPassword", newPassword);
|
||||
final String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
"InitKeystore",
|
||||
keyStoreDir,
|
||||
() -> Statusgo.initKeystore(keyStoreDir)
|
||||
);
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ConvertToKeycardAccountV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.convertToKeycardAccountV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeTransfer(final String to, final String value) {
|
||||
try {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("to", to);
|
||||
params.put("value", value);
|
||||
String jsonParams = params.toString();
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"EncodeTransferV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.encodeTransferV2(jsonParams)
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating JSON for encodeTransfer: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeFunctionCall(final String method, final String paramsJSON) {
|
||||
try {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("method", method);
|
||||
params.put("paramsJSON", new JSONObject(paramsJSON));
|
||||
String jsonString = params.toString();
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"EncodeFunctionCallV2",
|
||||
jsonString,
|
||||
() -> Statusgo.encodeFunctionCallV2(jsonString)
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating JSON for encodeFunctionCall: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String decodeParameters(final String decodeParamJSON) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"DecodeParameters",
|
||||
decodeParamJSON,
|
||||
() -> Statusgo.decodeParameters(decodeParamJSON)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String hexToNumber(final String hex) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToNumber",
|
||||
hex,
|
||||
() -> Statusgo.hexToNumber(hex)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String numberToHex(final String numString) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"NumberToHex",
|
||||
numString,
|
||||
() -> Statusgo.numberToHex(numString)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String sha3(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Sha3",
|
||||
str,
|
||||
() -> Statusgo.sha3(str)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String utf8ToHex(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Utf8ToHex",
|
||||
str,
|
||||
() -> Statusgo.utf8ToHex(str)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String hexToUtf8(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToUtf8",
|
||||
str,
|
||||
() -> Statusgo.hexToUtf8(str)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String serializeLegacyKey(final String publicKey) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"SerializeLegacyKey",
|
||||
publicKey,
|
||||
() -> Statusgo.serializeLegacyKey(publicKey)
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBlankPreviewFlag(final Boolean blankPreview) {
|
||||
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
|
||||
sharedPrefs.edit().putBoolean("BLANK_PREVIEW", blankPreview).commit();
|
||||
setSecureFlag();
|
||||
}
|
||||
|
||||
private void setSecureFlag() {
|
||||
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
|
||||
final boolean setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", true);
|
||||
final Activity activity = this.reactContext.getCurrentActivity();
|
||||
if (activity != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Window window = activity.getWindow();
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hashTransaction(final String txArgsJSON, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashTransaction",
|
||||
txArgsJSON,
|
||||
() -> Statusgo.hashTransaction(txArgsJSON),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hashMessage(final String message, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashMessage",
|
||||
message,
|
||||
() -> Statusgo.hashMessage(message),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void multiformatDeserializePublicKey(final String multiCodecKey, final String base58btc, final Callback callback) throws JSONException {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("key", multiCodecKey);
|
||||
params.put("outBase", base58btc);
|
||||
String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"MultiformatDeserializePublicKeyV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.multiformatDeserializePublicKeyV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void deserializeAndCompressKey(final String desktopKey, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"DeserializeAndCompressKey",
|
||||
desktopKey,
|
||||
() -> Statusgo.deserializeAndCompressKey(desktopKey),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hashTypedData(final String data, final Callback callback) throws JSONException {
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashTypedData(data), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hashTypedDataV4(final String data, final Callback callback) throws JSONException {
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashTypedDataV4(data), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void signMessage(final String rpcParams, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"SignMessage",
|
||||
rpcParams,
|
||||
() -> Statusgo.signMessage(rpcParams),
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void signTypedData(final String data, final String account, final String password, final Callback callback) throws JSONException {
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signTypedData(data, account, password), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void signTypedDataV4(final String data, final String account, final String password, final Callback callback) throws JSONException {
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signTypedDataV4(data, account, password), callback);
|
||||
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void signGroupMembership(final String content, final Callback callback) throws JSONException {
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signGroupMembership(content), callback);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
package im.status.ethereum.module
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import android.view.WindowManager
|
||||
import com.facebook.react.bridge.*
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import statusgo.Statusgo
|
||||
import java.lang.Exception
|
||||
import java.lang.RuntimeException
|
||||
|
||||
class EncryptionUtils(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||
private val utils = Utils(reactContext)
|
||||
|
||||
companion object {
|
||||
private const val TAG = "EncryptionUtils"
|
||||
}
|
||||
|
||||
override fun getName(): String = "EncryptionUtils"
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
private fun initKeystore(keyUID: String, callback: Callback) {
|
||||
Log.d(TAG, "initKeystore")
|
||||
val commonKeydir = utils.pathCombine(utils.getNoBackupDirectory(), "/keystore")
|
||||
val keydir = utils.pathCombine(commonKeydir, keyUID)
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"InitKeystore",
|
||||
keydir,
|
||||
{ Statusgo.initKeystore(keydir) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun reEncryptDbAndKeystore(keyUID: String, password: String, newPassword: String, callback: Callback) {
|
||||
val params = JSONObject().apply {
|
||||
put("keyUID", keyUID)
|
||||
put("oldPassword", password)
|
||||
put("newPassword", newPassword)
|
||||
}
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ChangeDatabasePasswordV2",
|
||||
params.toString(),
|
||||
{ Statusgo.changeDatabasePasswordV2(params.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun convertToKeycardAccount(
|
||||
keyUID: String,
|
||||
accountData: String,
|
||||
options: String,
|
||||
keycardUID: String,
|
||||
password: String,
|
||||
newPassword: String,
|
||||
callback: Callback
|
||||
) {
|
||||
val keyStoreDir = utils.getKeyStorePath(keyUID)
|
||||
val params = JSONObject().apply {
|
||||
put("keyUID", keyUID)
|
||||
put("account", JSONObject(accountData))
|
||||
put("settings", JSONObject(options))
|
||||
put("keycardUID", keycardUID)
|
||||
put("oldPassword", password)
|
||||
put("newPassword", newPassword)
|
||||
}
|
||||
val jsonParams = params.toString()
|
||||
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
"InitKeystore",
|
||||
keyStoreDir,
|
||||
{ Statusgo.initKeystore(keyStoreDir) }
|
||||
)
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ConvertToKeycardAccountV2",
|
||||
jsonParams,
|
||||
{ Statusgo.convertToKeycardAccountV2(jsonParams) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun decodeParameters(decodeParamJSON: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"DecodeParameters",
|
||||
decodeParamJSON,
|
||||
{ Statusgo.decodeParameters(decodeParamJSON) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun hexToNumber(hex: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToNumber",
|
||||
hex,
|
||||
{ Statusgo.hexToNumber(hex) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun numberToHex(numString: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"NumberToHex",
|
||||
numString,
|
||||
{ Statusgo.numberToHex(numString) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun sha3(str: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Sha3",
|
||||
str,
|
||||
{ Statusgo.sha3(str) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun utf8ToHex(str: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Utf8ToHex",
|
||||
str,
|
||||
{ Statusgo.utf8ToHex(str) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun hexToUtf8(str: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToUtf8",
|
||||
str,
|
||||
{ Statusgo.hexToUtf8(str) }
|
||||
)
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun serializeLegacyKey(publicKey: String): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"SerializeLegacyKey",
|
||||
publicKey,
|
||||
{ Statusgo.serializeLegacyKey(publicKey) }
|
||||
)
|
||||
|
||||
@ReactMethod
|
||||
fun setBlankPreviewFlag(blankPreview: Boolean) {
|
||||
PreferenceManager.getDefaultSharedPreferences(reactContext)
|
||||
.edit()
|
||||
.putBoolean("BLANK_PREVIEW", blankPreview)
|
||||
.commit()
|
||||
setSecureFlag()
|
||||
}
|
||||
|
||||
private fun setSecureFlag() {
|
||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(reactContext)
|
||||
val setSecure = sharedPrefs.getBoolean("BLANK_PREVIEW", true)
|
||||
|
||||
reactContext.currentActivity?.run {
|
||||
runOnUiThread {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun hashTransaction(txArgsJSON: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashTransaction",
|
||||
txArgsJSON,
|
||||
{ Statusgo.hashTransaction(txArgsJSON) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun hashMessage(message: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashMessage",
|
||||
message,
|
||||
{ Statusgo.hashMessage(message) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun multiformatDeserializePublicKey(multiCodecKey: String, base58btc: String, callback: Callback) {
|
||||
val params = JSONObject().apply {
|
||||
put("key", multiCodecKey)
|
||||
put("outBase", base58btc)
|
||||
}
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"MultiformatDeserializePublicKeyV2",
|
||||
params.toString(),
|
||||
{ Statusgo.multiformatDeserializePublicKeyV2(params.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun deserializeAndCompressKey(desktopKey: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"DeserializeAndCompressKey",
|
||||
desktopKey,
|
||||
{ Statusgo.deserializeAndCompressKey(desktopKey) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun hashTypedData(data: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.hashTypedData(data) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun hashTypedDataV4(data: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.hashTypedDataV4(data) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun signMessage(rpcParams: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"SignMessage",
|
||||
rpcParams,
|
||||
{ Statusgo.signMessage(rpcParams) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun signTypedData(data: String, account: String, password: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.signTypedData(data, account, password) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun signTypedDataV4(data: String, account: String, password: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.signTypedDataV4(data, account, password) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@Throws(Exception::class)
|
||||
fun signGroupMembership(content: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.signGroupMembership(content) }, callback)
|
||||
}
|
||||
}
|
||||
+10
@@ -35,6 +35,11 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
return File(pubDirectory, gethLogFileName)
|
||||
}
|
||||
|
||||
private fun getPreLoginLogFile(): File {
|
||||
val pubDirectory = utils.getPublicStorageDirectory()
|
||||
return File(pubDirectory, preLoginLogFileName)
|
||||
}
|
||||
|
||||
fun prepareLogsFile(context: Context): File? {
|
||||
val logFile = getGethLogFile()
|
||||
|
||||
@@ -156,6 +161,7 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
val statusLogFile = File(logsTempDir, statusLogFileName)
|
||||
val gethLogFile = getGethLogFile()
|
||||
val requestLogFile = getRequestLogFile()
|
||||
val preLoginLogFile = getPreLoginLogFile()
|
||||
|
||||
try {
|
||||
if (zipFile.exists() || zipFile.createNewFile()) {
|
||||
@@ -175,6 +181,9 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
if (requestLogFile.exists()) {
|
||||
filesToZip.add(requestLogFile)
|
||||
}
|
||||
if (preLoginLogFile.exists()) {
|
||||
filesToZip.add(preLoginLogFile)
|
||||
}
|
||||
val zipped = zip(filesToZip.toTypedArray(), zipFile, errorList)
|
||||
if (zipped && zipFile.exists()) {
|
||||
zipFile.setReadable(true, false)
|
||||
@@ -205,6 +214,7 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
private const val gethLogFileName = "geth.log"
|
||||
private const val statusLogFileName = "Status.log"
|
||||
private const val requestsLogFileName = "api.log"
|
||||
private const val preLoginLogFileName = "pre_login.log"
|
||||
private const val logsZipFileName = "Status-debug-logs.zip"
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -108,6 +108,15 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun intendedPanic(message: String) {
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "IntendedPanic",
|
||||
requestBody = message,
|
||||
statusgoFunction = { Statusgo.intendedPanic(message) },
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun addCentralizedMetric(request: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
package im.status.ethereum.module;
|
||||
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import android.app.Activity;
|
||||
import android.util.Log;
|
||||
import android.os.Build;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.WebStorage;
|
||||
import android.view.WindowManager;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.UIBlock;
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.content.Context;
|
||||
|
||||
public class UIHelper extends ReactContextBaseJavaModule {
|
||||
private static final String TAG = "UIHelper";
|
||||
private ReactApplicationContext reactContext;
|
||||
|
||||
public UIHelper(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "UIHelper";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setSoftInputMode(final int mode) {
|
||||
Log.d(TAG, "setSoftInputMode");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
activity.getWindow().setSoftInputMode(mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@ReactMethod
|
||||
public void clearCookies() {
|
||||
Log.d(TAG, "clearCookies");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
CookieManager.getInstance().removeAllCookies(null);
|
||||
CookieManager.getInstance().flush();
|
||||
} else {
|
||||
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(activity);
|
||||
cookieSyncManager.startSync();
|
||||
CookieManager cookieManager = CookieManager.getInstance();
|
||||
cookieManager.removeAllCookie();
|
||||
cookieManager.removeSessionCookie();
|
||||
cookieSyncManager.stopSync();
|
||||
cookieSyncManager.sync();
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void toggleWebviewDebug(final boolean val) {
|
||||
Log.d(TAG, "toggleWebviewDebug");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
WebView.setWebContentsDebuggingEnabled(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clearStorageAPIs() {
|
||||
Log.d(TAG, "clearStorageAPIs");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
WebStorage storage = WebStorage.getInstance();
|
||||
if (storage != null) {
|
||||
storage.deleteAllData();
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void resetKeyboardInputCursor(final int reactTagToReset, final int selection) {
|
||||
UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
|
||||
uiManager.addUIBlock(new UIBlock() {
|
||||
@Override
|
||||
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
|
||||
InputMethodManager imm = (InputMethodManager) getReactApplicationContext().getBaseContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
View viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset);
|
||||
imm.restartInput(viewToReset);
|
||||
try {
|
||||
EditText textView = (EditText) viewToReset;
|
||||
textView.setSelection(selection);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package im.status.ethereum.module
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.CookieSyncManager
|
||||
import android.webkit.WebStorage
|
||||
import android.webkit.WebView
|
||||
import android.widget.EditText
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||
import com.facebook.react.bridge.ReactMethod
|
||||
import com.facebook.react.uimanager.NativeViewHierarchyManager
|
||||
import com.facebook.react.uimanager.UIBlock
|
||||
import com.facebook.react.uimanager.UIManagerModule
|
||||
|
||||
class UIHelper(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||
companion object {
|
||||
private const val TAG = "UIHelper"
|
||||
}
|
||||
|
||||
override fun getName(): String = "UIHelper"
|
||||
|
||||
@ReactMethod
|
||||
fun setSoftInputMode(mode: Int) {
|
||||
Log.d(TAG, "setSoftInputMode")
|
||||
getCurrentActivity()?.run {
|
||||
runOnUiThread {
|
||||
window.setSoftInputMode(mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@ReactMethod
|
||||
fun clearCookies() {
|
||||
Log.d(TAG, "clearCookies")
|
||||
getCurrentActivity()?.let { activity ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
CookieManager.getInstance().apply {
|
||||
removeAllCookies(null)
|
||||
flush()
|
||||
}
|
||||
} else {
|
||||
CookieSyncManager.createInstance(activity).also { cookieSyncManager ->
|
||||
cookieSyncManager.startSync()
|
||||
CookieManager.getInstance().apply {
|
||||
removeAllCookie()
|
||||
removeSessionCookie()
|
||||
}
|
||||
cookieSyncManager.stopSync()
|
||||
cookieSyncManager.sync()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun toggleWebviewDebug(enabled: Boolean) {
|
||||
Log.d(TAG, "toggleWebviewDebug")
|
||||
getCurrentActivity()?.run {
|
||||
runOnUiThread {
|
||||
WebView.setWebContentsDebuggingEnabled(enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun clearStorageAPIs() {
|
||||
Log.d(TAG, "clearStorageAPIs")
|
||||
getCurrentActivity()?.let {
|
||||
WebStorage.getInstance()?.deleteAllData()
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun resetKeyboardInputCursor(reactTagToReset: Int, selection: Int) {
|
||||
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.addUIBlock(object : UIBlock {
|
||||
override fun execute(nativeViewHierarchyManager: NativeViewHierarchyManager) {
|
||||
(reactApplicationContext.baseContext.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.let { imm ->
|
||||
val viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset)
|
||||
imm.restartInput(viewToReset)
|
||||
try {
|
||||
(viewToReset as? EditText)?.setSelection(selection)
|
||||
} catch (e: Exception) {
|
||||
// Ignore exceptions during selection setting
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.app.Service;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.IBinder;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import android.os.Build;
|
||||
import im.status.ethereum.module.R;
|
||||
|
||||
public class ForegroundService extends Service {
|
||||
private static final String CHANNEL_ID = "status-service";
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent i, int flags, int startId) {
|
||||
// NOTE: recent versions of Android require the service to display
|
||||
// a sticky notification to inform the user that the service is running
|
||||
Context context = getApplicationContext();
|
||||
// Create the NotificationChannel, but only on API 26+ because
|
||||
// the NotificationChannel class is new and not in the support library
|
||||
|
||||
Intent intent = null;
|
||||
String notificationContentText = null;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationManager notificationManager =
|
||||
context.getSystemService(NotificationManager.class);
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
|
||||
context.getResources().getString(R.string.status_service),
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
channel.setShowBadge(false);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
|
||||
// Create intent that takes the user to the notification channel settings so they can hide it
|
||||
|
||||
intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
|
||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, CHANNEL_ID);
|
||||
|
||||
notificationContentText = context.getResources().getString(R.string.tap_to_hide_notification);
|
||||
|
||||
} else {
|
||||
|
||||
// For older versions of android intent takes the user to the Status app
|
||||
|
||||
Class intentClass;
|
||||
String packageName = context.getPackageName();
|
||||
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
String className = launchIntent.getComponent().getClassName();
|
||||
try {
|
||||
intentClass = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
intent = new Intent(context, intentClass);
|
||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
|
||||
notificationContentText = context.getResources().getString(R.string.keep_status_running);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||
Intent stopIntent = new Intent(PushNotificationHelper.ACTION_TAP_STOP);
|
||||
PendingIntent stopPendingIntent = PendingIntent.getBroadcast(context, 0, stopIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_stat_notify_status)
|
||||
.setContentTitle(context.getResources().getString(R.string.background_service_opened))
|
||||
.setContentText(notificationContentText)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setNumber(0)
|
||||
.addAction(R.drawable.ic_stat_notify_status,
|
||||
context.getResources().getString(R.string.stop),
|
||||
stopPendingIntent)
|
||||
.build();
|
||||
|
||||
// the id of the foreground notification MUST NOT be 0
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
|
||||
} else {
|
||||
startForeground(1, notification);
|
||||
}
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.app.Service
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.IBinder
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.provider.Settings
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import android.os.Build
|
||||
import im.status.ethereum.module.R
|
||||
|
||||
class ForegroundService : Service() {
|
||||
companion object {
|
||||
private const val CHANNEL_ID = "status-service"
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onStartCommand(i: Intent?, flags: Int, startId: Int): Int {
|
||||
// NOTE: recent versions of Android require the service to display
|
||||
// a sticky notification to inform the user that the service is running
|
||||
val context = applicationContext
|
||||
// Create the NotificationChannel, but only on API 26+ because
|
||||
// the NotificationChannel class is new and not in the support library
|
||||
|
||||
// Create notification channel for Android O and above
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val notificationManager = context.getSystemService(NotificationManager::class.java)
|
||||
val channel = NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
context.resources.getString(R.string.status_service),
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
).apply {
|
||||
setShowBadge(false)
|
||||
}
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
// Initialize intent and notification text based on Android version
|
||||
val notificationIntent = createNotificationIntent(context)
|
||||
val notificationText = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.resources.getString(R.string.tap_to_hide_notification)
|
||||
} else {
|
||||
context.resources.getString(R.string.keep_status_running)
|
||||
}
|
||||
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
notificationIntent,
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val stopIntent = Intent(PushNotificationHelper.ACTION_TAP_STOP)
|
||||
val stopPendingIntent = PendingIntent.getBroadcast(
|
||||
context,
|
||||
0,
|
||||
stopIntent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_stat_notify_status)
|
||||
.setContentTitle(context.resources.getString(R.string.background_service_opened))
|
||||
.setContentText(notificationText)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setNumber(0)
|
||||
.addAction(
|
||||
R.drawable.ic_stat_notify_status,
|
||||
context.resources.getString(R.string.stop),
|
||||
stopPendingIntent
|
||||
)
|
||||
.build()
|
||||
|
||||
// the id of the foreground notification MUST NOT be 0
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
|
||||
} else {
|
||||
startForeground(1, notification)
|
||||
}
|
||||
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
private fun createNotificationIntent(context: Context): Intent {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Create intent that takes the user to the notification channel settings
|
||||
Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
|
||||
putExtra(Settings.EXTRA_CHANNEL_ID, CHANNEL_ID)
|
||||
}
|
||||
} else {
|
||||
// For older versions of android, intent takes the user to the Status app
|
||||
val packageName = context.packageName
|
||||
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
|
||||
val className = launchIntent?.component?.className
|
||||
|
||||
try {
|
||||
val intentClass = Class.forName(className!!)
|
||||
Intent(context, intentClass).apply {
|
||||
addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
action = Intent.ACTION_VIEW
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
}
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
// Return an empty intent as fallback
|
||||
Intent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import com.facebook.react.bridge.ActivityEventListener;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import android.util.Log;
|
||||
|
||||
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
|
||||
|
||||
public class PushNotification extends ReactContextBaseJavaModule implements ActivityEventListener {
|
||||
public static final String LOG_TAG = "PushNotification";
|
||||
|
||||
private final SecureRandom mRandomNumberGenerator = new SecureRandom();
|
||||
private PushNotificationHelper pushNotificationHelper;
|
||||
private PushNotificationJsDelivery delivery;
|
||||
private ReactApplicationContext reactContext;
|
||||
private boolean started;
|
||||
|
||||
public PushNotification(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
reactContext.addActivityEventListener(this);
|
||||
Application applicationContext = (Application) reactContext.getApplicationContext();
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
pushNotificationHelper = new PushNotificationHelper(applicationContext, intentFilter);
|
||||
|
||||
delivery = new PushNotificationJsDelivery(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PushNotification";
|
||||
}
|
||||
|
||||
// removed @Override temporarily just to get it working on different versions of RN
|
||||
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
||||
onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
// removed @Override temporarily just to get it working on different versions of RN
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
// Ignored, required to implement ActivityEventListener for RN 0.33
|
||||
}
|
||||
|
||||
private Bundle getBundleFromIntent(Intent intent) {
|
||||
Bundle bundle = null;
|
||||
if (intent.hasExtra("notification")) {
|
||||
bundle = intent.getBundleExtra("notification");
|
||||
} else if (intent.hasExtra("google.message_id")) {
|
||||
bundle = new Bundle();
|
||||
|
||||
bundle.putBundle("data", intent.getExtras());
|
||||
}
|
||||
|
||||
if(null != bundle && !bundle.getBoolean("foreground", false) && !bundle.containsKey("userInteraction")) {
|
||||
bundle.putBoolean("userInteraction", true);
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
Bundle bundle = this.getBundleFromIntent(intent);
|
||||
if (bundle != null) {
|
||||
delivery.notifyNotification(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
/**
|
||||
* Creates a channel if it does not already exist. Returns whether the channel was created.
|
||||
*/
|
||||
public void createChannel(ReadableMap channelInfo, Callback callback) {
|
||||
boolean created = pushNotificationHelper.createChannel(channelInfo);
|
||||
|
||||
if(callback != null) {
|
||||
callback.invoke(created);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void presentLocalNotification(ReadableMap details) {
|
||||
if (!this.started) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle bundle = Arguments.toBundle(details);
|
||||
// If notification ID is not provided by the user, generate one at random
|
||||
if (bundle.getString("id") == null) {
|
||||
bundle.putString("id", String.valueOf(mRandomNumberGenerator.nextInt()));
|
||||
}
|
||||
|
||||
pushNotificationHelper.sendToNotificationCentre(bundle);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clearMessageNotifications(String conversationId) {
|
||||
if (this.started) {
|
||||
pushNotificationHelper.clearMessageNotifications(conversationId);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clearAllMessageNotifications() {
|
||||
pushNotificationHelper.clearAllMessageNotifications();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void enableNotifications() {
|
||||
this.started = true;
|
||||
this.pushNotificationHelper.start();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void disableNotifications() {
|
||||
if (this.started) {
|
||||
this.started = false;
|
||||
this.pushNotificationHelper.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.facebook.react.bridge.*
|
||||
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery
|
||||
import java.security.SecureRandom
|
||||
|
||||
class PushNotification(reactContext: ReactApplicationContext) :
|
||||
ReactContextBaseJavaModule(reactContext), ActivityEventListener {
|
||||
|
||||
companion object {
|
||||
const val LOG_TAG = "PushNotification"
|
||||
}
|
||||
|
||||
private val mRandomNumberGenerator = SecureRandom()
|
||||
private val pushNotificationHelper: PushNotificationHelper
|
||||
private val delivery: PushNotificationJsDelivery
|
||||
private val reactContext: ReactApplicationContext = reactContext
|
||||
private var started: Boolean = false
|
||||
|
||||
init {
|
||||
reactContext.addActivityEventListener(this)
|
||||
val applicationContext = reactContext.applicationContext as Application
|
||||
|
||||
val intentFilter = IntentFilter()
|
||||
pushNotificationHelper = PushNotificationHelper(applicationContext, intentFilter)
|
||||
|
||||
delivery = PushNotificationJsDelivery(reactContext)
|
||||
}
|
||||
|
||||
override fun getName(): String = "PushNotification"
|
||||
|
||||
// Primary implementation of ActivityEventListener interface
|
||||
override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
// Call the helper method with the correct parameter order
|
||||
handleActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
// Private helper method for handling activity results
|
||||
private fun handleActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
// Ignored, required to implement ActivityEventListener for RN 0.33
|
||||
}
|
||||
|
||||
private fun getBundleFromIntent(intent: Intent): Bundle? {
|
||||
return when {
|
||||
intent.hasExtra("notification") -> intent.getBundleExtra("notification")
|
||||
intent.hasExtra("google.message_id") -> Bundle().apply {
|
||||
putBundle("data", intent.extras)
|
||||
}
|
||||
else -> null
|
||||
}?.apply {
|
||||
if (!getBoolean("foreground", false) && !containsKey("userInteraction")) {
|
||||
putBoolean("userInteraction", true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
getBundleFromIntent(intent)?.let { bundle ->
|
||||
delivery.notifyNotification(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun createChannel(channelInfo: ReadableMap, callback: Callback?) {
|
||||
val created = pushNotificationHelper.createChannel(channelInfo)
|
||||
callback?.invoke(created)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun presentLocalNotification(details: ReadableMap) {
|
||||
if (!started) return
|
||||
|
||||
Arguments.toBundle(details)?.apply {
|
||||
// If notification ID is not provided by the user, generate one at random
|
||||
if (getString("id") == null) {
|
||||
putString("id", mRandomNumberGenerator.nextInt().toString())
|
||||
}
|
||||
pushNotificationHelper.sendToNotificationCentre(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun clearMessageNotifications(conversationId: String) {
|
||||
if (started) {
|
||||
pushNotificationHelper.clearMessageNotifications(conversationId)
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun clearAllMessageNotifications() {
|
||||
pushNotificationHelper.clearAllMessageNotifications()
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun enableNotifications() {
|
||||
started = true
|
||||
pushNotificationHelper.start()
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun disableNotifications() {
|
||||
if (started) {
|
||||
started = false
|
||||
pushNotificationHelper.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import android.os.Build;
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
|
||||
|
||||
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
|
||||
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
|
||||
|
||||
public class PushNotificationActions extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
String intentActionPrefix = context.getPackageName() + ".ACTION_";
|
||||
|
||||
Log.i(LOG_TAG, "PushNotificationBootEventReceiver loading scheduled notifications");
|
||||
|
||||
if (null == intent.getAction() || !intent.getAction().startsWith(intentActionPrefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Bundle bundle = intent.getBundleExtra("notification");
|
||||
|
||||
// Dismiss the notification popup.
|
||||
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
|
||||
int notificationID = Integer.parseInt(bundle.getString("id"));
|
||||
|
||||
boolean autoCancel = bundle.getBoolean("autoCancel", true);
|
||||
|
||||
if(autoCancel) {
|
||||
if (bundle.containsKey("tag")) {
|
||||
String tag = bundle.getString("tag");
|
||||
manager.cancel(tag, notificationID);
|
||||
} else {
|
||||
manager.cancel(notificationID);
|
||||
}
|
||||
}
|
||||
|
||||
boolean invokeApp = bundle.getBoolean("invokeApp", true);
|
||||
|
||||
// Notify the action.
|
||||
if(invokeApp) {
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
PushNotificationHelper helper = new PushNotificationHelper((Application) context.getApplicationContext(), intentFilter);
|
||||
|
||||
helper.invokeApp(bundle);
|
||||
} else {
|
||||
|
||||
// We need to run this on the main thread, as the React code assumes that is true.
|
||||
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
|
||||
// "Can't create handler inside thread that has not called Looper.prepare()"
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
// Construct and load our normal React JS code bundle
|
||||
final ReactInstanceManager mReactInstanceManager = ((ReactApplication) context.getApplicationContext()).getReactNativeHost().getReactInstanceManager();
|
||||
ReactContext context = mReactInstanceManager.getCurrentReactContext();
|
||||
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
|
||||
// If it's constructed, send a notification
|
||||
if (context != null) {
|
||||
delivery.notifyNotificationAction(bundle);
|
||||
} else {
|
||||
// Otherwise wait for construction, then send the notification
|
||||
mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
public void onReactContextInitialized(ReactContext context) {
|
||||
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
|
||||
delivery.notifyNotificationAction(bundle);
|
||||
mReactInstanceManager.removeReactInstanceEventListener(this);
|
||||
}
|
||||
});
|
||||
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
|
||||
// Construct it in the background
|
||||
mReactInstanceManager.createReactContextInBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.os.Build
|
||||
import android.app.Application
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.facebook.react.ReactApplication
|
||||
import com.facebook.react.ReactInstanceManager
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery
|
||||
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
|
||||
|
||||
/**
|
||||
* BroadcastReceiver responsible for handling push notification actions.
|
||||
* This class processes notification interactions and manages their lifecycle.
|
||||
*/
|
||||
class PushNotificationActions : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val intentActionPrefix = "${context.packageName}.ACTION_"
|
||||
|
||||
Log.i(LOG_TAG, "PushNotificationBootEventReceiver loading scheduled notifications")
|
||||
|
||||
if (intent.action == null || !intent.action!!.startsWith(intentActionPrefix)) {
|
||||
return
|
||||
}
|
||||
|
||||
val bundle = intent.getBundleExtra("notification") ?: return
|
||||
|
||||
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
val notificationID = bundle.getString("id")?.toInt() ?: return
|
||||
|
||||
// Dismiss the notification popup.
|
||||
val autoCancel = bundle.getBoolean("autoCancel", true)
|
||||
if (autoCancel) {
|
||||
bundle.getString("tag")?.let { tag ->
|
||||
manager.cancel(tag, notificationID)
|
||||
} ?: run {
|
||||
manager.cancel(notificationID)
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the action.
|
||||
val invokeApp = bundle.getBoolean("invokeApp", true)
|
||||
|
||||
if (invokeApp) {
|
||||
val intentFilter = IntentFilter()
|
||||
val helper = PushNotificationHelper(
|
||||
context.applicationContext as Application,
|
||||
intentFilter
|
||||
)
|
||||
helper.invokeApp(bundle)
|
||||
} else {
|
||||
// We need to run this on the main thread, as the React code assumes that is true.
|
||||
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
|
||||
// "Can't create handler inside thread that has not called Looper.prepare()"
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
// Construct and load our normal React JS code bundle
|
||||
val reactInstanceManager = (context.applicationContext as ReactApplication)
|
||||
.reactNativeHost
|
||||
.reactInstanceManager
|
||||
|
||||
val currentContext = reactInstanceManager.currentReactContext
|
||||
|
||||
when {
|
||||
// If context exists, deliver notification immediately
|
||||
currentContext != null -> {
|
||||
PushNotificationJsDelivery(currentContext)
|
||||
.notifyNotificationAction(bundle)
|
||||
}
|
||||
// Otherwise wait for construction, then send the notification
|
||||
else -> {
|
||||
val listener = object : ReactInstanceManager.ReactInstanceEventListener {
|
||||
override fun onReactContextInitialized(reactContext: ReactContext) {
|
||||
PushNotificationJsDelivery(reactContext)
|
||||
.notifyNotificationAction(bundle)
|
||||
reactInstanceManager.removeReactInstanceEventListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
// Add the listener and create context if needed
|
||||
reactInstanceManager.addReactInstanceEventListener(listener)
|
||||
if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
|
||||
// Construct it in the background
|
||||
reactInstanceManager.createReactContextInBackground()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-890
@@ -1,890 +0,0 @@
|
||||
// https://github.com/zo0r/react-native-push-notification/blob/bedc8f646aab67d594f291449fbfa24e07b64fe8/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java Copy-Paste with removed firebase
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningAppProcessInfo;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Application;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.Person;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import im.status.ethereum.module.R;
|
||||
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
|
||||
|
||||
public class PushNotificationHelper {
|
||||
|
||||
private Context context;
|
||||
|
||||
private static final long DEFAULT_VIBRATION = 300L;
|
||||
private static final String CHANNEL_ID = "status-im-notifications";
|
||||
public static final String ACTION_DELETE_NOTIFICATION = "im.status.ethereum.module.DELETE_NOTIFICATION";
|
||||
public static final String ACTION_TAP_STOP = "im.status.ethereum.module.TAP_STOP";
|
||||
final int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_CANCEL_CURRENT;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
|
||||
|
||||
private HashMap<String, Person> persons;
|
||||
private HashMap<String, StatusMessageGroup> messageGroups;
|
||||
|
||||
private IntentFilter intentFilter;
|
||||
|
||||
public PushNotificationHelper(Application context, IntentFilter intentFilter) {
|
||||
this.context = context;
|
||||
this.intentFilter = intentFilter;
|
||||
this.persons = new HashMap<String, Person>();
|
||||
this.messageGroups = new HashMap<String, StatusMessageGroup>();
|
||||
this.notificationManager = context.getSystemService(NotificationManager.class);
|
||||
this.registerBroadcastReceiver();
|
||||
}
|
||||
|
||||
public Intent getOpenAppIntent(String deepLink) {
|
||||
Class intentClass;
|
||||
String packageName = context.getPackageName();
|
||||
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
String className = launchIntent.getComponent().getClassName();
|
||||
try {
|
||||
intentClass = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
Intent intent = new Intent(context, intentClass);
|
||||
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
//NOTE: you might wonder, why the heck did he decide to set these flags in particular. Well,
|
||||
//the answer is a simple as it can get in the Android native development world. I noticed
|
||||
//that my initial setup was opening the app but wasn't triggering any events on the js side, like
|
||||
//the links do from the browser. So I compared both intents and noticed that the link from
|
||||
//the browser produces an intent with the flag 0x14000000. I found out that it was the following
|
||||
//flags in this link:
|
||||
//https://stackoverflow.com/questions/52390129/android-intent-setflags-issue
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
if (deepLink != null) {
|
||||
intent.setData(Uri.parse(deepLink));
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
//NOTE: we use a dynamically created BroadcastReceiver here so that we can capture
|
||||
//intents from notifications and act on them. For instance when tapping/dismissing
|
||||
//a chat notification we want to clear the chat so that next messages don't show
|
||||
//the messages that we have seen again
|
||||
private final BroadcastReceiver notificationActionReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction() == ACTION_DELETE_NOTIFICATION) {
|
||||
String groupId = intent.getExtras().getString("im.status.ethereum.groupId");
|
||||
if (groupId != null) {
|
||||
cleanGroup(groupId);
|
||||
}
|
||||
}
|
||||
if (intent.getAction() == ACTION_TAP_STOP) {
|
||||
stop();
|
||||
System.exit(0);
|
||||
}
|
||||
Log.e(LOG_TAG, "intent received: " + intent.getAction());
|
||||
}
|
||||
};
|
||||
|
||||
public void registerBroadcastReceiver() {
|
||||
this.intentFilter.addAction(ACTION_DELETE_NOTIFICATION);
|
||||
this.intentFilter.addAction(ACTION_TAP_STOP);
|
||||
context.registerReceiver(notificationActionReceiver, this.intentFilter, Context.RECEIVER_EXPORTED);
|
||||
Log.e(LOG_TAG, "Broadcast Receiver registered");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private NotificationManager notificationManager() {
|
||||
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
}
|
||||
|
||||
public void invokeApp(Bundle bundle) {
|
||||
String packageName = context.getPackageName();
|
||||
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
String className = launchIntent.getComponent().getClassName();
|
||||
|
||||
try {
|
||||
Class<?> activityClass = Class.forName(className);
|
||||
Intent activityIntent = new Intent(context, activityClass);
|
||||
|
||||
if(bundle != null) {
|
||||
activityIntent.putExtra("notification", bundle);
|
||||
}
|
||||
|
||||
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
context.startActivity(activityIntent);
|
||||
} catch(Exception e) {
|
||||
Log.e(LOG_TAG, "Class not found", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendToNotificationCentre(final Bundle bundle) {
|
||||
PushNotificationPicturesAggregator aggregator = new PushNotificationPicturesAggregator(new PushNotificationPicturesAggregator.Callback() {
|
||||
public void call(Bitmap largeIconImage, Bitmap bigPictureImage) {
|
||||
sendToNotificationCentreWithPicture(bundle, largeIconImage, bigPictureImage);
|
||||
}
|
||||
});
|
||||
|
||||
aggregator.setLargeIconUrl(context, bundle.getString("largeIconUrl"));
|
||||
aggregator.setBigPictureUrl(context, bundle.getString("bigPictureUrl"));
|
||||
}
|
||||
|
||||
public void handleConversation(final Bundle bundle) {
|
||||
if (bundle.getBoolean("deleted")){
|
||||
this.removeStatusMessage(bundle);
|
||||
} else {
|
||||
this.addStatusMessage(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearMessageNotifications(String conversationId) {
|
||||
notificationManager.cancel(conversationId.hashCode());
|
||||
cleanGroup(conversationId);
|
||||
}
|
||||
|
||||
public void clearAllMessageNotifications() {
|
||||
notificationManager.cancelAll();
|
||||
}
|
||||
|
||||
public void sendToNotificationCentreWithPicture(final Bundle bundle, Bitmap largeIconBitmap, Bitmap bigPictureBitmap) {
|
||||
|
||||
try {
|
||||
Class intentClass = getMainActivityClass();
|
||||
if (intentClass == null) {
|
||||
Log.e(LOG_TAG, "No activity class found for the notification");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bundle.getBoolean("isConversation")) {
|
||||
this.handleConversation(bundle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bundle.getString("message") == null) {
|
||||
// this happens when a 'data' notification is received - we do not synthesize a local notification in this case
|
||||
Log.d(LOG_TAG, "Ignore this message if you sent data-only notification. Cannot send to notification centre because there is no 'message' field in: " + bundle);
|
||||
return;
|
||||
}
|
||||
|
||||
String notificationIdString = bundle.getString("id");
|
||||
if (notificationIdString == null) {
|
||||
Log.e(LOG_TAG, "No notification ID specified for the notification");
|
||||
return;
|
||||
}
|
||||
|
||||
Resources res = context.getResources();
|
||||
String packageName = context.getPackageName();
|
||||
|
||||
String title = bundle.getString("title");
|
||||
if (title == null) {
|
||||
ApplicationInfo appInfo = context.getApplicationInfo();
|
||||
title = context.getPackageManager().getApplicationLabel(appInfo).toString();
|
||||
}
|
||||
|
||||
int priority = NotificationCompat.PRIORITY_HIGH;
|
||||
final String priorityString = bundle.getString("priority");
|
||||
|
||||
if (priorityString != null) {
|
||||
switch (priorityString.toLowerCase()) {
|
||||
case "max":
|
||||
priority = NotificationCompat.PRIORITY_MAX;
|
||||
break;
|
||||
case "high":
|
||||
priority = NotificationCompat.PRIORITY_HIGH;
|
||||
break;
|
||||
case "low":
|
||||
priority = NotificationCompat.PRIORITY_LOW;
|
||||
break;
|
||||
case "min":
|
||||
priority = NotificationCompat.PRIORITY_MIN;
|
||||
break;
|
||||
case "default":
|
||||
priority = NotificationCompat.PRIORITY_DEFAULT;
|
||||
break;
|
||||
default:
|
||||
priority = NotificationCompat.PRIORITY_HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
int visibility = NotificationCompat.VISIBILITY_PRIVATE;
|
||||
final String visibilityString = bundle.getString("visibility");
|
||||
|
||||
if (visibilityString != null) {
|
||||
switch (visibilityString.toLowerCase()) {
|
||||
case "private":
|
||||
visibility = NotificationCompat.VISIBILITY_PRIVATE;
|
||||
break;
|
||||
case "public":
|
||||
visibility = NotificationCompat.VISIBILITY_PUBLIC;
|
||||
break;
|
||||
case "secret":
|
||||
visibility = NotificationCompat.VISIBILITY_SECRET;
|
||||
break;
|
||||
default:
|
||||
visibility = NotificationCompat.VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
String channel_id = bundle.getString("channelId");
|
||||
|
||||
if(channel_id == null) {
|
||||
channel_id = this.getNotificationDefaultChannelId();
|
||||
}
|
||||
|
||||
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, channel_id)
|
||||
.setContentTitle(title)
|
||||
.setTicker(bundle.getString("ticker"))
|
||||
.setVisibility(visibility)
|
||||
.setPriority(priority)
|
||||
.setAutoCancel(bundle.getBoolean("autoCancel", true))
|
||||
.setOnlyAlertOnce(bundle.getBoolean("onlyAlertOnce", false));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // API 24 and higher
|
||||
// Restore showing timestamp on Android 7+
|
||||
// Source: https://developer.android.com/reference/android/app/Notification.Builder.html#setShowWhen(boolean)
|
||||
boolean showWhen = bundle.getBoolean("showWhen", true);
|
||||
|
||||
notification.setShowWhen(showWhen);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
|
||||
// Changing Default mode of notification
|
||||
notification.setDefaults(Notification.DEFAULT_LIGHTS);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { // API 20 and higher
|
||||
String group = bundle.getString("group");
|
||||
|
||||
if (group != null) {
|
||||
notification.setGroup(group);
|
||||
}
|
||||
|
||||
if (bundle.containsKey("groupSummary") || bundle.getBoolean("groupSummary")) {
|
||||
notification.setGroupSummary(bundle.getBoolean("groupSummary"));
|
||||
}
|
||||
}
|
||||
|
||||
String numberString = bundle.getString("number");
|
||||
|
||||
if (numberString != null) {
|
||||
notification.setNumber(Integer.parseInt(numberString));
|
||||
}
|
||||
|
||||
// Small icon
|
||||
int smallIconResId = 0;
|
||||
|
||||
String smallIcon = bundle.getString("smallIcon");
|
||||
|
||||
if (smallIcon != null && !smallIcon.isEmpty()) {
|
||||
smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName);
|
||||
} else if(smallIcon == null) {
|
||||
smallIconResId = res.getIdentifier("ic_stat_notify_status", "drawable", packageName);
|
||||
}
|
||||
|
||||
if (smallIconResId == 0) {
|
||||
smallIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
|
||||
|
||||
if (smallIconResId == 0) {
|
||||
smallIconResId = android.R.drawable.ic_dialog_info;
|
||||
}
|
||||
}
|
||||
|
||||
notification.setSmallIcon(smallIconResId);
|
||||
|
||||
// Large icon
|
||||
if(largeIconBitmap == null) {
|
||||
int largeIconResId = 0;
|
||||
|
||||
String largeIcon = bundle.getString("largeIcon");
|
||||
|
||||
if (largeIcon != null && !largeIcon.isEmpty()) {
|
||||
largeIconResId = res.getIdentifier(largeIcon, "mipmap", packageName);
|
||||
} else if(largeIcon == null) {
|
||||
largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
|
||||
}
|
||||
|
||||
// Before Lolipop there was no large icon for notifications.
|
||||
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
|
||||
largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId);
|
||||
}
|
||||
}
|
||||
|
||||
Bundle author = bundle.getBundle("notificationAuthor");
|
||||
|
||||
if (largeIconBitmap == null && author != null) {
|
||||
String base64Image = author.getString("icon").split(",")[1];
|
||||
byte[] decodedString = Base64.decode(base64Image, Base64.DEFAULT);
|
||||
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
|
||||
notification.setLargeIcon(getCircleBitmap(decodedByte));
|
||||
} else if (largeIconBitmap != null){
|
||||
notification.setLargeIcon(largeIconBitmap);
|
||||
}
|
||||
|
||||
String message = bundle.getString("message");
|
||||
|
||||
notification.setContentText(message);
|
||||
|
||||
String subText = bundle.getString("subText");
|
||||
|
||||
if (subText != null) {
|
||||
notification.setSubText(subText);
|
||||
}
|
||||
|
||||
String bigText = bundle.getString("bigText");
|
||||
|
||||
if (bigText == null) {
|
||||
bigText = message;
|
||||
}
|
||||
|
||||
NotificationCompat.Style style;
|
||||
|
||||
if(bigPictureBitmap != null) {
|
||||
style = new NotificationCompat.BigPictureStyle()
|
||||
.bigPicture(bigPictureBitmap)
|
||||
.setBigContentTitle(title)
|
||||
.setSummaryText(message);
|
||||
} else {
|
||||
style = new NotificationCompat.BigTextStyle().bigText(bigText);
|
||||
}
|
||||
|
||||
notification.setStyle(style);
|
||||
|
||||
Intent intent = new Intent(context, intentClass);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
bundle.putBoolean("foreground", this.isApplicationInForeground());
|
||||
bundle.putBoolean("userInteraction", true);
|
||||
intent.putExtra("notification", bundle);
|
||||
|
||||
Uri soundUri = null;
|
||||
|
||||
if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
|
||||
String soundName = bundle.getString("soundName");
|
||||
|
||||
if (soundName == null) {
|
||||
soundName = "default";
|
||||
}
|
||||
|
||||
soundUri = getSoundUri(soundName);
|
||||
|
||||
notification.setSound(soundUri);
|
||||
}
|
||||
|
||||
if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
notification.setSound(null);
|
||||
}
|
||||
|
||||
if (bundle.containsKey("ongoing") || bundle.getBoolean("ongoing")) {
|
||||
notification.setOngoing(bundle.getBoolean("ongoing"));
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
notification.setCategory(NotificationCompat.CATEGORY_CALL);
|
||||
|
||||
String color = bundle.getString("color");
|
||||
int defaultColor = -1;
|
||||
if (color != null) {
|
||||
notification.setColor(Color.parseColor(color));
|
||||
} else if (defaultColor != -1) {
|
||||
notification.setColor(defaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
int notificationID = notificationIdString.hashCode();
|
||||
|
||||
notification.setContentIntent(createOnTapIntent(context, notificationID, bundle.getString("deepLink")))
|
||||
.setDeleteIntent(createOnDismissedIntent(context, notificationID, bundle.getString("deepLink")));
|
||||
|
||||
NotificationManager notificationManager = notificationManager();
|
||||
|
||||
long[] vibratePattern = new long[]{0};
|
||||
|
||||
if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
|
||||
long vibration = bundle.containsKey("vibration") ? (long) bundle.getDouble("vibration") : DEFAULT_VIBRATION;
|
||||
if (vibration == 0)
|
||||
vibration = DEFAULT_VIBRATION;
|
||||
|
||||
vibratePattern = new long[]{0, vibration};
|
||||
|
||||
notification.setVibrate(vibratePattern);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Define the shortcutId
|
||||
String shortcutId = bundle.getString("shortcutId");
|
||||
|
||||
if (shortcutId != null) {
|
||||
notification.setShortcutId(shortcutId);
|
||||
}
|
||||
|
||||
Long timeoutAfter = (long) bundle.getDouble("timeoutAfter");
|
||||
|
||||
if (timeoutAfter != null && timeoutAfter >= 0) {
|
||||
notification.setTimeoutAfter(timeoutAfter);
|
||||
}
|
||||
}
|
||||
|
||||
Long when = (long) bundle.getDouble("when");
|
||||
|
||||
if (when != null && when >= 0) {
|
||||
notification.setWhen(when);
|
||||
}
|
||||
|
||||
notification.setUsesChronometer(bundle.getBoolean("usesChronometer", false));
|
||||
notification.setChannelId(channel_id);
|
||||
|
||||
JSONArray actionsArray = null;
|
||||
try {
|
||||
actionsArray = bundle.getString("actions") != null ? new JSONArray(bundle.getString("actions")) : null;
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOG_TAG, "Exception while converting actions to JSON object.", e);
|
||||
}
|
||||
|
||||
if (actionsArray != null) {
|
||||
// No icon for now. The icon value of 0 shows no icon.
|
||||
int icon = 0;
|
||||
|
||||
// Add button for each actions.
|
||||
for (int i = 0; i < actionsArray.length(); i++) {
|
||||
String action;
|
||||
try {
|
||||
action = actionsArray.getString(i);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOG_TAG, "Exception while getting action from actionsArray.", e);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Intent actionIntent = new Intent(context, PushNotificationActions.class);
|
||||
actionIntent.setAction(packageName + ".ACTION_" + i);
|
||||
|
||||
actionIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
|
||||
// Add "action" for later identifying which button gets pressed.
|
||||
bundle.putString("action", action);
|
||||
actionIntent.putExtra("notification", bundle);
|
||||
actionIntent.setPackage(packageName);
|
||||
|
||||
PendingIntent pendingActionIntent = PendingIntent.getBroadcast(context, notificationID, actionIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
notification.addAction(new NotificationCompat.Action.Builder(icon, action, pendingActionIntent).build());
|
||||
} else {
|
||||
notification.addAction(icon, action, pendingActionIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(this.isApplicationInForeground() && bundle.getBoolean("ignoreInForeground"))) {
|
||||
Notification info = notification.build();
|
||||
info.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
|
||||
if (bundle.containsKey("tag")) {
|
||||
String tag = bundle.getString("tag");
|
||||
notificationManager.notify(tag, notificationID, info);
|
||||
} else {
|
||||
notificationManager.notify(notificationID, info);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_TAG, "failed to send push notification", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkOrCreateChannel(NotificationManager manager, String channel_id, String channel_name, String channel_description, Uri soundUri, int importance, long[] vibratePattern, boolean showBadge) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
||||
return false;
|
||||
if (manager == null)
|
||||
return false;
|
||||
|
||||
NotificationChannel channel = manager.getNotificationChannel(channel_id);
|
||||
|
||||
if (
|
||||
channel == null && channel_name != null && channel_description != null ||
|
||||
channel != null &&
|
||||
(
|
||||
channel_name != null && !channel.getName().equals(channel_name) ||
|
||||
channel_description != null && !channel.getDescription().equals(channel_description)
|
||||
)
|
||||
) {
|
||||
// If channel doesn't exist create a new one.
|
||||
// If channel name or description is updated then update the existing channel.
|
||||
channel = new NotificationChannel(channel_id, channel_name, importance);
|
||||
|
||||
channel.setDescription(channel_description);
|
||||
channel.enableLights(true);
|
||||
channel.enableVibration(vibratePattern != null);
|
||||
channel.setVibrationPattern(vibratePattern);
|
||||
channel.setShowBadge(showBadge);
|
||||
|
||||
if (soundUri != null) {
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
||||
.build();
|
||||
|
||||
channel.setSound(soundUri, audioAttributes);
|
||||
} else {
|
||||
channel.setSound(null, null);
|
||||
}
|
||||
|
||||
manager.createNotificationChannel(channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean createChannel(ReadableMap channelInfo) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
|
||||
return false;
|
||||
|
||||
String channelId = channelInfo.getString("channelId");
|
||||
String channelName = channelInfo.getString("channelName");
|
||||
String channelDescription = channelInfo.hasKey("channelDescription") ? channelInfo.getString("channelDescription") : "";
|
||||
String soundName = channelInfo.hasKey("soundName") ? channelInfo.getString("soundName") : "default";
|
||||
int importance = channelInfo.hasKey("importance") ? channelInfo.getInt("importance") : 4;
|
||||
boolean vibrate = channelInfo.hasKey("vibrate") && channelInfo.getBoolean("vibrate");
|
||||
long[] vibratePattern = vibrate ? new long[] { DEFAULT_VIBRATION } : null;
|
||||
boolean showBadge = channelInfo.hasKey("showBadge") && channelInfo.getBoolean("showBadge");
|
||||
|
||||
NotificationManager manager = notificationManager();
|
||||
|
||||
Uri soundUri = getSoundUri(soundName);
|
||||
|
||||
return checkOrCreateChannel(manager, channelId, channelName, channelDescription, soundUri, importance, vibratePattern, showBadge);
|
||||
}
|
||||
|
||||
public String getNotificationDefaultChannelId() {
|
||||
return this.CHANNEL_ID;
|
||||
}
|
||||
|
||||
private Uri getSoundUri(String soundName) {
|
||||
if (soundName == null || "default".equalsIgnoreCase(soundName)) {
|
||||
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
} else {
|
||||
|
||||
// sound name can be full filename, or just the resource name.
|
||||
// So the strings 'my_sound.mp3' AND 'my_sound' are accepted
|
||||
// The reason is to make the iOS and android javascript interfaces compatible
|
||||
|
||||
int resId;
|
||||
if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
|
||||
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
|
||||
} else {
|
||||
soundName = soundName.substring(0, soundName.lastIndexOf('.'));
|
||||
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
|
||||
}
|
||||
|
||||
return Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);
|
||||
}
|
||||
}
|
||||
|
||||
public Class getMainActivityClass() {
|
||||
String packageName = context.getPackageName();
|
||||
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
String className = launchIntent.getComponent().getClassName();
|
||||
try {
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isApplicationInForeground() {
|
||||
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
|
||||
if (processInfos != null) {
|
||||
for (RunningAppProcessInfo processInfo : processInfos) {
|
||||
if (processInfo.processName.equals(context.getPackageName())
|
||||
&& processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|
||||
&& processInfo.pkgList.length > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Bitmap getCircleBitmap(Bitmap bitmap) {
|
||||
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
|
||||
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
final Canvas canvas = new Canvas(output);
|
||||
|
||||
final int color = Color.RED;
|
||||
final Paint paint = new Paint();
|
||||
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
final RectF rectF = new RectF(rect);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0, 0, 0, 0);
|
||||
paint.setColor(color);
|
||||
canvas.drawOval(rectF, paint);
|
||||
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmap, rect, rect, paint);
|
||||
|
||||
bitmap.recycle();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private Person getPerson(Bundle bundle) {
|
||||
String name = bundle.getString("name");
|
||||
|
||||
return new Person.Builder().setName(name).build();
|
||||
}
|
||||
|
||||
private StatusMessage createMessage(Bundle data) {
|
||||
Person author = getPerson(data.getBundle("notificationAuthor"));
|
||||
long timeStampLongValue = (long) data.getDouble("timestamp");
|
||||
return new StatusMessage(data.getString("id"), author, timeStampLongValue, data.getString("message"));
|
||||
}
|
||||
|
||||
private PendingIntent createGroupOnDismissedIntent(Context context, int notificationId, String groupId, String deepLink) {
|
||||
Intent intent = new Intent(ACTION_DELETE_NOTIFICATION);
|
||||
intent.putExtra("im.status.ethereum.deepLink", deepLink);
|
||||
intent.putExtra("im.status.ethereum.groupId", groupId);
|
||||
return PendingIntent.getBroadcast(context.getApplicationContext(), notificationId, intent, flag);
|
||||
}
|
||||
|
||||
private PendingIntent createGroupOnTapIntent(Context context, int notificationId, String groupId, String deepLink) {
|
||||
Intent intent = getOpenAppIntent(deepLink);
|
||||
return PendingIntent.getActivity(context.getApplicationContext(), notificationId, intent, flag);
|
||||
}
|
||||
|
||||
private PendingIntent createOnTapIntent(Context context, int notificationId, String deepLink) {
|
||||
Intent intent = getOpenAppIntent(deepLink);
|
||||
return PendingIntent.getActivity(context.getApplicationContext(), notificationId, intent, flag);
|
||||
}
|
||||
|
||||
private PendingIntent createOnDismissedIntent(Context context, int notificationId, String deepLink) {
|
||||
Intent intent = new Intent(ACTION_DELETE_NOTIFICATION);
|
||||
intent.putExtra("im.status.ethereum.deepLink", deepLink);
|
||||
return PendingIntent.getBroadcast(context.getApplicationContext(), notificationId, intent, flag);
|
||||
}
|
||||
|
||||
public void removeStatusMessage(Bundle bundle) {
|
||||
String conversationId = bundle.getString("conversationId");
|
||||
StatusMessageGroup group = this.messageGroups.get(conversationId);
|
||||
NotificationManager notificationManager = notificationManager();
|
||||
|
||||
if (group == null) {
|
||||
group = new StatusMessageGroup(conversationId);
|
||||
}
|
||||
|
||||
this.messageGroups.put(conversationId, group);
|
||||
|
||||
String id = bundle.getString("id");
|
||||
group.removeMessage(id);
|
||||
|
||||
this.showMessages(bundle);
|
||||
}
|
||||
|
||||
public StatusMessageGroup getMessageGroup(String conversationId) {
|
||||
return this.messageGroups.get(conversationId);
|
||||
}
|
||||
|
||||
public void addStatusMessage(Bundle bundle) {
|
||||
String conversationId = bundle.getString("conversationId");
|
||||
StatusMessageGroup group = this.messageGroups.get(conversationId);
|
||||
NotificationManager notificationManager = notificationManager();
|
||||
|
||||
if (group == null) {
|
||||
group = new StatusMessageGroup(conversationId);
|
||||
}
|
||||
|
||||
this.messageGroups.put(conversationId, group);
|
||||
|
||||
group.addMessage(createMessage(bundle));
|
||||
|
||||
this.showMessages(bundle);
|
||||
}
|
||||
|
||||
public void showMessages(Bundle bundle) {
|
||||
String conversationId = bundle.getString("conversationId");
|
||||
StatusMessageGroup group = this.messageGroups.get(conversationId);
|
||||
NotificationManager notificationManager = notificationManager();
|
||||
|
||||
NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle("Me");
|
||||
ArrayList<StatusMessage> messages = group.getMessages();
|
||||
|
||||
if (messages.size() == 0) {
|
||||
notificationManager.cancel(conversationId.hashCode());
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
StatusMessage message = messages.get(i);
|
||||
messagingStyle.addMessage(message.getText(),
|
||||
message.getTimestamp(),
|
||||
message.getAuthor());
|
||||
}
|
||||
|
||||
if (bundle.getString("title") != null) {
|
||||
messagingStyle.setConversationTitle(bundle.getString("title"));
|
||||
}
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_stat_notify_status)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||
.setStyle(messagingStyle)
|
||||
.setGroup(conversationId)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setGroupSummary(true)
|
||||
.setContentIntent(createGroupOnTapIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
|
||||
.setDeleteIntent(createGroupOnDismissedIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
|
||||
.setNumber(messages.size() + 1)
|
||||
.setAutoCancel(true);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
builder.setVibrate(new long[0]);
|
||||
}
|
||||
notificationManager.notify(conversationId.hashCode(), builder.build());
|
||||
}
|
||||
|
||||
class StatusMessageGroup {
|
||||
private ArrayList<StatusMessage> messages;
|
||||
private String id;
|
||||
|
||||
StatusMessageGroup(String id) {
|
||||
this.id = id;
|
||||
this.messages = new ArrayList<StatusMessage>();
|
||||
}
|
||||
public ArrayList<StatusMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void addMessage(StatusMessage message) {
|
||||
this.messages.add(message);
|
||||
}
|
||||
|
||||
public void removeMessage(String id) {
|
||||
ArrayList<StatusMessage> newMessages = new ArrayList<StatusMessage>();
|
||||
for(StatusMessage message: this.messages) {
|
||||
if(!message.id.equals(id)) {
|
||||
newMessages.add(message);
|
||||
}
|
||||
}
|
||||
this.messages = newMessages;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
class StatusMessage {
|
||||
public Person getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
private String id;
|
||||
private Person author;
|
||||
private long timestamp;
|
||||
private String text;
|
||||
|
||||
StatusMessage(String id, Person author, long timestamp, String text) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.timestamp = timestamp;
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeGroup(String groupId) {
|
||||
this.messageGroups.remove(groupId);
|
||||
}
|
||||
|
||||
private void cleanGroup(String groupId) {
|
||||
removeGroup(groupId);
|
||||
if (messageGroups.size() == 0) {
|
||||
notificationManager.cancelAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Log.e(LOG_TAG, "Starting Foreground Service");
|
||||
Intent serviceIntent = new Intent(context, ForegroundService.class);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(serviceIntent);
|
||||
} else {
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
this.registerBroadcastReceiver();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Log.e(LOG_TAG, "Stopping Foreground Service");
|
||||
//NOTE: we cancel all the current notifications, because the intents can't be used anymore
|
||||
//since the broadcast receiver will be killed as well and won't be able to handle any intent
|
||||
notificationManager.cancelAll();
|
||||
Intent serviceIntent = new Intent(context, ForegroundService.class);
|
||||
context.stopService(serviceIntent);
|
||||
context.unregisterReceiver(notificationActionReceiver);
|
||||
}
|
||||
}
|
||||
+750
@@ -0,0 +1,750 @@
|
||||
// https://github.com/zo0r/react-native-push-notification/blob/bedc8f646aab67d594f291449fbfa24e07b64fe8/android/src/main/
|
||||
// java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java Copy-Paste with removed firebase
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.app.ActivityManager.RunningAppProcessInfo
|
||||
import android.app.AlarmManager
|
||||
import android.app.Application
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffXfermode
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.media.AudioAttributes
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.util.Log
|
||||
import android.util.Base64
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.facebook.react.bridge.Arguments
|
||||
import com.facebook.react.bridge.ReadableArray
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import com.facebook.react.bridge.WritableArray
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import im.status.ethereum.module.R
|
||||
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
|
||||
|
||||
class PushNotificationHelper(private val context: Application, private val intentFilter: IntentFilter) {
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_VIBRATION: Long = 300L
|
||||
private const val CHANNEL_ID = "status-im-notifications"
|
||||
const val ACTION_DELETE_NOTIFICATION = "im.status.ethereum.module.DELETE_NOTIFICATION"
|
||||
const val ACTION_TAP_STOP = "im.status.ethereum.module.TAP_STOP"
|
||||
}
|
||||
|
||||
private val flag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
|
||||
private val notificationManager: NotificationManager by lazy {
|
||||
context.getSystemService(NotificationManager::class.java)
|
||||
}
|
||||
|
||||
private val persons: MutableMap<String, Person> = mutableMapOf()
|
||||
private val messageGroups: MutableMap<String, StatusMessageGroup> = mutableMapOf()
|
||||
|
||||
init {
|
||||
registerBroadcastReceiver()
|
||||
}
|
||||
|
||||
private val notificationActionReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
ACTION_DELETE_NOTIFICATION -> {
|
||||
intent.extras?.getString("im.status.ethereum.groupId")?.let { groupId ->
|
||||
cleanGroup(groupId)
|
||||
}
|
||||
}
|
||||
ACTION_TAP_STOP -> {
|
||||
stop()
|
||||
System.exit(0)
|
||||
}
|
||||
}
|
||||
Log.e(LOG_TAG, "intent received: ${intent.action}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerBroadcastReceiver() {
|
||||
intentFilter.apply {
|
||||
addAction(ACTION_DELETE_NOTIFICATION)
|
||||
addAction(ACTION_TAP_STOP)
|
||||
}
|
||||
context.registerReceiver(notificationActionReceiver, intentFilter, Context.RECEIVER_EXPORTED)
|
||||
Log.e(LOG_TAG, "Broadcast Receiver registered")
|
||||
}
|
||||
|
||||
fun getOpenAppIntent(deepLink: String?): Intent? {
|
||||
val packageName = context.packageName
|
||||
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
|
||||
val className = launchIntent?.component?.className ?: return null
|
||||
|
||||
return try {
|
||||
val intentClass = Class.forName(className)
|
||||
Intent(context, intentClass).apply {
|
||||
addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
action = Intent.ACTION_VIEW
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
deepLink?.let { data = Uri.parse(it) }
|
||||
}
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun invokeApp(bundle: Bundle?) {
|
||||
val packageName = context.packageName
|
||||
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
|
||||
val className = launchIntent?.component?.className ?: return
|
||||
|
||||
try {
|
||||
val activityClass = Class.forName(className)
|
||||
Intent(context, activityClass).apply {
|
||||
bundle?.let { putExtra("notification", it) }
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(this)
|
||||
}
|
||||
} catch (e: ClassNotFoundException) {
|
||||
Log.e(LOG_TAG, "Class not found", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMainActivityClass(): Class<*>? {
|
||||
val packageName = context.packageName
|
||||
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
|
||||
val className = launchIntent?.component?.className ?: return null
|
||||
|
||||
return try {
|
||||
Class.forName(className)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun isApplicationInForeground(): Boolean {
|
||||
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
val processInfos = activityManager.runningAppProcesses ?: return false
|
||||
|
||||
return processInfos.any { processInfo ->
|
||||
processInfo.processName == context.packageName &&
|
||||
processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
|
||||
processInfo.pkgList.isNotEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCircleBitmap(bitmap: Bitmap): Bitmap {
|
||||
val output = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(output)
|
||||
val paint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = Color.RED
|
||||
}
|
||||
val rect = Rect(0, 0, bitmap.width, bitmap.height)
|
||||
val rectF = RectF(rect)
|
||||
|
||||
canvas.drawARGB(0, 0, 0, 0)
|
||||
canvas.drawOval(rectF, paint)
|
||||
|
||||
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
|
||||
canvas.drawBitmap(bitmap, rect, rect, paint)
|
||||
|
||||
bitmap.recycle()
|
||||
return output
|
||||
}
|
||||
|
||||
// Represents a message in a Status conversation
|
||||
data class StatusMessage(
|
||||
val id: String,
|
||||
val author: Person,
|
||||
val timestamp: Long,
|
||||
val text: String
|
||||
)
|
||||
|
||||
// Represents a group of messages in a Status conversation
|
||||
inner class StatusMessageGroup(val id: String) {
|
||||
private val _messages = mutableListOf<StatusMessage>()
|
||||
val messages: List<StatusMessage> get() = _messages.toList()
|
||||
|
||||
fun addMessage(message: StatusMessage) {
|
||||
_messages.add(message)
|
||||
}
|
||||
|
||||
fun removeMessage(id: String) {
|
||||
_messages.removeAll { it.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPerson(bundle: Bundle): Person {
|
||||
return Person.Builder()
|
||||
.setName(bundle.getString("name"))
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createMessage(data: Bundle): StatusMessage {
|
||||
val author = getPerson(data.getBundle("notificationAuthor") ?: Bundle())
|
||||
val timeStampLongValue = data.getDouble("timestamp").toLong()
|
||||
return StatusMessage(
|
||||
id = data.getString("id") ?: "",
|
||||
author = author,
|
||||
timestamp = timeStampLongValue,
|
||||
text = data.getString("message") ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
private fun createGroupOnDismissedIntent(
|
||||
context: Context,
|
||||
notificationId: Int,
|
||||
groupId: String,
|
||||
deepLink: String?
|
||||
): PendingIntent {
|
||||
return Intent(ACTION_DELETE_NOTIFICATION).apply {
|
||||
putExtra("im.status.ethereum.deepLink", deepLink)
|
||||
putExtra("im.status.ethereum.groupId", groupId)
|
||||
}.let { intent ->
|
||||
PendingIntent.getBroadcast(
|
||||
context.applicationContext,
|
||||
notificationId,
|
||||
intent,
|
||||
flag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createGroupOnTapIntent(
|
||||
context: Context,
|
||||
notificationId: Int,
|
||||
groupId: String,
|
||||
deepLink: String?
|
||||
): PendingIntent {
|
||||
return getOpenAppIntent(deepLink)?.let { intent ->
|
||||
PendingIntent.getActivity(
|
||||
context.applicationContext,
|
||||
notificationId,
|
||||
intent,
|
||||
flag
|
||||
)
|
||||
} ?: throw IllegalStateException("Could not create open app intent")
|
||||
}
|
||||
|
||||
private fun createOnTapIntent(
|
||||
context: Context,
|
||||
notificationId: Int,
|
||||
deepLink: String?
|
||||
): PendingIntent {
|
||||
return getOpenAppIntent(deepLink)?.let { intent ->
|
||||
PendingIntent.getActivity(
|
||||
context.applicationContext,
|
||||
notificationId,
|
||||
intent,
|
||||
flag
|
||||
)
|
||||
} ?: throw IllegalStateException("Could not create open app intent")
|
||||
}
|
||||
|
||||
private fun createOnDismissedIntent(
|
||||
context: Context,
|
||||
notificationId: Int,
|
||||
deepLink: String?
|
||||
): PendingIntent {
|
||||
return Intent(ACTION_DELETE_NOTIFICATION).apply {
|
||||
putExtra("im.status.ethereum.deepLink", deepLink)
|
||||
}.let { intent ->
|
||||
PendingIntent.getBroadcast(
|
||||
context.applicationContext,
|
||||
notificationId,
|
||||
intent,
|
||||
flag
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeStatusMessage(bundle: Bundle) {
|
||||
val conversationId = bundle.getString("conversationId") ?: return
|
||||
val group = messageGroups.getOrPut(conversationId) {
|
||||
StatusMessageGroup(conversationId)
|
||||
}
|
||||
|
||||
bundle.getString("id")?.let { id ->
|
||||
group.removeMessage(id)
|
||||
}
|
||||
|
||||
showMessages(bundle)
|
||||
}
|
||||
|
||||
fun getMessageGroup(conversationId: String): StatusMessageGroup? {
|
||||
return messageGroups[conversationId]
|
||||
}
|
||||
|
||||
fun addStatusMessage(bundle: Bundle) {
|
||||
val conversationId = bundle.getString("conversationId") ?: return
|
||||
val group = messageGroups.getOrPut(conversationId) {
|
||||
StatusMessageGroup(conversationId)
|
||||
}
|
||||
|
||||
group.addMessage(createMessage(bundle))
|
||||
showMessages(bundle)
|
||||
}
|
||||
|
||||
fun showMessages(bundle: Bundle) {
|
||||
val conversationId = bundle.getString("conversationId") ?: return
|
||||
val group = messageGroups[conversationId] ?: return
|
||||
|
||||
val messagingStyle = NotificationCompat.MessagingStyle("Me")
|
||||
|
||||
// If there are no messages, cancel the notification and return
|
||||
if (group.messages.isEmpty()) {
|
||||
notificationManager.cancel(conversationId.hashCode())
|
||||
return
|
||||
}
|
||||
|
||||
group.messages.forEach { message ->
|
||||
messagingStyle.addMessage(
|
||||
message.text,
|
||||
message.timestamp,
|
||||
message.author
|
||||
)
|
||||
}
|
||||
|
||||
// Set conversation title if available
|
||||
bundle.getString("title")?.let { title ->
|
||||
messagingStyle.conversationTitle = title
|
||||
}
|
||||
|
||||
val builder = NotificationCompat.Builder(context, CHANNEL_ID).apply {
|
||||
setSmallIcon(R.drawable.ic_stat_notify_status)
|
||||
setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||
setStyle(messagingStyle)
|
||||
setGroup(conversationId)
|
||||
setOnlyAlertOnce(true)
|
||||
setGroupSummary(true)
|
||||
setContentIntent(createGroupOnTapIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
|
||||
setDeleteIntent(createGroupOnDismissedIntent(context, conversationId.hashCode(), conversationId, bundle.getString("deepLink")))
|
||||
setNumber(group.messages.size + 1)
|
||||
setAutoCancel(true)
|
||||
|
||||
// Set empty vibration pattern for Android 5.0 and above
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setVibrate(LongArray(0))
|
||||
}
|
||||
}
|
||||
|
||||
// Show the notification
|
||||
notificationManager.notify(conversationId.hashCode(), builder.build())
|
||||
}
|
||||
|
||||
fun checkOrCreateChannel(
|
||||
manager: NotificationManager?,
|
||||
channelId: String,
|
||||
channelName: String?,
|
||||
channelDescription: String?,
|
||||
soundUri: Uri?,
|
||||
importance: Int,
|
||||
vibratePattern: LongArray?,
|
||||
showBadge: Boolean
|
||||
): Boolean {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || manager == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
val existingChannel = manager.getNotificationChannel(channelId)
|
||||
val shouldCreateOrUpdate = when {
|
||||
// Channel doesn't exist and we have required info
|
||||
existingChannel == null && channelName != null && channelDescription != null -> true
|
||||
|
||||
// Channel exists but needs update
|
||||
existingChannel != null && (
|
||||
(channelName != null && existingChannel.name != channelName) ||
|
||||
(channelDescription != null && existingChannel.description != channelDescription)
|
||||
) -> true
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (shouldCreateOrUpdate) {
|
||||
NotificationChannel(channelId, channelName, importance).apply {
|
||||
description = channelDescription
|
||||
enableLights(true)
|
||||
enableVibration(vibratePattern != null)
|
||||
vibrationPattern = vibratePattern
|
||||
setShowBadge(showBadge)
|
||||
|
||||
// Configure sound
|
||||
if (soundUri != null) {
|
||||
val audioAttributes = AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
|
||||
.build()
|
||||
setSound(soundUri, audioAttributes)
|
||||
} else {
|
||||
setSound(null, null)
|
||||
}
|
||||
|
||||
manager.createNotificationChannel(this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun createChannel(channelInfo: ReadableMap): Boolean {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return false
|
||||
}
|
||||
|
||||
return checkOrCreateChannel(
|
||||
manager = notificationManager,
|
||||
channelId = channelInfo.getString("channelId") ?: return false,
|
||||
channelName = channelInfo.getString("channelName"),
|
||||
channelDescription = if (channelInfo.hasKey("channelDescription")) {
|
||||
channelInfo.getString("channelDescription")
|
||||
} else "",
|
||||
soundUri = getSoundUri(
|
||||
if (channelInfo.hasKey("soundName")) {
|
||||
channelInfo.getString("soundName")
|
||||
} else "default"
|
||||
),
|
||||
importance = if (channelInfo.hasKey("importance")) {
|
||||
channelInfo.getInt("importance")
|
||||
} else 4,
|
||||
vibratePattern = if (channelInfo.hasKey("vibrate") && channelInfo.getBoolean("vibrate")) {
|
||||
longArrayOf(DEFAULT_VIBRATION)
|
||||
} else null,
|
||||
showBadge = channelInfo.hasKey("showBadge") && channelInfo.getBoolean("showBadge")
|
||||
)
|
||||
}
|
||||
|
||||
fun getNotificationDefaultChannelId(): String = CHANNEL_ID
|
||||
|
||||
private fun getSoundUri(soundName: String?): Uri {
|
||||
return when {
|
||||
soundName == null || soundName.equals("default", ignoreCase = true) -> {
|
||||
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||
}
|
||||
else -> {
|
||||
val resources = context.resources
|
||||
val packageName = context.packageName
|
||||
val resId = when {
|
||||
// Try to find the resource as is
|
||||
resources.getIdentifier(soundName, "raw", packageName) != 0 -> {
|
||||
resources.getIdentifier(soundName, "raw", packageName)
|
||||
}
|
||||
// Try without file extension
|
||||
else -> {
|
||||
val nameWithoutExtension = soundName.substringBeforeLast('.')
|
||||
resources.getIdentifier(nameWithoutExtension, "raw", packageName)
|
||||
}
|
||||
}
|
||||
Uri.parse("android.resource://$packageName/$resId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeGroup(groupId: String) {
|
||||
messageGroups.remove(groupId)
|
||||
}
|
||||
|
||||
private fun cleanGroup(groupId: String) {
|
||||
removeGroup(groupId)
|
||||
if (messageGroups.isEmpty()) {
|
||||
notificationManager.cancelAll()
|
||||
}
|
||||
}
|
||||
|
||||
fun start() {
|
||||
Log.e(LOG_TAG, "Starting Foreground Service")
|
||||
Intent(context, ForegroundService::class.java).also { serviceIntent ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(serviceIntent)
|
||||
} else {
|
||||
context.startService(serviceIntent)
|
||||
}
|
||||
}
|
||||
registerBroadcastReceiver()
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
Log.e(LOG_TAG, "Stopping Foreground Service")
|
||||
// Cancel all current notifications since their intents won't be valid
|
||||
// after the broadcast receiver is killed
|
||||
notificationManager.cancelAll()
|
||||
|
||||
Intent(context, ForegroundService::class.java).also { serviceIntent ->
|
||||
context.stopService(serviceIntent)
|
||||
}
|
||||
context.unregisterReceiver(notificationActionReceiver)
|
||||
}
|
||||
|
||||
fun sendToNotificationCentre(bundle: Bundle) {
|
||||
val aggregator = PushNotificationPicturesAggregator { largeIconImage, bigPictureImage ->
|
||||
sendToNotificationCentreWithPicture(bundle, largeIconImage, bigPictureImage)
|
||||
}
|
||||
|
||||
aggregator.apply {
|
||||
setLargeIconUrl(context, bundle.getString("largeIconUrl"))
|
||||
setBigPictureUrl(context, bundle.getString("bigPictureUrl"))
|
||||
}
|
||||
}
|
||||
|
||||
fun handleConversation(bundle: Bundle) {
|
||||
if (bundle.getBoolean("deleted")) {
|
||||
removeStatusMessage(bundle)
|
||||
} else {
|
||||
addStatusMessage(bundle)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearMessageNotifications(conversationId: String) {
|
||||
notificationManager.cancel(conversationId.hashCode())
|
||||
cleanGroup(conversationId)
|
||||
}
|
||||
|
||||
fun clearAllMessageNotifications() {
|
||||
notificationManager.cancelAll()
|
||||
}
|
||||
|
||||
fun sendToNotificationCentreWithPicture(
|
||||
bundle: Bundle,
|
||||
largeIconBitmap: Bitmap?,
|
||||
bigPictureBitmap: Bitmap?
|
||||
) {
|
||||
try {
|
||||
val intentClass = getMainActivityClass() ?: run {
|
||||
Log.e(LOG_TAG, "No activity class found for the notification")
|
||||
return
|
||||
}
|
||||
|
||||
if (bundle.getBoolean("isConversation")) {
|
||||
handleConversation(bundle)
|
||||
return
|
||||
}
|
||||
|
||||
if (bundle.getString("message") == null) {
|
||||
Log.d(LOG_TAG, "Ignore this message if you sent data-only notification. " +
|
||||
"Cannot send to notification centre because there is no 'message' field in: $bundle")
|
||||
return
|
||||
}
|
||||
|
||||
val notificationIdString = bundle.getString("id") ?: run {
|
||||
Log.e(LOG_TAG, "No notification ID specified for the notification")
|
||||
return
|
||||
}
|
||||
|
||||
val resources = context.resources
|
||||
val packageName = context.packageName
|
||||
|
||||
val title = bundle.getString("title") ?: run {
|
||||
val appInfo = context.applicationInfo
|
||||
context.packageManager.getApplicationLabel(appInfo).toString()
|
||||
}
|
||||
|
||||
val priority = when (bundle.getString("priority")?.toLowerCase()) {
|
||||
"max" -> NotificationCompat.PRIORITY_MAX
|
||||
"high" -> NotificationCompat.PRIORITY_HIGH
|
||||
"low" -> NotificationCompat.PRIORITY_LOW
|
||||
"min" -> NotificationCompat.PRIORITY_MIN
|
||||
"default" -> NotificationCompat.PRIORITY_DEFAULT
|
||||
else -> NotificationCompat.PRIORITY_HIGH
|
||||
}
|
||||
|
||||
val visibility = when (bundle.getString("visibility")?.toLowerCase()) {
|
||||
"private" -> NotificationCompat.VISIBILITY_PRIVATE
|
||||
"public" -> NotificationCompat.VISIBILITY_PUBLIC
|
||||
"secret" -> NotificationCompat.VISIBILITY_SECRET
|
||||
else -> NotificationCompat.VISIBILITY_PRIVATE
|
||||
}
|
||||
|
||||
val channelId = bundle.getString("channelId") ?: getNotificationDefaultChannelId()
|
||||
|
||||
NotificationCompat.Builder(context, channelId).apply {
|
||||
setContentTitle(title)
|
||||
setTicker(bundle.getString("ticker"))
|
||||
setVisibility(visibility)
|
||||
setPriority(priority)
|
||||
setAutoCancel(bundle.getBoolean("autoCancel", true))
|
||||
setOnlyAlertOnce(bundle.getBoolean("onlyAlertOnce", false))
|
||||
|
||||
// Configure notification based on Android version
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
setShowWhen(bundle.getBoolean("showWhen", true))
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
setDefaults(Notification.DEFAULT_LIGHTS)
|
||||
}
|
||||
|
||||
// Handle group settings for Android KitKat Watch and above
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
|
||||
bundle.getString("group")?.let { group ->
|
||||
setGroup(group)
|
||||
}
|
||||
|
||||
if (bundle.containsKey("groupSummary") || bundle.getBoolean("groupSummary")) {
|
||||
setGroupSummary(bundle.getBoolean("groupSummary"))
|
||||
}
|
||||
}
|
||||
|
||||
// Set notification number if provided
|
||||
bundle.getString("number")?.toIntOrNull()?.let { number ->
|
||||
setNumber(number)
|
||||
}
|
||||
|
||||
val smallIconResId = findSmallIconResourceId(resources, packageName, bundle)
|
||||
setSmallIcon(smallIconResId)
|
||||
|
||||
configureLargeIcon(this, largeIconBitmap, bundle, resources, packageName)
|
||||
|
||||
val message = bundle.getString("message") ?: ""
|
||||
setContentText(message)
|
||||
|
||||
bundle.getString("subText")?.let { subText ->
|
||||
setSubText(subText)
|
||||
}
|
||||
|
||||
val bigText = bundle.getString("bigText") ?: message
|
||||
val style = when {
|
||||
bigPictureBitmap != null -> NotificationCompat.BigPictureStyle()
|
||||
.bigPicture(bigPictureBitmap)
|
||||
.setBigContentTitle(title)
|
||||
.setSummaryText(message)
|
||||
else -> NotificationCompat.BigTextStyle().bigText(bigText)
|
||||
}
|
||||
setStyle(style)
|
||||
|
||||
val notificationId = notificationIdString.hashCode()
|
||||
setContentIntent(createOnTapIntent(context, notificationId, bundle.getString("deepLink")))
|
||||
setDeleteIntent(createOnDismissedIntent(context, notificationId, bundle.getString("deepLink")))
|
||||
|
||||
configureSoundAndVibration(this, bundle)
|
||||
|
||||
setOngoing(bundle.getBoolean("ongoing", false))
|
||||
|
||||
// Handle color for Lollipop and above
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
bundle.getString("color")?.let { color ->
|
||||
setColor(Color.parseColor(color))
|
||||
}
|
||||
}
|
||||
|
||||
// Finally show the notification if conditions are met
|
||||
if (!(isApplicationInForeground() && bundle.getBoolean("ignoreInForeground"))) {
|
||||
val notification = build()
|
||||
notification.defaults = notification.defaults or Notification.DEFAULT_LIGHTS
|
||||
|
||||
if (bundle.containsKey("tag")) {
|
||||
notificationManager.notify(bundle.getString("tag"), notificationId, notification)
|
||||
} else {
|
||||
notificationManager.notify(notificationId, notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Log.e(LOG_TAG, "Failed to send push notification", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findSmallIconResourceId(resources: Resources, packageName: String, bundle: Bundle): Int {
|
||||
val smallIcon = bundle.getString("smallIcon")
|
||||
return when {
|
||||
!smallIcon.isNullOrEmpty() ->
|
||||
resources.getIdentifier(smallIcon, "mipmap", packageName)
|
||||
smallIcon == null ->
|
||||
resources.getIdentifier("ic_stat_notify_status", "drawable", packageName)
|
||||
else -> {
|
||||
val defaultIcon = resources.getIdentifier("ic_launcher", "mipmap", packageName)
|
||||
defaultIcon.takeIf { it != 0 } ?: android.R.drawable.ic_dialog_info
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureLargeIcon(
|
||||
builder: NotificationCompat.Builder,
|
||||
largeIconBitmap: Bitmap?,
|
||||
bundle: Bundle,
|
||||
resources: Resources,
|
||||
packageName: String
|
||||
) {
|
||||
var finalLargeIcon = largeIconBitmap
|
||||
|
||||
if (finalLargeIcon == null) {
|
||||
val largeIcon = bundle.getString("largeIcon")
|
||||
val largeIconResId = when {
|
||||
!largeIcon.isNullOrEmpty() ->
|
||||
resources.getIdentifier(largeIcon, "mipmap", packageName)
|
||||
largeIcon == null ->
|
||||
resources.getIdentifier("ic_launcher", "mipmap", packageName)
|
||||
else -> 0
|
||||
}
|
||||
|
||||
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
|
||||
finalLargeIcon = BitmapFactory.decodeResource(resources, largeIconResId)
|
||||
}
|
||||
}
|
||||
|
||||
bundle.getBundle("notificationAuthor")?.getString("icon")?.let { icon ->
|
||||
val base64Image = icon.split(",")[1]
|
||||
val decodedString = Base64.decode(base64Image, Base64.DEFAULT)
|
||||
val decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
|
||||
builder.setLargeIcon(getCircleBitmap(decodedByte))
|
||||
} ?: finalLargeIcon?.let { icon ->
|
||||
builder.setLargeIcon(icon)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureSoundAndVibration(
|
||||
builder: NotificationCompat.Builder,
|
||||
bundle: Bundle
|
||||
) {
|
||||
var soundUri: Uri? = null
|
||||
|
||||
if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
|
||||
val soundName = bundle.getString("soundName") ?: "default"
|
||||
soundUri = getSoundUri(soundName)
|
||||
builder.setSound(soundUri)
|
||||
}
|
||||
|
||||
if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
builder.setSound(null)
|
||||
}
|
||||
|
||||
if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
|
||||
val vibration = if (bundle.containsKey("vibration")) {
|
||||
bundle.getDouble("vibration").toLong()
|
||||
} else DEFAULT_VIBRATION
|
||||
|
||||
val finalVibration = if (vibration == 0L) DEFAULT_VIBRATION else vibration
|
||||
builder.setVibrate(longArrayOf(0, finalVibration))
|
||||
}
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import android.os.Build;
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
|
||||
|
||||
class PushNotificationJsDelivery {
|
||||
|
||||
private ReactContext reactContext;
|
||||
|
||||
PushNotificationJsDelivery(ReactContext context){
|
||||
reactContext = context;
|
||||
}
|
||||
|
||||
String convertJSON(Bundle bundle) {
|
||||
try {
|
||||
JSONObject json = convertJSONObject(bundle);
|
||||
return json.toString();
|
||||
} catch (JSONException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// a Bundle is not a map, so we have to convert it explicitly
|
||||
private JSONObject convertJSONObject(Bundle bundle) throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
Set<String> keys = bundle.keySet();
|
||||
for (String key : keys) {
|
||||
Object value = bundle.get(key);
|
||||
if (value instanceof Bundle) {
|
||||
json.put(key, convertJSONObject((Bundle)value));
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
json.put(key, JSONObject.wrap(value));
|
||||
} else {
|
||||
json.put(key, value);
|
||||
}
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
void notifyNotification(Bundle bundle) {
|
||||
String bundleString = convertJSON(bundle);
|
||||
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putString("dataJSON", bundleString);
|
||||
|
||||
sendEvent("remoteNotificationReceived", params);
|
||||
}
|
||||
|
||||
void notifyNotificationAction(Bundle bundle) {
|
||||
String bundleString = convertJSON(bundle);
|
||||
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putString("dataJSON", bundleString);
|
||||
|
||||
sendEvent("notificationActionReceived", params);
|
||||
}
|
||||
|
||||
void sendEvent(String eventName, Object params) {
|
||||
if (reactContext.hasActiveCatalystInstance()) {
|
||||
reactContext
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(eventName, params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.os.Build
|
||||
import android.app.Application
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
import com.facebook.react.bridge.Arguments
|
||||
import com.facebook.react.bridge.WritableMap
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
|
||||
|
||||
class PushNotificationJsDelivery(
|
||||
private val reactContext: ReactContext
|
||||
) {
|
||||
/**
|
||||
* Converts a Bundle to its JSON string representation.
|
||||
* Returns null if conversion fails.
|
||||
*/
|
||||
fun convertJSON(bundle: Bundle): String? {
|
||||
return try {
|
||||
convertJSONObject(bundle).toString()
|
||||
} catch (e: JSONException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Bundle to a JSONObject, handling nested bundles and different value types.
|
||||
* This explicit conversion is necessary because Bundle is not a standard map.
|
||||
*/
|
||||
@Throws(JSONException::class)
|
||||
private fun convertJSONObject(bundle: Bundle): JSONObject {
|
||||
return JSONObject().apply {
|
||||
// Using Kotlin's for loop syntax and 'apply' scope function
|
||||
bundle.keySet().forEach { key ->
|
||||
bundle.get(key)?.let { value ->
|
||||
when (value) {
|
||||
is Bundle -> put(key, convertJSONObject(value))
|
||||
else -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
put(key, JSONObject.wrap(value))
|
||||
} else {
|
||||
put(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies about a received remote notification by sending an event to JavaScript
|
||||
*/
|
||||
fun notifyNotification(bundle: Bundle) {
|
||||
convertJSON(bundle)?.let { bundleString ->
|
||||
Arguments.createMap().apply {
|
||||
putString("dataJSON", bundleString)
|
||||
sendEvent("remoteNotificationReceived", this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies about a notification action by sending an event to JavaScript
|
||||
*/
|
||||
fun notifyNotificationAction(bundle: Bundle) {
|
||||
convertJSON(bundle)?.let { bundleString ->
|
||||
Arguments.createMap().apply {
|
||||
putString("dataJSON", bundleString)
|
||||
sendEvent("notificationActionReceived", this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an event to JavaScript if there's an active Catalyst instance
|
||||
*/
|
||||
fun sendEvent(eventName: String, params: Any) {
|
||||
if (reactContext.hasActiveCatalystInstance()) {
|
||||
reactContext
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
||||
.emit(eventName, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import im.status.ethereum.pushnotifications.PushNotification;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PushNotificationPackage implements ReactPackage {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
return Collections.<NativeModule>singletonList(new PushNotification(reactContext));
|
||||
}
|
||||
|
||||
public List<Class<? extends JavaScriptModule>> createJSModules() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import im.status.ethereum.pushnotifications.PushNotification
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.bridge.JavaScriptModule
|
||||
import com.facebook.react.bridge.NativeModule
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
|
||||
class PushNotificationPackage : ReactPackage {
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
||||
return listOf(PushNotification(reactContext))
|
||||
}
|
||||
|
||||
// Note: This function is deprecated in newer versions of React Native
|
||||
// but kept for backwards compatibility
|
||||
fun createJSModules(): List<Class<out JavaScriptModule>> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.common.executors.CallerThreadExecutor;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.datasource.DataSource;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.common.Priority;
|
||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
|
||||
import android.util.Log;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
|
||||
|
||||
public class PushNotificationPicturesAggregator {
|
||||
interface Callback {
|
||||
public void call(Bitmap largeIconImage, Bitmap bigPictureImage);
|
||||
}
|
||||
|
||||
private AtomicInteger count = new AtomicInteger(0);
|
||||
|
||||
private Bitmap largeIconImage;
|
||||
private Bitmap bigPictureImage;
|
||||
|
||||
private Callback callback;
|
||||
|
||||
public PushNotificationPicturesAggregator(Callback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setBigPicture(Bitmap bitmap) {
|
||||
this.bigPictureImage = bitmap;
|
||||
this.finished();
|
||||
}
|
||||
|
||||
public void setBigPictureUrl(Context context, String url) {
|
||||
if(null == url) {
|
||||
this.setBigPicture(null);
|
||||
return;
|
||||
}
|
||||
|
||||
Uri uri = null;
|
||||
|
||||
try {
|
||||
uri = Uri.parse(url);
|
||||
} catch(Exception ex) {
|
||||
Log.e(LOG_TAG, "Failed to parse bigPictureUrl", ex);
|
||||
this.setBigPicture(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final PushNotificationPicturesAggregator aggregator = this;
|
||||
|
||||
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
||||
aggregator.setBigPicture(bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailureImpl(DataSource dataSource) {
|
||||
aggregator.setBigPicture(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setLargeIcon(Bitmap bitmap) {
|
||||
this.largeIconImage = bitmap;
|
||||
this.finished();
|
||||
}
|
||||
|
||||
public void setLargeIconUrl(Context context, String url) {
|
||||
if(null == url) {
|
||||
this.setLargeIcon(null);
|
||||
return;
|
||||
}
|
||||
|
||||
Uri uri = null;
|
||||
|
||||
try {
|
||||
uri = Uri.parse(url);
|
||||
} catch(Exception ex) {
|
||||
Log.e(LOG_TAG, "Failed to parse largeIconUrl", ex);
|
||||
this.setLargeIcon(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final PushNotificationPicturesAggregator aggregator = this;
|
||||
|
||||
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
public void onNewResultImpl(@Nullable Bitmap bitmap) {
|
||||
aggregator.setLargeIcon(bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailureImpl(DataSource dataSource) {
|
||||
aggregator.setLargeIcon(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void downloadRequest(Context context, Uri uri, BaseBitmapDataSubscriber subscriber) {
|
||||
ImageRequest imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(uri)
|
||||
.setRequestPriority(Priority.HIGH)
|
||||
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
|
||||
.build();
|
||||
|
||||
if(!Fresco.hasBeenInitialized()) {
|
||||
Fresco.initialize(context);
|
||||
}
|
||||
|
||||
DataSource<CloseableReference<CloseableImage>> dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context);
|
||||
|
||||
dataSource.subscribe(subscriber, CallerThreadExecutor.getInstance());
|
||||
}
|
||||
|
||||
private void finished() {
|
||||
synchronized(this.count) {
|
||||
int val = this.count.incrementAndGet();
|
||||
|
||||
if(val >= 2 && this.callback != null) {
|
||||
this.callback.call(this.largeIconImage, this.bigPictureImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import androidx.annotation.Nullable
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.datasource.DataSource
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.common.Priority
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.CloseableImage
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import im.status.ethereum.pushnotifications.PushNotification.Companion.LOG_TAG
|
||||
|
||||
class PushNotificationPicturesAggregator(
|
||||
private val callback: (Bitmap?, Bitmap?) -> Unit
|
||||
) {
|
||||
private val count = AtomicInteger(0)
|
||||
private var largeIconImage: Bitmap? = null
|
||||
private var bigPictureImage: Bitmap? = null
|
||||
|
||||
fun setBigPicture(bitmap: Bitmap?) {
|
||||
bigPictureImage = bitmap
|
||||
finished()
|
||||
}
|
||||
|
||||
fun setBigPictureUrl(context: Context, url: String?) {
|
||||
if (url == null) {
|
||||
setBigPicture(null)
|
||||
return
|
||||
}
|
||||
|
||||
val uri = try {
|
||||
Uri.parse(url)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(LOG_TAG, "Failed to parse bigPictureUrl", ex)
|
||||
setBigPicture(null)
|
||||
return
|
||||
}
|
||||
|
||||
downloadRequest(context, uri, object : BaseBitmapDataSubscriber() {
|
||||
override fun onNewResultImpl(@Nullable bitmap: Bitmap?) {
|
||||
setBigPicture(bitmap)
|
||||
}
|
||||
|
||||
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
|
||||
setBigPicture(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun setLargeIcon(bitmap: Bitmap?) {
|
||||
largeIconImage = bitmap
|
||||
finished()
|
||||
}
|
||||
|
||||
fun setLargeIconUrl(context: Context, url: String?) {
|
||||
if (url == null) {
|
||||
setLargeIcon(null)
|
||||
return
|
||||
}
|
||||
|
||||
val uri = try {
|
||||
Uri.parse(url)
|
||||
} catch (ex: Exception) {
|
||||
Log.e(LOG_TAG, "Failed to parse largeIconUrl", ex)
|
||||
setLargeIcon(null)
|
||||
return
|
||||
}
|
||||
|
||||
downloadRequest(context, uri, object : BaseBitmapDataSubscriber() {
|
||||
override fun onNewResultImpl(@Nullable bitmap: Bitmap?) {
|
||||
setLargeIcon(bitmap)
|
||||
}
|
||||
|
||||
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
|
||||
setLargeIcon(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun downloadRequest(context: Context, uri: Uri, subscriber: BaseBitmapDataSubscriber) {
|
||||
val imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(uri)
|
||||
.setRequestPriority(Priority.HIGH)
|
||||
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
|
||||
.build()
|
||||
|
||||
if (!Fresco.hasBeenInitialized()) {
|
||||
Fresco.initialize(context)
|
||||
}
|
||||
|
||||
val dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context)
|
||||
dataSource.subscribe(subscriber, CallerThreadExecutor.getInstance())
|
||||
}
|
||||
|
||||
private fun finished() {
|
||||
synchronized(count) {
|
||||
if (count.incrementAndGet() >= 2) {
|
||||
callback(largeIconImage, bigPictureImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
package im.status.ethereum.pushnotifications;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentFilter;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.mockito.Spy;
|
||||
|
||||
public class PushNotificationHelperTest {
|
||||
|
||||
PushNotificationHelper helper;
|
||||
|
||||
|
||||
@Test
|
||||
public void testAddStatusMessage() {
|
||||
final Application context = mock(Application.class);
|
||||
final NotificationManager manager = mock(NotificationManager.class);
|
||||
final IntentFilter filter = mock(IntentFilter.class);
|
||||
|
||||
when(context.getSystemService(NotificationManager.class)).thenReturn(manager);
|
||||
|
||||
// Create a spy for PushNotificationHelper
|
||||
PushNotificationHelper realHelper = new PushNotificationHelper(context, filter);
|
||||
helper = spy(realHelper);
|
||||
|
||||
Bundle bundle = mock(Bundle.class);
|
||||
Bundle personBundle = mock(Bundle.class);
|
||||
|
||||
String conversationId = "conversation-id";
|
||||
String deepLink = "deep-link";
|
||||
|
||||
when(bundle.getString("conversationId")).thenReturn(conversationId);
|
||||
when(bundle.getString("id")).thenReturn("id");
|
||||
when(bundle.getString("message")).thenReturn("message");
|
||||
when(bundle.getDouble("timestamp")).thenReturn(100000.0);
|
||||
when(bundle.getString("deepLink")).thenReturn(deepLink);
|
||||
|
||||
when(personBundle.getString("name")).thenReturn("name");
|
||||
when(bundle.getBundle("notificationAuthor")).thenReturn(personBundle);
|
||||
|
||||
|
||||
doNothing().when(helper).showMessages(bundle);
|
||||
|
||||
helper.addStatusMessage(bundle);
|
||||
assertNotNull(helper.getMessageGroup(conversationId));
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package im.status.ethereum.pushnotifications
|
||||
|
||||
import android.app.Application
|
||||
import android.app.NotificationManager
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.*
|
||||
import org.mockito.Spy
|
||||
|
||||
class PushNotificationHelperTest {
|
||||
|
||||
private lateinit var helper: PushNotificationHelper
|
||||
|
||||
@Test
|
||||
fun testAddStatusMessage() {
|
||||
val context = mock(Application::class.java)
|
||||
val manager = mock(NotificationManager::class.java)
|
||||
val filter = mock(IntentFilter::class.java)
|
||||
|
||||
`when`(context.getSystemService(NotificationManager::class.java)).thenReturn(manager)
|
||||
|
||||
// Create a spy for PushNotificationHelper
|
||||
val realHelper = PushNotificationHelper(context, filter)
|
||||
helper = spy(realHelper)
|
||||
|
||||
val bundle = mock(Bundle::class.java)
|
||||
val personBundle = mock(Bundle::class.java)
|
||||
|
||||
val conversationId = "conversation-id"
|
||||
val deepLink = "deep-link"
|
||||
|
||||
`when`(bundle.getString("conversationId")).thenReturn(conversationId)
|
||||
`when`(bundle.getString("id")).thenReturn("id")
|
||||
`when`(bundle.getString("message")).thenReturn("message")
|
||||
`when`(bundle.getDouble("timestamp")).thenReturn(100000.0)
|
||||
`when`(bundle.getString("deepLink")).thenReturn(deepLink)
|
||||
|
||||
`when`(personBundle.getString("name")).thenReturn("name")
|
||||
`when`(bundle.getBundle("notificationAuthor")).thenReturn(personBundle)
|
||||
|
||||
doNothing().`when`(helper).showMessages(bundle)
|
||||
|
||||
helper.addStatusMessage(bundle)
|
||||
assertNotNull(helper.getMessageGroup(conversationId))
|
||||
}
|
||||
}
|
||||
@@ -195,36 +195,6 @@ RCT_EXPORT_METHOD(loginAccount:(NSString *)request) {
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(verify:(NSString *)address
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"VerifyAccountPasswordV2() method called");
|
||||
#endif
|
||||
NSURL *rootUrl = [Utils getRootUrl];
|
||||
NSString *keystorePath = [rootUrl.path stringByAppendingPathComponent:@"keystore"];
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"keyStoreDir": keystorePath,
|
||||
@"address": address,
|
||||
@"password": password
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"VerifyAccountPasswordV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoVerifyAccountPasswordV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
|
||||
@@ -105,48 +105,6 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeTransfer:(NSString *)to
|
||||
value:(NSString *)value) {
|
||||
NSDictionary *params = @{
|
||||
@"to": to,
|
||||
@"value": value
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return nil;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeTransferV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoEncodeTransferV2(jsonString);
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeFunctionCall:(NSString *)method
|
||||
paramsJSON:(NSString *)paramsJSON) {
|
||||
NSDictionary *params = @{
|
||||
@"method": method,
|
||||
@"paramsJSON": paramsJSON
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return nil;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeFunctionCallV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoEncodeFunctionCallV2(jsonString);
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(decodeParameters:(NSString *)decodeParamJSON) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"DecodeParameters"
|
||||
body:decodeParamJSON
|
||||
|
||||
@@ -35,6 +35,7 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
|
||||
NSURL *mainGethLogsFile = [rootUrl URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *mainLogsFile = [logsFolderName URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *preLoginLogFile = [rootUrl URLByAppendingPathComponent:@"pre_login.log"];
|
||||
|
||||
NSURL *requestsLogFile = [rootUrl URLByAppendingPathComponent:@"api.log"];
|
||||
|
||||
@@ -46,6 +47,10 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
if ([fileManager fileExistsAtPath:requestsLogFile.path]) {
|
||||
[fileManager copyItemAtPath:requestsLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"api.log"].path error:nil];
|
||||
}
|
||||
|
||||
if ([fileManager fileExistsAtPath:preLoginLogFile.path]) {
|
||||
[fileManager copyItemAtPath:preLoginLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"pre_login.log"].path error:nil];
|
||||
}
|
||||
|
||||
[SSZipArchive createZipFileAtPath:zipFile.path withContentsOfDirectory:logsFolderName.path];
|
||||
[fileManager removeItemAtPath:logsFolderName.path error:nil];
|
||||
|
||||
@@ -109,6 +109,17 @@ RCT_EXPORT_METHOD(getNodeConfig:(RCTResponseSenderBlock)callback) {
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(intendedPanic:(NSString *)message) {
|
||||
#if DEBUG
|
||||
NSLog(@"IntendedPanic() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"IntendedPanic"
|
||||
body:message
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoIntendedPanic(message);
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(fleets) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"Fleets"
|
||||
body:@""
|
||||
|
||||
@@ -389,86 +389,6 @@ void _StopCPUProfiling(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _EncodeTransfer(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 2) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeTransfer")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'to'")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[1]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'value'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
|
||||
char *arg1 = *arg1Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = EncodeTransfer(arg0, arg1);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _EncodeFunctionCall(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 2) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for EncodeFunctionCall")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'method'")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[1]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'paramsJSON'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
|
||||
char *arg1 = *arg1Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = EncodeFunctionCall(arg0, arg1);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
}
|
||||
|
||||
void _DecodeParameters(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -1380,53 +1300,6 @@ void _CallPrivateRPC(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _VerifyAccountPassword(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 3) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for VerifyAccountPassword")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
if (!args[0]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'keyStoreDir'")));
|
||||
return;
|
||||
}
|
||||
if (!args[1]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'address'")));
|
||||
return;
|
||||
}
|
||||
if (!args[2]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'password'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
char *arg0 = *arg0Obj;
|
||||
String::Utf8Value arg1Obj(isolate, args[1]->ToString(context).ToLocalChecked());
|
||||
char *arg1 = *arg1Obj;
|
||||
String::Utf8Value arg2Obj(isolate, args[2]->ToString(context).ToLocalChecked());
|
||||
char *arg2 = *arg2Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = VerifyAccountPassword(arg0, arg1, arg2);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _SendTransactionWithSignature(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -1992,8 +1865,6 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "acceptTerms", _AcceptTerms);
|
||||
NODE_SET_METHOD(exports, "fleets", _Fleets);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
NODE_SET_METHOD(exports, "encodeFunctionCall", _EncodeFunctionCall);
|
||||
NODE_SET_METHOD(exports, "decodeParameters", _DecodeParameters);
|
||||
NODE_SET_METHOD(exports, "hexToNumber", _HexToNumber);
|
||||
NODE_SET_METHOD(exports, "numberToHex", _NumberToHex);
|
||||
@@ -2017,7 +1888,6 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "openAccounts", _OpenAccounts);
|
||||
NODE_SET_METHOD(exports, "extractGroupMembershipSignatures", _ExtractGroupMembershipSignatures);
|
||||
NODE_SET_METHOD(exports, "callPrivateRPC", _CallPrivateRPC);
|
||||
NODE_SET_METHOD(exports, "verifyAccountPassword", _VerifyAccountPassword);
|
||||
NODE_SET_METHOD(exports, "sendTransactionWithSignature", _SendTransactionWithSignature);
|
||||
NODE_SET_METHOD(exports, "writeHeapProfile", _WriteHeapProfile);
|
||||
NODE_SET_METHOD(exports, "addPeer", _AddPeer);
|
||||
|
||||
+1488
-255
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ androidx.annotation:annotation:1.0.0
|
||||
androidx.annotation:annotation:1.1.0
|
||||
androidx.annotation:annotation:1.2.0
|
||||
androidx.annotation:annotation:1.3.0
|
||||
androidx.annotation:annotation:1.5.0
|
||||
androidx.annotation:annotation:1.6.0
|
||||
androidx.appcompat:appcompat-resources:1.1.0-rc01
|
||||
androidx.appcompat:appcompat-resources:1.2.0
|
||||
@@ -47,7 +48,7 @@ androidx.core:core-ktx:1.12.0
|
||||
androidx.core:core-splashscreen:1.0.0
|
||||
androidx.core:core:1.0.0
|
||||
androidx.core:core:1.1.0
|
||||
androidx.core:core:1.1.0-rc01
|
||||
androidx.core:core:1.2.0
|
||||
androidx.core:core:1.6.0
|
||||
androidx.core:core:1.9.0
|
||||
androidx.core:core:1.12.0
|
||||
@@ -81,6 +82,7 @@ androidx.fragment:fragment:1.0.0
|
||||
androidx.fragment:fragment:1.1.0
|
||||
androidx.fragment:fragment:1.1.0-rc01
|
||||
androidx.fragment:fragment:1.3.6
|
||||
androidx.fragment:fragment:1.5.7
|
||||
androidx.interpolator:interpolator:1.0.0
|
||||
androidx.legacy:legacy-support-core-ui:1.0.0
|
||||
androidx.legacy:legacy-support-core-utils:1.0.0
|
||||
@@ -110,6 +112,7 @@ androidx.lifecycle:lifecycle-viewmodel:2.1.0-rc01
|
||||
androidx.lifecycle:lifecycle-viewmodel:2.3.1
|
||||
androidx.lifecycle:lifecycle-viewmodel:2.5.1
|
||||
androidx.loader:loader:1.0.0
|
||||
androidx.loader:loader:1.1.0
|
||||
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
|
||||
androidx.media:media:1.0.0
|
||||
androidx.multidex:multidex:2.0.1
|
||||
@@ -144,7 +147,6 @@ androidx.vectordrawable:vectordrawable:1.1.0
|
||||
androidx.vectordrawable:vectordrawable:1.1.0-rc01
|
||||
androidx.versionedparcelable:versionedparcelable:1.0.0
|
||||
androidx.versionedparcelable:versionedparcelable:1.1.0
|
||||
androidx.versionedparcelable:versionedparcelable:1.1.0-rc01
|
||||
androidx.versionedparcelable:versionedparcelable:1.1.1
|
||||
androidx.viewpager2:viewpager2:1.0.0
|
||||
androidx.viewpager:viewpager:1.0.0
|
||||
@@ -571,6 +573,22 @@ com.googlecode.javaewah:JavaEWAH:1.1.12
|
||||
com.googlecode.javaewah:JavaEWAH:1.1.13
|
||||
com.googlecode.json-simple:json-simple:1.1
|
||||
com.googlecode.juniversalchardet:juniversalchardet:1.0.3
|
||||
com.google.android.datatransport:transport-api:3.0.0
|
||||
com.google.android.datatransport:transport-api:3.1.0
|
||||
com.google.android.datatransport:transport-backend-cct:3.1.9
|
||||
com.google.android.datatransport:transport-runtime:3.1.9
|
||||
com.google.android.gms:play-services-auth-api-phone:18.0.2
|
||||
com.google.android.gms:play-services-auth-base:18.0.10
|
||||
com.google.android.gms:play-services-auth:21.3.0
|
||||
com.google.android.gms:play-services-basement:18.0.0
|
||||
com.google.android.gms:play-services-basement:18.4.0
|
||||
com.google.android.gms:play-services-base:18.5.0
|
||||
com.google.android.gms:play-services-cloud-messaging:17.2.0
|
||||
com.google.android.gms:play-services-fido:20.0.1
|
||||
com.google.android.gms:play-services-stats:17.0.2
|
||||
com.google.android.gms:play-services-tasks:18.0.1
|
||||
com.google.android.gms:play-services-tasks:18.2.0
|
||||
com.google.android.gms:strict-version-matcher-plugin:1.2.4
|
||||
com.google.android.material:material:1.2.0-alpha03
|
||||
com.google.android:annotations:4.1.1.4
|
||||
com.google.api.grpc:proto-google-common-protos:1.12.0
|
||||
@@ -600,7 +618,24 @@ com.google.errorprone:error_prone_annotations:2.4.0
|
||||
com.google.errorprone:error_prone_annotations:2.7.1
|
||||
com.google.errorprone:error_prone_annotations:2.9.0
|
||||
com.google.errorprone:error_prone_annotations:2.11.0
|
||||
com.google.errorprone:error_prone_annotations:2.26.0
|
||||
com.google.firebase:firebase-annotations:16.2.0
|
||||
com.google.firebase:firebase-bom:33.8.0
|
||||
com.google.firebase:firebase-common-ktx:21.0.0
|
||||
com.google.firebase:firebase-common:21.0.0
|
||||
com.google.firebase:firebase-components:18.0.0
|
||||
com.google.firebase:firebase-datatransport:18.2.0
|
||||
com.google.firebase:firebase-encoders-json:18.0.0
|
||||
com.google.firebase:firebase-encoders-proto:16.0.0
|
||||
com.google.firebase:firebase-encoders:17.0.0
|
||||
com.google.firebase:firebase-iid-interop:17.1.0
|
||||
com.google.firebase:firebase-installations-interop:17.1.1
|
||||
com.google.firebase:firebase-installations:17.2.0
|
||||
com.google.firebase:firebase-installations:18.0.0
|
||||
com.google.firebase:firebase-measurement-connector:19.0.0
|
||||
com.google.firebase:firebase-messaging:24.1.0
|
||||
com.google.flatbuffers:flatbuffers-java:1.12.0
|
||||
com.google.gms:google-services:4.4.2
|
||||
com.google.guava:failureaccess:1.0.1
|
||||
com.google.guava:guava:17.0
|
||||
com.google.guava:guava:22.0
|
||||
@@ -662,6 +697,7 @@ com.tunnelvisionlabs:antlr4-runtime:4.5
|
||||
com.tunnelvisionlabs:antlr4:4.5
|
||||
de.undercouch:gradle-download-task:4.1.1
|
||||
de.undercouch:gradle-download-task:5.0.1
|
||||
gradle.plugin.io.invertase.gradle:react-native:1.5
|
||||
io.grpc:grpc-api:1.21.1
|
||||
io.grpc:grpc-api:1.39.0
|
||||
io.grpc:grpc-api:1.45.1
|
||||
@@ -807,7 +843,7 @@ org.glassfish.jaxb:txw2:2.2.11
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.2
|
||||
org.gradle.toolchains:foojay-resolver:0.5.0
|
||||
org.gradle:github-dependency-graph-gradle-plugin:1.3.1
|
||||
org.gradle:github-dependency-graph-gradle-plugin:1.3.2
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
org.hamcrest:hamcrest:2.2
|
||||
org.jacoco:org.jacoco.core:0.7.4.201502262128
|
||||
@@ -817,21 +853,28 @@ org.jetbrains.dokka:dokka-core:1.4.32
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20181211
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330
|
||||
org.jetbrains.kotlinx:atomicfu:0.16.3
|
||||
org.jetbrains.kotlinx:atomicfu:0.17.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.9.0
|
||||
@@ -913,6 +956,7 @@ org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71
|
||||
@@ -925,6 +969,7 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.71
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50
|
||||
@@ -935,6 +980,7 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.2.71
|
||||
@@ -947,6 +993,7 @@ org.jetbrains.kotlin:kotlin-stdlib:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.22
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:1.8.0
|
||||
@@ -1021,5 +1068,5 @@ xml-apis:xml-apis:1.4.01
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
|
||||
com.android.tools.build:gradle:3.5.4
|
||||
com.facebook.react:hermes-android:0.73.5
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
com.facebook.react:hermes-android:0.73.5
|
||||
+108
-29
@@ -2,6 +2,7 @@ https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.0.0-rc01/ac
|
||||
https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.0.0/activity-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.1.0/activity-1.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.2.4/activity-1.2.4.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.5.1/activity-1.5.1.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/activity/activity/1.6.0/activity-1.6.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation-experimental/1.0.0/annotation-experimental-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation-experimental/1.1.0/annotation-experimental-1.1.0.pom
|
||||
@@ -14,6 +15,7 @@ https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.1.0-rc0
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.1.0/annotation-1.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.2.0/annotation-1.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.3.0/annotation-1.3.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.5.0/annotation-1.5.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/annotation/annotation/1.6.0/annotation-1.6.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/appcompat/appcompat-resources/1.1.0-rc01/appcompat-resources-1.1.0-rc01.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/appcompat/appcompat-resources/1.1.0/appcompat-resources-1.1.0.pom
|
||||
@@ -100,6 +102,7 @@ https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.1.0-rc01/fr
|
||||
https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.1.0/fragment-1.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.2.5/fragment-1.2.5.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.3.6/fragment-1.3.6.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/fragment/fragment/1.5.7/fragment-1.5.7.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/interpolator/interpolator/1.0.0/interpolator-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/legacy/legacy-support-core-ui/1.0.0/legacy-support-core-ui-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/legacy/legacy-support-core-utils/1.0.0/legacy-support-core-utils-1.0.0.pom
|
||||
@@ -138,6 +141,7 @@ https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel/2
|
||||
https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel/2.3.1/lifecycle-viewmodel-2.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel/2.5.1/lifecycle-viewmodel-2.5.1.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/loader/loader/1.0.0/loader-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/loader/loader/1.1.0/loader-1.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/localbroadcastmanager/localbroadcastmanager/1.0.0/localbroadcastmanager-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/media/media/1.0.0/media-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/androidx/multidex/multidex/2.0.1/multidex-2.0.1.pom
|
||||
@@ -210,15 +214,21 @@ https://dl.google.com/dl/android/maven2/com/android/support/support-annotations/
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-annotations/26.1.0/support-annotations-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-annotations/27.0.1/support-annotations-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-compat/26.0.2/support-compat-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-compat/26.1.0/support-compat-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-compat/27.0.1/support-compat-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-ui/26.0.2/support-core-ui-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-ui/26.1.0/support-core-ui-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-ui/27.0.1/support-core-ui-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-utils/26.0.2/support-core-utils-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-utils/26.1.0/support-core-utils-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-core-utils/27.0.1/support-core-utils-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-fragment/26.0.2/support-fragment-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-fragment/26.1.0/support-fragment-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-fragment/27.0.1/support-fragment-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-media-compat/26.0.2/support-media-compat-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-media-compat/26.1.0/support-media-compat-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-v4/26.0.2/support-v4-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-v4/26.1.0/support-v4-26.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-vector-drawable/26.0.2/support-vector-drawable-26.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/support/support-vector-drawable/27.0.1/support-vector-drawable-27.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/26.2.1/crash-26.2.1.pom
|
||||
@@ -531,8 +541,62 @@ https://dl.google.com/dl/android/maven2/com/android/zipflinger/7.2.1/zipflinger-
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/7.3.1/zipflinger-7.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/7.4.2/zipflinger-7.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/8.1.1/zipflinger-8.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-api/3.0.0/transport-api-3.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-api/3.1.0/transport-api-3.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-backend-cct/3.1.8/transport-backend-cct-3.1.8.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-backend-cct/3.1.9/transport-backend-cct-3.1.9.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-runtime/3.1.8/transport-runtime-3.1.8.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/datatransport/transport-runtime/3.1.9/transport-runtime-3.1.9.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-auth-api-phone/18.0.2/play-services-auth-api-phone-18.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-auth-base/18.0.10/play-services-auth-base-18.0.10.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-auth/21.3.0/play-services-auth-21.3.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/16.0.1/play-services-basement-16.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/17.0.0/play-services-basement-17.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.0.0/play-services-basement-18.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.0.2/play-services-basement-18.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.1.0/play-services-basement-18.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.2.0/play-services-basement-18.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.3.0/play-services-basement-18.3.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-basement/18.4.0/play-services-basement-18.4.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-base/18.0.1/play-services-base-18.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-base/18.5.0/play-services-base-18.5.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-cloud-messaging/17.2.0/play-services-cloud-messaging-17.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-fido/20.0.1/play-services-fido-20.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-stats/17.0.2/play-services-stats-17.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/16.0.1/play-services-tasks-16.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/17.0.0/play-services-tasks-17.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/18.0.1/play-services-tasks-18.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/18.0.2/play-services-tasks-18.0.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/18.1.0/play-services-tasks-18.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/play-services-tasks/18.2.0/play-services-tasks-18.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/gms/strict-version-matcher-plugin/1.2.4/strict-version-matcher-plugin-1.2.4.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.0.0/material-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.2.0-alpha03/material-1.2.0-alpha03.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-annotations/16.0.0/firebase-annotations-16.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-annotations/16.1.0/firebase-annotations-16.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-annotations/16.2.0/firebase-annotations-16.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-bom/33.8.0/firebase-bom-33.8.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-common-ktx/20.4.2/firebase-common-ktx-20.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-common-ktx/21.0.0/firebase-common-ktx-21.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-common/20.3.3/firebase-common-20.3.3.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-common/20.4.2/firebase-common-20.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-common/21.0.0/firebase-common-21.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-components/17.1.0/firebase-components-17.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-components/17.1.3/firebase-components-17.1.3.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-components/17.1.5/firebase-components-17.1.5.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-components/18.0.0/firebase-components-18.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-datatransport/18.2.0/firebase-datatransport-18.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-encoders-json/18.0.0/firebase-encoders-json-18.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-encoders-proto/16.0.0/firebase-encoders-proto-16.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-encoders/17.0.0/firebase-encoders-17.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-iid-interop/17.1.0/firebase-iid-interop-17.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-installations-interop/17.1.0/firebase-installations-interop-17.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-installations-interop/17.1.1/firebase-installations-interop-17.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-installations/17.2.0/firebase-installations-17.2.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-installations/18.0.0/firebase-installations-18.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-measurement-connector/19.0.0/firebase-measurement-connector-19.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/firebase/firebase-messaging/24.1.0/firebase-messaging-24.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/gms/google-services/4.4.2/google-services-4.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/prefab/cli/2.0.0/cli-2.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/android-device-provider-local/0.0.8-alpha08/android-device-provider-local-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/android-driver-instrumentation/0.0.8-alpha08/android-driver-instrumentation-0.0.8-alpha08.pom
|
||||
@@ -552,7 +616,9 @@ https://jitpack.io/com/github/wix-playground/reflow-animator/1.0.6/reflow-animat
|
||||
https://jitpack.io/com/github/yalantis/ucrop/2.2.6-native/ucrop-2.2.6-native.pom
|
||||
https://jitpack.io/com/github/zacharee/AndroidPdfViewer/4.0.1/AndroidPdfViewer-4.0.1.pom
|
||||
https://plugins.gradle.org/m2/com/adarshr/gradle-test-logger-plugin/2.0.0/gradle-test-logger-plugin-2.0.0.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/github-dependency-graph-gradle-plugin/1.3.1/github-dependency-graph-gradle-plugin-1.3.1.pom
|
||||
https://plugins.gradle.org/m2/gradle/plugin/io/invertase/gradle/react-native/1.5/react-native-1.5.pom
|
||||
https://plugins.gradle.org/m2/io/invertase/gradle/build/io.invertase.gradle.build.gradle.plugin/1.5/io.invertase.gradle.build.gradle.plugin-1.5.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/github-dependency-graph-gradle-plugin/1.3.2/github-dependency-graph-gradle-plugin-1.3.2.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/toolchains/foojay-resolver-convention/org.gradle.toolchains.foojay-resolver-convention.gradle.plugin/0.5.0/org.gradle.toolchains.foojay-resolver-convention.gradle.plugin-0.5.0.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/toolchains/foojay-resolver/0.5.0/foojay-resolver-0.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/antlr/antlr/2.7.1/antlr-2.7.1.pom
|
||||
@@ -562,12 +628,12 @@ https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.6/commons-cod
|
||||
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.9/commons-codec-1.9.pom
|
||||
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.10/commons-codec-1.10.pom
|
||||
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.11/commons-codec-1.11.pom
|
||||
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.17.1/commons-codec-1.17.1.pom
|
||||
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.18.0/commons-codec-1.18.0.pom
|
||||
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.4/commons-io-2.4.pom
|
||||
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.18.0/commons-io-2.18.0.pom
|
||||
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
|
||||
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.pom
|
||||
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.4/commons-logging-1.3.4.pom
|
||||
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.5/commons-logging-1.3.5.pom
|
||||
https://repo.maven.apache.org/maven2/com/adobe/xmp/xmpcore/6.1.11/xmpcore-6.1.11.pom
|
||||
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/commons/0.9.6.0/commons-0.9.6.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/core/0.9.6.0/core-0.9.6.0.pom
|
||||
@@ -726,7 +792,7 @@ https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.8.5/gson
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.8.6/gson-parent-2.8.6.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.8.9/gson-parent-2.8.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.9.1/gson-parent-2.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.11.0/gson-parent-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.12.1/gson-parent-2.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.2.4/gson-2.2.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.3/gson-2.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.7/gson-2.7.pom
|
||||
@@ -735,7 +801,7 @@ https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.5/gson-2.8.5.
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.8.9/gson-2.8.9.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.9.1/gson-2.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.12.1/gson-2.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/crypto/tink/tink/1.3.0-rc2/tink-1.3.0-rc2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/crypto/tink/tink/1.7.0/tink-1.7.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/dagger/dagger/2.28.3/dagger-2.28.3.pom
|
||||
@@ -750,7 +816,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotatio
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.9.0/error_prone_annotations-2.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.10.0/error_prone_annotations-2.10.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.26.0/error_prone_annotations-2.26.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
|
||||
@@ -763,7 +829,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.9.0/error_prone_parent-2.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.10.0/error_prone_parent-2.10.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.11.0/error_prone_parent-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.27.0/error_prone_parent-2.27.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.26.0/error_prone_parent-2.26.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.36.0/error_prone_parent-2.36.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/flatbuffers/flatbuffers-java/1.12.0/flatbuffers-java-1.12.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
|
||||
@@ -781,8 +847,8 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-jre/guav
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-android/guava-parent-31.0.1-android.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-jre/guava-parent-31.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.1-jre/guava-parent-31.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/33.3.1-jre/guava-parent-33.3.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/33.3.1-jre/guava-testlib-33.3.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/33.4.0-jre/guava-parent-33.4.0-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/33.4.0-jre/guava-testlib-33.4.0-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/17.0/guava-17.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/22.0/guava-22.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/23.0/guava-23.0.pom
|
||||
@@ -795,7 +861,7 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-jre/guava-30.1-
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-android/guava-31.0.1-android.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/33.3.1-jre/guava-33.3.1-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/guava/33.4.0-jre/guava-33.4.0-jre.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/1.0/listenablefuture-1.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.pom
|
||||
@@ -809,7 +875,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.13.0/pro
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.17.2/protobuf-bom-3.17.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.19.2/protobuf-bom-3.19.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.19.3/protobuf-bom-3.19.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/4.29.0/protobuf-bom-4.29.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/4.30.0-RC1/protobuf-bom-4.30.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-javalite/3.17.2/protobuf-javalite-3.17.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-javalite/3.19.2/protobuf-javalite-3.19.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java-util/3.4.0/protobuf-java-util-3.4.0.pom
|
||||
@@ -826,7 +892,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.13.0/pr
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.17.2/protobuf-java-3.17.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.19.2/protobuf-java-3.19.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.19.3/protobuf-java-3.19.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/4.29.0/protobuf-java-4.29.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/4.30.0-RC1/protobuf-java-4.30.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-lite/3.0.1/protobuf-lite-3.0.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.0.0/protobuf-parent-3.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.4.0/protobuf-parent-3.4.0.pom
|
||||
@@ -837,7 +903,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.13.0/
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.17.2/protobuf-parent-3.17.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.19.2/protobuf-parent-3.19.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.19.3/protobuf-parent-3.19.3.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/4.29.0/protobuf-parent-4.29.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/4.30.0-RC1/protobuf-parent-4.30.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/truth/truth-parent/1.4.4/truth-parent-1.4.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/truth/truth/1.4.4/truth-1.4.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/zxing/core/3.4.1/core-3.4.1.pom
|
||||
@@ -858,13 +924,13 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.11.0/okhttp-4
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.2.0/okio-jvm-3.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.1/okio-jvm-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.10.2/okio-jvm-3.10.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.17.4/okio-parent-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.2.0/okio-3.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.1/okio-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.10.2/okio-3.10.2.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.1/all-1.2.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.2/all-1.2.2.pom
|
||||
@@ -971,9 +1037,9 @@ https://repo.maven.apache.org/maven2/io/netty/netty-resolver/4.1.52.Final/netty-
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-resolver/4.1.72.Final/netty-resolver-4.1.72.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-resolver/5.0.0.Alpha2/netty-resolver-5.0.0.Alpha2.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.46.Final/netty-tcnative-classes-2.0.46.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.69.Final/netty-tcnative-classes-2.0.69.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.70.Final/netty-tcnative-classes-2.0.70.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.46.Final/netty-tcnative-parent-2.0.46.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.69.Final/netty-tcnative-parent-2.0.69.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.70.Final/netty-tcnative-parent-2.0.70.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.34.Final/netty-transport-4.1.34.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.52.Final/netty-transport-4.1.52.Final.pom
|
||||
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.72.Final/netty-transport-4.1.72.Final.pom
|
||||
@@ -1006,15 +1072,15 @@ https://repo.maven.apache.org/maven2/junit/junit/4.13.2/junit-4.13.2.pom
|
||||
https://repo.maven.apache.org/maven2/me/zhanghai/android/materialprogressbar/library/1.4.2/library-1.4.2.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.11.13/byte-buddy-agent-1.11.13.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.11.19/byte-buddy-agent-1.11.19.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.15.4/byte-buddy-agent-1.15.4.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.15.11/byte-buddy-agent-1.15.11.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.11.13/byte-buddy-parent-1.11.13.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.11.19/byte-buddy-parent-1.11.19.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.15.4/byte-buddy-parent-1.15.4.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.15.10/byte-buddy-parent-1.15.10.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-parent/1.15.11/byte-buddy-parent-1.15.11.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.11.13/byte-buddy-1.11.13.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.11.19/byte-buddy-1.11.19.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.15.4/byte-buddy-1.15.4.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.15.10/byte-buddy-1.15.10.pom
|
||||
https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.15.11/byte-buddy-1.15.11.pom
|
||||
https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.6.0/jna-platform-5.6.0.pom
|
||||
https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom
|
||||
https://repo.maven.apache.org/maven2/net/java/jvnet-parent/1/jvnet-parent-1.pom
|
||||
@@ -1058,7 +1124,6 @@ https://repo.maven.apache.org/maven2/org/apache/apache/16/apache-16.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/apache/18/apache-18.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/apache/21/apache-21.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/apache/23/apache-23.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/apache/32/apache-32.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/apache/33/apache-33.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.12/commons-compress-1.12.pom
|
||||
@@ -1078,9 +1143,9 @@ https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/39/common
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/42/commons-parent-42.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/48/commons-parent-48.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/52/commons-parent-52.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/71/commons-parent-71.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/72/commons-parent-72.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/78/commons-parent-78.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/79/commons-parent-79.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/81/commons-parent-81.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.2.6/httpclient-4.2.6.pom
|
||||
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.pom
|
||||
@@ -1135,7 +1200,7 @@ https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.8.1/che
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.11.1/checker-qual-2.11.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.5.0/checker-qual-3.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.48.2/checker-qual-3.48.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.49.0/checker-qual-3.49.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-xml/3.0.9/groovy-xml-3.0.9.pom
|
||||
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-xml/3.0.10/groovy-xml-3.0.10.pom
|
||||
@@ -1206,24 +1271,32 @@ https://repo.maven.apache.org/maven2/org/jetbrains/dokka/dokka-core/1.4.32/dokka
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20181211/trove4j-1.0.20181211.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/atomicfu-jvm/0.16.3/atomicfu-jvm-0.16.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/atomicfu-jvm/0.17.3/atomicfu-jvm-0.17.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/atomicfu/0.16.3/atomicfu-0.16.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/atomicfu/0.17.3/atomicfu-0.17.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.5.2/kotlinx-coroutines-android-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.6.1/kotlinx-coroutines-android-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.6.4/kotlinx-coroutines-android-1.6.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.7.3/kotlinx-coroutines-android-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.6.1/kotlinx-coroutines-bom-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.6.3/kotlinx-coroutines-bom-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.6.4/kotlinx-coroutines-bom-1.6.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.7.3/kotlinx-coroutines-bom-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.4.1/kotlinx-coroutines-core-jvm-1.4.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.2/kotlinx-coroutines-core-jvm-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.6.1/kotlinx-coroutines-core-jvm-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.6.3/kotlinx-coroutines-core-jvm-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.6.4/kotlinx-coroutines-core-jvm-1.6.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.7.3/kotlinx-coroutines-core-jvm-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.4.1/kotlinx-coroutines-core-1.4.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.5.2/kotlinx-coroutines-core-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.6.1/kotlinx-coroutines-core-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.6.3/kotlinx-coroutines-core-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.6.4/kotlinx-coroutines-core-1.6.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.7.3/kotlinx-coroutines-core-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-play-services/1.6.4/kotlinx-coroutines-play-services-1.6.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-play-services/1.7.3/kotlinx-coroutines-play-services-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.1.0/kotlinx-metadata-jvm-0.1.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.8.0/org.jetbrains.kotlin.jvm.gradle.plugin-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-android-extensions/1.6.20/kotlin-android-extensions-1.6.20.pom
|
||||
@@ -1285,7 +1358,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.10/
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.20/kotlin-reflect-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.7.10/kotlin-reflect-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.8.20-RC2/kotlin-reflect-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/2.1.0/kotlin-reflect-2.1.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/2.1.20-RC/kotlin-reflect-2.1.20-RC.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.20/kotlin-scripting-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.8.0/kotlin-scripting-common-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.0/kotlin-scripting-common-1.9.0.pom
|
||||
@@ -1321,6 +1394,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.20/kotlin-stdlib-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.21/kotlin-stdlib-common-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.10/kotlin-stdlib-common-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.22/kotlin-stdlib-common-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.20-RC2/kotlin-stdlib-common-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.20/kotlin-stdlib-common-1.8.20.pom
|
||||
@@ -1341,10 +1415,12 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.20/kotlin-stdlib-jdk7-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.21/kotlin-stdlib-jdk7-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.10/kotlin-stdlib-jdk7-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.22/kotlin-stdlib-jdk7-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.20-RC2/kotlin-stdlib-jdk7-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.20/kotlin-stdlib-jdk7-1.8.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.21/kotlin-stdlib-jdk7-1.8.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.22/kotlin-stdlib-jdk7-1.8.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.0/kotlin-stdlib-jdk7-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.2.71/kotlin-stdlib-jdk8-1.2.71.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.50/kotlin-stdlib-jdk8-1.3.50.pom
|
||||
@@ -1359,10 +1435,12 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.20/kotlin-stdlib-jdk8-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.21/kotlin-stdlib-jdk8-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.10/kotlin-stdlib-jdk8-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.22/kotlin-stdlib-jdk8-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.20-RC2/kotlin-stdlib-jdk8-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.20/kotlin-stdlib-jdk8-1.8.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.21/kotlin-stdlib-jdk8-1.8.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.22/kotlin-stdlib-jdk8-1.8.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.0/kotlin-stdlib-jdk8-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.1.3-2/kotlin-stdlib-1.1.3-2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.0/kotlin-stdlib-1.2.0.pom
|
||||
@@ -1387,6 +1465,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.10/k
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.20/kotlin-stdlib-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.21/kotlin-stdlib-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.10/kotlin-stdlib-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.22/kotlin-stdlib-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.20-RC2/kotlin-stdlib-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.20/kotlin-stdlib-1.8.20.pom
|
||||
@@ -1394,8 +1473,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/k
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.22/kotlin-stdlib-1.8.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/kotlin-stdlib-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.25/kotlin-stdlib-1.9.25.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/2.1.0/kotlin-stdlib-2.1.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/2.1.20-RC/kotlin-stdlib-2.1.20-RC.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-core/1.8.0/kotlin-tooling-core-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.0/kotlin-tooling-core-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.20/kotlin-tooling-metadata-1.6.20.pom
|
||||
@@ -1409,17 +1488,17 @@ https://repo.maven.apache.org/maven2/org/jetbrains/markdown-jvm/0.2.1/markdown-j
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/markdown/0.2.1/markdown-0.2.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.pom
|
||||
https://repo.maven.apache.org/maven2/org/json/json/20180813/json-20180813.pom
|
||||
https://repo.maven.apache.org/maven2/org/json/json/20240303/json-20240303.pom
|
||||
https://repo.maven.apache.org/maven2/org/json/json/20250107/json-20250107.pom
|
||||
https://repo.maven.apache.org/maven2/org/jsoup/jsoup/1.13.1/jsoup-1.13.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.11.3/junit-bom-5.11.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.12.0-RC2/junit-bom-5.12.0-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.7.7/stax-ex-1.7.7.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8.1/stax-ex-1.8.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8/stax-ex-1.8.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/2.1.0/stax-ex-2.1.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/3.12.4/mockito-core-3.12.4.pom
|
||||
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/4.0.0/mockito-core-4.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.14.2/mockito-core-5.14.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.15.2/mockito-core-5.15.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/mockito/mockito-inline/4.0.0/mockito-inline-4.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.2/objenesis-parent-3.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/objenesis/objenesis-parent/3.3/objenesis-parent-3.3.pom
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Fallback versions for each dependency
|
||||
readonly FOOJAY_FALLBACK="0.5.0"
|
||||
readonly KOTLIN_FALLBACK="1.8.0"
|
||||
readonly TOOLS_FALLBACK="3.5.4"
|
||||
readonly HERMES_FALLBACK="0.73.5"
|
||||
readonly GRADLE_LINT_FALLBACK="31.1.1"
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
cd "${GIT_ROOT}"
|
||||
|
||||
get_version() {
|
||||
local file="$1"
|
||||
local pattern="$2"
|
||||
local fallback="$3"
|
||||
local version
|
||||
|
||||
if [[ ! -f "$file" ]]; then
|
||||
echo "$fallback"
|
||||
return 0
|
||||
fi
|
||||
|
||||
version=$(grep "$pattern" "$file" 2>/dev/null | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.*[0-9]*" | tail -n1 || echo "$fallback")
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
# https://github.com/googlesamples/android-custom-lint-rules/blob/be672cd747ecf13844918e1afccadb935f856a72/docs/api-guide/example.md.html#L112-L129
|
||||
get_gradle_lint_version() {
|
||||
gradlePluginVersion=$(get_version "./nix/pkgs/aapt2/default.nix" "version =" $GRADLE_LINT_FALLBACK)
|
||||
major=$(echo "$gradlePluginVersion" | grep -o "^[0-9]*")
|
||||
# lintVersion = gradlePluginVersion + 23.0.0
|
||||
major=$((major + 23))
|
||||
minor=$(echo "$gradlePluginVersion" | grep -o "\.[0-9]*\." | grep -o "[0-9]*")
|
||||
patch=$(echo "$gradlePluginVersion" | grep -o "[0-9]*$")
|
||||
|
||||
echo "$major.$minor.$patch"
|
||||
}
|
||||
|
||||
foojay_version=$(get_version "./node_modules/@react-native/gradle-plugin/settings.gradle.kts" "foojay.*version" "$FOOJAY_FALLBACK")
|
||||
kotlin_version=$(get_version "./node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml" "kotlin =" "$KOTLIN_FALLBACK")
|
||||
tools_version=$(get_version "./patches/BlurView-build.gradle.patch" "gradle:" "$TOOLS_FALLBACK")
|
||||
hermes_version=$(get_version "./node_modules/react-native/ReactAndroid/gradle.properties" "VERSION_NAME" "$HERMES_FALLBACK")
|
||||
lint_version=$(get_gradle_lint_version)
|
||||
|
||||
cat << EOF
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:$foojay_version
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:$kotlin_version
|
||||
com.android.tools.build:gradle:$tools_version
|
||||
com.facebook.react:hermes-android:$hermes_version
|
||||
com.android.tools.lint:lint-gradle:$lint_version
|
||||
EOF
|
||||
@@ -38,16 +38,10 @@ function gen_deps_list() {
|
||||
echo -e "${CLR}Found ${GRN}$(wc -l < "${DEPS_LIST}")${RST} direct dependencies..."
|
||||
}
|
||||
|
||||
# FIXME: Temporary fix for missing packages.
|
||||
# FIXME: Fix for missing packages.
|
||||
# https://github.com/status-im/status-mobile/issues/15447
|
||||
function add_deps_hack() {
|
||||
echo -n \
|
||||
'org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
|
||||
com.android.tools.build:gradle:3.5.4
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
com.facebook.react:hermes-android:0.73.5' \
|
||||
>> "${DEPS_LIST}"
|
||||
"${CUR_DIR}/deps_hack.sh" >> "${DEPS_LIST}"
|
||||
}
|
||||
|
||||
# Find download URLs for each dependency.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script generates a list of dependencies for the main project and its
|
||||
# sub-projects defined using Gradle config files. It parses Gradle output of
|
||||
# 'dependencies' and 'buildEnvironment` tasks using AWK.
|
||||
# sub-projects defined using Gradle config files. It uses github-dependency-graph-gradle-plugin:
|
||||
# https://github.com/gradle/github-dependency-graph-gradle-plugin?tab=readme-ov-file#using-the-plugin-to-generate-dependency-reports
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ react-native-community_slider
|
||||
react-native-config
|
||||
react-native-dialogs
|
||||
react-native-fast-image
|
||||
react-native-firebase_app
|
||||
react-native-firebase_messaging
|
||||
react-native-fs
|
||||
react-native-gesture-handler
|
||||
react-native-get-random-values
|
||||
|
||||
@@ -71,7 +71,7 @@ in stdenv.mkDerivation rec {
|
||||
};
|
||||
};
|
||||
|
||||
buildInputs = with pkgs; [ nodejs openjdk ];
|
||||
buildInputs = with pkgs; [ nodejs openjdk_headless ];
|
||||
nativeBuildInputs = with pkgs; [ bash gradle unzip ]
|
||||
++ lib.optionals stdenv.isDarwin [ file gnumake ];
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ rec {
|
||||
|
||||
shell = mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
openjdk
|
||||
openjdk_headless
|
||||
gradle
|
||||
lsof # used in start-react-native.sh
|
||||
flock # used in nix/scripts/node_modules.sh
|
||||
|
||||
@@ -38,7 +38,7 @@ stdenv.mkDerivation {
|
||||
];
|
||||
};
|
||||
};
|
||||
buildInputs = with pkgs; [ clojure nodejs bash git openjdk];
|
||||
buildInputs = with pkgs; [ clojure nodejs bash git openjdk_headless ];
|
||||
phases = [
|
||||
"unpackPhase" "secretsPhase" "patchPhase"
|
||||
"configurePhase" "buildPhase" "installPhase"
|
||||
|
||||
+8
-19
@@ -49,29 +49,18 @@ in {
|
||||
nodejs = super.nodejs_20;
|
||||
ruby = super.ruby_3_1;
|
||||
yarn = super.yarn.override { nodejs = super.nodejs_20; };
|
||||
openjdk = super.openjdk17_headless;
|
||||
openjdk_headless = super.openjdk17_headless;
|
||||
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
|
||||
versions = ["15.1" "15.2" "15.3" "15.4"];
|
||||
versions = ["16.0" "16.1" "16.2"];
|
||||
};
|
||||
go = super.go_1_21;
|
||||
go = super.go_1_22;
|
||||
clang = super.clang_15;
|
||||
buildGoPackage = super.buildGo121Package;
|
||||
buildGoModule = super.buildGo121Module;
|
||||
gomobile = (super.gomobile.overrideAttrs (old: {
|
||||
patches = [
|
||||
(self.fetchurl { # https://github.com/golang/mobile/pull/84
|
||||
url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
|
||||
sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
|
||||
})
|
||||
(self.fetchurl { # https://github.com/golang/go/issues/58426
|
||||
url = "https://github.com/golang/mobile/commit/406ed3a7b8e44dc32844953647b49696d8847d51.patch";
|
||||
sha256 = "sha256-dqbYukHkQEw8npOkKykOAzMC3ot/Y4DEuh7fE+ptlr8=";
|
||||
})
|
||||
];
|
||||
})).override {
|
||||
# FIXME: No Android SDK packages for aarch64-darwin.
|
||||
withAndroidPkgs = stdenv.system != "aarch64-darwin";
|
||||
buildGoPackage = super.buildGo122Package;
|
||||
buildGoModule = super.buildGo122Module;
|
||||
gomobile = callPackage ./pkgs/gomobile {
|
||||
#FIXME: No Android SDK packages for aarch64-darwin.
|
||||
androidPkgs = self.androidEnvCustom.compose;
|
||||
withAndroidPkgs = stdenv.system != "aarch64-darwin";
|
||||
};
|
||||
|
||||
# Android environment
|
||||
|
||||
@@ -10,6 +10,7 @@ let
|
||||
|
||||
pname = "aapt2";
|
||||
# Warning: This must be the same as gradlePluginVersion android/gradle.properties
|
||||
# also referenced in nix/deps/gradle/deps_hack.sh
|
||||
version = "8.1.1-10154469";
|
||||
|
||||
pkgPath = "com/android/tools/build/aapt2";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{ mkShell, openjdk, androidPkgs }:
|
||||
{ mkShell, openjdk_headless, androidPkgs }:
|
||||
|
||||
mkShell {
|
||||
name = "android-sdk-shell";
|
||||
buildInputs = [ openjdk ];
|
||||
buildInputs = [ openjdk_headless ];
|
||||
|
||||
shellHook = ''
|
||||
export ANDROID_HOME="${androidPkgs.sdk}"
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
fetchgit,
|
||||
fetchurl,
|
||||
buildGo122Module,
|
||||
zlib,
|
||||
makeWrapper,
|
||||
xcodeenv,
|
||||
androidenv,
|
||||
xcodeWrapperArgs ? { },
|
||||
xcodeWrapper ? xcodeenv.composeXcodeWrapper xcodeWrapperArgs,
|
||||
withAndroidPkgs ? stdenv.system != "aarch64-darwin",
|
||||
androidPkgs ? (
|
||||
androidenv.composeAndroidPackages {
|
||||
includeNDK = true;
|
||||
}
|
||||
),
|
||||
}:
|
||||
buildGo122Module {
|
||||
pname = "gomobile";
|
||||
version = "0-unstable-2024-12-13";
|
||||
|
||||
src = fetchgit {
|
||||
name = "gomobile";
|
||||
url = "https://go.googlesource.com/mobile";
|
||||
rev = "a87c1cf6cf463f0d4476cfe0fcf67c2953d76e7c";
|
||||
hash = "sha256-7j4rdmCZMC8tn4vAsC9x/mMNkom/+Tl7uAY+5gkSvfY=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-6ycxEDEE0/i6Lxo0gb8wq3U2U7Q49AJj+PdzSl57wwI=";
|
||||
|
||||
CGO_ENABLED = "1";
|
||||
|
||||
subPackages = [
|
||||
"bind"
|
||||
"cmd/gobind"
|
||||
"cmd/gomobile"
|
||||
];
|
||||
|
||||
# Fails with: go: cannot find GOROOT directory
|
||||
doCheck = false;
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ xcodeWrapper ];
|
||||
|
||||
# Prevent a non-deterministic temporary directory from polluting the resulting object files
|
||||
postPatch = ''
|
||||
substituteInPlace cmd/gomobile/env.go --replace-quiet \
|
||||
'tmpdir, err = ioutil.TempDir("", "gomobile-work-")' \
|
||||
'tmpdir = filepath.Join(os.Getenv("NIX_BUILD_TOP"), "gomobile-work")'
|
||||
substituteInPlace cmd/gomobile/init.go --replace-quiet \
|
||||
'tmpdir, err = ioutil.TempDir(gomobilepath, "work-")' \
|
||||
'tmpdir = filepath.Join(os.Getenv("NIX_BUILD_TOP"), "work")'
|
||||
|
||||
# To fix unable to import bind: no Go package in golang.org/x/mobile/bind
|
||||
substituteInPlace cmd/gomobile/init.go --replace \
|
||||
'golang.org/x/mobile/cmd/gobind@latest' \
|
||||
'golang.org/x/mobile/cmd/gobind'
|
||||
'';
|
||||
|
||||
# Necessary for GOPATH when using gomobile.
|
||||
postInstall = ''
|
||||
mkdir -p $out/src/golang.org/x
|
||||
ln -s $src $out/src/golang.org/x/mobile
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
for prog in gomobile gobind; do
|
||||
wrapProgram $out/bin/$prog \
|
||||
--suffix GOPATH : $out \
|
||||
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ zlib ]}" \
|
||||
${lib.optionalString withAndroidPkgs ''
|
||||
--prefix PATH : "${androidPkgs.androidsdk}/bin" \
|
||||
--set-default ANDROID_HOME "${androidPkgs.androidsdk}/libexec/android-sdk"
|
||||
''}
|
||||
done
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Tool for building and running mobile apps written in Go";
|
||||
homepage = "https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile";
|
||||
license = with lib.licenses; [ bsd3 ];
|
||||
maintainers = with lib.maintainers; [ jakubgs ];
|
||||
};
|
||||
}
|
||||
+2
-2
@@ -38,8 +38,8 @@ nix_install_type() {
|
||||
"${UID}") echo "single";;
|
||||
"(${UID})") echo "single";;
|
||||
"") echo "none";
|
||||
echo "No Nix installtion detected!" >&2;;
|
||||
*) echo "Unknown Nix installtion type!" >&2; exit 1;;
|
||||
echo "No Nix installation detected!" >&2;;
|
||||
*) echo "Unknown Nix installation type!" >&2; exit 1;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
export NIX_VERSION="2.19.3"
|
||||
export NIX_PACKAGE="nixVersions.nix_2_19"
|
||||
export NIX_VERSION="2.24.11"
|
||||
export NIX_PACKAGE="nixVersions.nix_2_24"
|
||||
export NIX_INSTALL_URL="https://nixos.org/releases/nix/nix-${NIX_VERSION}/install"
|
||||
export NIX_INSTALL_SHA256="73d47b0ab783fddca1b2d44a03d52a74c97c28a1fc8ff5a29419079302ef9c3d"
|
||||
export NIX_INSTALL_SHA256="5c610a0e97c8a2dd48c1a630608502e43fdecd7d2572463dd4166126106d9188"
|
||||
export NIX_INSTALL_PATH="/tmp/nix-install-${NIX_VERSION}"
|
||||
|
||||
@@ -38,6 +38,9 @@ in mkShell {
|
||||
LANG="en_US.UTF-8";
|
||||
LANGUAGE="en_US.UTF-8";
|
||||
|
||||
# Important to load our own Nix binary cache.
|
||||
NIX_CONFIG = builtins.readFile ./nix.conf;
|
||||
|
||||
# just a nicety for easy access to node scripts
|
||||
shellHook = ''
|
||||
export STATUS_MOBILE_HOME=$(git rev-parse --show-toplevel)
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ let
|
||||
# for calling clojure targets in CI or Makefile
|
||||
clojure = mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
clojure flock maven openjdk
|
||||
clojure flock maven openjdk_headless
|
||||
# lint specific utilities
|
||||
babashka clj-kondo clojure-lsp ripgrep zprint
|
||||
];
|
||||
@@ -61,7 +61,7 @@ let
|
||||
|
||||
# for 'scripts/generate-keystore.sh'
|
||||
keytool = mkShell {
|
||||
buildInputs = with pkgs; [ openjdk apksigner ];
|
||||
buildInputs = with pkgs; [ openjdk_headless apksigner ];
|
||||
};
|
||||
|
||||
# for targets needing 'adb', 'apkanalyzer' and other SDK/NDK tools
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ callPackage, lib, buildGoPackage
|
||||
, androidPkgs, openjdk, gomobile, xcodeWrapper, removeReferencesTo
|
||||
{ callPackage, lib, buildGoPackage, pkgs
|
||||
, androidPkgs, openjdk_headless, gomobile, xcodeWrapper, removeReferencesTo
|
||||
, go-bindata, mockgen, protobuf3_20, protoc-gen-go
|
||||
, meta
|
||||
, source
|
||||
@@ -15,6 +15,8 @@ let
|
||||
isIOS = platform == "ios";
|
||||
isAndroid = platform == "android";
|
||||
enforceXCodeAvailable = callPackage ./enforceXCodeAvailable.nix { };
|
||||
# Fixes fatal: not a git repository (or any of the parent directories): .git
|
||||
fakeGit = pkgs.writeScriptBin "git" "echo ${source.version}";
|
||||
|
||||
in buildGoPackage rec {
|
||||
pname = source.repo;
|
||||
@@ -29,8 +31,8 @@ in buildGoPackage rec {
|
||||
|
||||
extraSrcPaths = [ gomobile ];
|
||||
nativeBuildInputs = [
|
||||
gomobile removeReferencesTo go-bindata mockgen protoc-gen-go protobuf3_20
|
||||
] ++ optional isAndroid openjdk
|
||||
gomobile removeReferencesTo go-bindata mockgen protoc-gen-go protobuf3_20 fakeGit
|
||||
] ++ optional isAndroid openjdk_headless
|
||||
++ optional isIOS xcodeWrapper;
|
||||
|
||||
ldflags = goBuildLdFlags;
|
||||
@@ -46,6 +48,10 @@ in buildGoPackage rec {
|
||||
# TODO: try removing when go is upgraded to 1.22
|
||||
GODEBUG = "netdns=cgo+2";
|
||||
|
||||
# Sentry for status-go
|
||||
SENTRY_CONTEXT_NAME = "status-mobile";
|
||||
SENTRY_CONTEXT_VERSION = version;
|
||||
|
||||
preBuild = ''
|
||||
echo 'Generate static files'
|
||||
pushd go/src/$goPackagePath
|
||||
|
||||
@@ -13,8 +13,8 @@ let
|
||||
repo = "status-go";
|
||||
rev = "unknown";
|
||||
shortRev = rev;
|
||||
rawVersion = "develop";
|
||||
cleanVersion = rawVersion;
|
||||
version = "unknown";
|
||||
cleanVersion = version;
|
||||
goPackagePath = "github.com/${owner}/${repo}";
|
||||
# We use builtins.path so that we can name the resulting derivation,
|
||||
# Normally the name would not be deterministic, taken from the checkout directory.
|
||||
@@ -43,7 +43,6 @@ let
|
||||
inherit (versionJSON) owner repo version;
|
||||
rev = versionJSON.commit-sha1;
|
||||
shortRev = strings.substring 0 7 rev;
|
||||
rawVersion = versionJSON.version;
|
||||
cleanVersion = lib.sanitizeVersion versionJSON.version;
|
||||
# Need to pretend this is from status-im to let Go build it.
|
||||
goPackagePath = "github.com/status-im/${repo}";
|
||||
|
||||
+6
-4
@@ -20,8 +20,10 @@
|
||||
"@react-native-community/netinfo": "^4.4.0",
|
||||
"@react-native-community/push-notification-ios": "^1.4.1",
|
||||
"@react-native-community/slider": "^3.0.0",
|
||||
"@walletconnect/react-native-compat": "2.11.2",
|
||||
"@walletconnect/web3wallet": "1.10.2",
|
||||
"@react-native-firebase/app": "^21.7.2",
|
||||
"@react-native-firebase/messaging": "^21.7.2",
|
||||
"@reown/walletkit": "^1.0.0",
|
||||
"@walletconnect/react-native-compat": "2.17.3",
|
||||
"base-64": "^1.0.0",
|
||||
"big-integer": "1.6.51",
|
||||
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#refs/tags/v4.0.2-status",
|
||||
@@ -51,7 +53,7 @@
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-gifted-charts": "^1.3.2",
|
||||
"react-native-hole-view": "^3.0.0-alpha4",
|
||||
"react-native-image-crop-picker": "0.40.0",
|
||||
"react-native-image-crop-picker": "0.41.2",
|
||||
"react-native-image-resizer": "^1.2.3",
|
||||
"react-native-keychain": "8.1.2",
|
||||
"react-native-linear-gradient": "3.0.0-alpha.1",
|
||||
@@ -66,7 +68,7 @@
|
||||
"react-native-shake": "^3.3.1",
|
||||
"react-native-share": "10.0.2",
|
||||
"react-native-static-safe-area-insets": "^2.2.0",
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.3",
|
||||
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.6.5",
|
||||
"react-native-svg": "13.10.0",
|
||||
"react-native-webview": "13.6.3",
|
||||
"react-syntax-highlighter": "^15.5.0"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user