Compare commits

..
57 Commits
Author SHA1 Message Date
Erik Seppanen 43ad3ccb95 Lookup/add a contact from home screen (#14477) 2023-01-24 17:20:34 -05:00
Ibrahem Khalil 7f2623a23e [14849] Only allow dragging inside bottom sheet when no handle is shown (#14850) 2023-01-24 20:27:57 +02:00
Parvesh Monu 080b13c304 fix some buttons are not responding after theme change (#14811) 2023-01-24 20:28:41 +05:30
Roman Volosovskyi df2dd56cfb [#14728] Fix sender avatar in reply 2023-01-24 12:04:24 +01:00
Brian Sztamfater bd3c724c66 feat: record audio complete flow
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-01-23 14:04:06 -03:00
Icaro Motta 206730a777 Show "Added to group chat" notifications (#14785)
Partially implements https://github.com/status-im/status-mobile/issues/14712
Fixes #14744

### Summary

This PR implements the first, among what will probably be many different kinds of membership notifications. For this PR, I started with implementing a particular flow for private group chats because it's already supported by `status-go` (albeit I had to make some changes, see [PR in status-go](https://github.com/status-im/status-go/pull/3088).

1. `A` and `B` are mutual contacts.
2. `A` creates a private group chat with `B` as member.
3. `B` sees the group chat in the app, but doesn't interact with it.
4. `B` reinstalls the app (remember to back up the seed phrase).
5. `A` mentions `B` in the group chat.
6. `B` should see a group chat notification, which can be accepted/declined.

- [x] Also fixes #14744

### Demo

In the video I'm simulating the steps outlined in the *Summary*, but using the approach described in *Steps to test*, because it's way easier to iterate during development.

[demo.webm](https://user-images.githubusercontent.com/46027/212470798-c135d229-948d-4ba5-98db-ee73cc5495cd.webm)

### Review Notes

Some changes had to be made in `status-go` ([PR](https://github.com/status-im/status-go/pull/3088)), namely:

- According to [Figma](https://www.figma.com/file/eDfxTa9IoaCMUy5cLTp0ys/Shell-for-Mobile?node-id=3806%3A586901&t=xLTAjLXjG1UtorpI-0), users should be able to see `accepted` group chat notifications. Until now, `status-go` hardcoded that `accepted` notifications would *not* be returned in query results, and so it would be impossible to show them to users. This was changed and now the RPC endpoint accepts an additional filter. The implementation on the backend is backwards compatible so as to not break Status desktop.
- The `Membership` tab needs to display various types of notifications (group chat, community, etc), but the membership type doesn't exist on the backend. To overcome this constraint, this PR makes the membership type a logical/virtual type, i.e. a Clojure set of types. `status-go` was changed to support querying for multiple notification types (also backwards compatible).

#### Platforms

- Android
- iOS

### Steps to test

Please, follow the steps described in the Summary and you should be able to test.

But during development, I followed these steps (recommended by @cammellos). I documented them here for reference.

1. Checkout `feature/e2e` in status-go. Apply the diff below.
2. `cd cmd/e2e && ./e2e`
3. This will create a temporary account automatically, let's call it `A`.
4. On another device, create account `B`.
5. Follow the steps documented in https://github.com/status-im/status-go/blob/bdc406ea2e6eb990ce5c0fed7ea2e84b63c92139/cmd/e2e/README.md#L2 in order for user `A` to create a group chat with `B` as member. Don't make `A` and `B` mutual contacts.
6. On `B`'s device, a notification should appear, and `B` should be able to accept or decline the "invitation" (actually *invitation* is another concept and related to another feature).

```diff
modified   cmd/e2e/main.go
@@ -283,6 +283,11 @@ func defaultNodeConfig(installationID string) (*params.NodeConfig, error) {
    nodeConfig.NetworkID = 1
    nodeConfig.LogLevel = "ERROR"
    nodeConfig.DataDir = "/ethereum/mainnet_rpc"
+        nodeConfig.HTTPEnabled = true
+        nodeConfig.HTTPPort = 8545
+        nodeConfig.HTTPHost = "localhost"
+        nodeConfig.HTTPVirtualHosts = []string{"localhost"}
+
         nodeConfig.APIModules = "wakuext,ext,waku"

    nodeConfig.UpstreamConfig = params.UpstreamRPCConfig{
modified   protocol/messenger_group_chat.go
@@ -26,17 +26,17 @@ func (m *Messenger) validateAddedGroupMembers(members []string) error {
        }

        contact, _ := m.allContacts.Load(contactID)
-		if contact == nil || !(contact.Added && contact.HasAddedUs) {
-			return ErrGroupChatAddedContacts
-		}
+                if contact == nil {
+                  contact, err = buildContactFromPkString(contactID)
+                  if err != nil {
+                    return err
+                  }
+                }
    }
    return nil
 }

 func (m *Messenger) CreateGroupChatWithMembers(ctx context.Context, name string, members []string) (*MessengerResponse, error) {
-	if err := m.validateAddedGroupMembers(members); err != nil {
-		return nil, err
-	}

    var response MessengerResponse
    logger := m.logger.With(zap.String("site", "CreateGroupChatWithMembers"))
```
2023-01-23 13:54:51 -03:00
Parvesh Monu b3a03119d1 Implement unread badge for bottom tabs (#14856) 2023-01-23 20:23:41 +05:30
flexsurfer d79d2e9d36 sanitize quo2 (#14859) 2023-01-23 14:41:55 +01:00
Jamie Caprani 098821d20b chore: get community img from real data (#14765) 2023-01-23 03:17:50 -08:00
Jamie Caprani 92a180c477 add shadows to foundations (#14839)
* chore: add shadows to foundations
2023-01-23 03:06:26 -08:00
Mohamed Javid 6722b45076 [Fix] Admin Notification marked unread after closing and reopening AC (#14824)
* [Fix][#14823] Admin Notification unread issue

* [Fix][#14823] Changed dispatch of event from the PR feedback

* [Fix][#14823] Organize dispatch of event from the PR feedback

* [Fix][#14823] Organize dispatch of event from the PR feedback
2023-01-23 18:56:58 +08:00
Andrea Maria Piana 897a5eb201 [Fixes: #14794] Use toast instead of old pin modal
Instead of using the old modal, we show a toast when the limit of 3
messages is reached.
2023-01-23 10:44:15 +00:00
Parvesh Monu d3667ad683 fix nil value in reanimated style crashing at runtime (#14855) 2023-01-23 15:55:24 +05:30
Ibrahem Khalil dc9454defa Fix using functions as identifiers (#14848) 2023-01-21 13:28:45 +02:00
Omar Basem 53495dc893 Images Album (2) (#14755)
* feat: images album (2)
2023-01-20 16:51:44 +04:00
Jamie Caprani 967c869486 chore: fix component tests and permission drawer preview (#14831) 2023-01-19 15:03:53 -08:00
flexsurfer f0272f2e77 move chat events (#14835) 2023-01-19 19:35:14 +01:00
Churikova Tetiana b8dfa6b645 e2e: offline messages + edit 2023-01-19 19:01:14 +01:00
Omar Basem 6c14fd1cb9 Scroll page animations (#14695)
* feat: scroll page animations
2023-01-19 16:46:05 +04:00
flexsurfer e8e8547879 cleanup setup (#14827) 2023-01-19 12:15:28 +01:00
flexsurfer 2899819e95 rollback user profile (#14828) 2023-01-19 12:02:05 +01:00
Alexander 27c8c5547c [#14689] Link previews in chat (#14771)
* Initial

* Link fetching

* Post-merge fix
2023-01-18 22:43:26 +01:00
Parvesh Monu b370514ef3 Improve community avatar for shell card (#14813) 2023-01-19 00:12:49 +05:30
Ulises Manuel Cárdenas ab1fd43f28 Add Collectible ui component (#14803) 2023-01-18 19:00:47 +01:00
Churikova Tetiana 4c33b43713 e2e: more fixes 2023-01-18 16:02:09 +01:00
flexsurfer d2e35fe928 move constants/config to status-im2 root and remove old constants/config (#14821) 2023-01-18 15:43:58 +01:00
flexsurfer d030e211e3 move i18n to utils (#14819) 2023-01-18 14:36:02 +01:00
flexsurfer ed348e0871 cleaning (#14808)
cleaning, introduce react-native.red-black-tree and move messages list events
2023-01-18 12:16:33 +01:00
Icaro Motta 9a60fc1600 Fix all type hint warnings (#14810) 2023-01-17 19:52:12 -03:00
Andrea Maria Piana 14c9a7c6ac [Fixes: #14777] Set dns nameserver to cloudflare 2023-01-17 09:22:48 +00:00
flexsurfer 685c95591c refactor and move composer to status-im2 (#14758)
refactor and move composer to status-im2
2023-01-16 17:20:10 +01:00
Siddarth Kumar d6c899be3d make sure nodejs uses a fixed timezone (#14793)
* make sure node uses the UTC timezone
  we have a few timebomb tests in the codebase that would break and making sure node specifies a timezone fixes them.
2023-01-16 16:34:15 +05:30
Ibrahem Khalil aa8f5b3d48 Disable starting a new chat for non mutual contact (#14726) 2023-01-14 12:57:45 +02:00
Churikova Tetiana 4960f5a59c e2e: fixes for mutual contacts 2023-01-13 19:22:51 +01:00
Mohamed Javid 2f52cb1f0c Show Admin Notifications in Activity Center (#14748)
* [Feature][#14713] Added Admin Notifications in Activity Center

* [Feature][#14713] Admin Notification UI fixes

* [Feature][#14713] Admin Notification PR Feedbacks

* [Feature][#14713] Admin Notification PR Feedbacks

* [Feature][#14713] Admin Notification accessiblity label update
2023-01-14 02:14:02 +08:00
Andrea Maria Piana 64ec49c9c4 Removed removed files and add untracked from linting
The linter would fail if there were removed files, as it would
try to lint them but would not find them.
Similarly, untracked files would not be linted.

This commit changes the behavior so that untracked files are linted and
removed files are ignored, that way we can run it before committing if
there are unstaged changes that include removed/untracked files.
2023-01-13 17:22:13 +00:00
jakub c9223cd988 ci: use arm64 macos hosts for iOS builds
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-01-13 13:44:05 +01:00
Churikova Tetiana c1c9fef7ec e2e: revert failed tests 2023-01-13 12:12:12 +01:00
Jamie Caprani 73c4be8dee Communities Join Screens - Implement all permutations of Context Drawer options (#14700) 2023-01-13 09:35:41 +00:00
Roman Volosovskyi bfdca0fb38 https://github.com/status-im/status-go/compare/d40290a6...d60c1d00
[#14574] Update chat clock on group event
2023-01-12 18:57:22 +01:00
jakub f446ab163e ci: upgrade Xcode from 13.4 to 14.2
Depends on:
https://github.com/status-im/infra-role-bootstrap-macos/commit/fefb0081

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-01-12 16:55:24 +01:00
jakub 0623355e84 fleets.json: drop decomissioned eth.test fleet
The fleet wasn't being used so it has been liquidated:
https://github.com/status-im/infra-eth-cluster/commit/de986014

Signed-off-by: Jakub Sokołowski <jakub@status.im>

make sure that "waku-nodes" is not pulled from fleets.json
2023-01-12 13:15:13 +01:00
Andrea Maria Piana 7a5871a03f [Fixes: #14623] Enable mutual contacts by default and show banner 2023-01-12 09:16:02 +00:00
Parvesh Monu 5c0bd33697 Improve switcher cards lifecycle (#14751) 2023-01-12 02:37:55 +05:30
Churikova Tetiana 220341e0be e2e: introduced failed due to issues tests in results 2023-01-11 13:58:11 +01:00
yqrashawn ceaa363f08 fix: not using layout animation, causing flickers on android (#14753) 2023-01-11 18:37:42 +08:00
Jamie Caprani 846d628a9d chore: use banner from quo library (#14629) 2023-01-11 00:59:00 -08:00
Alexander 9ed89ac97d Fix for tapping on new contact from contact list (#14737)
* Tapping on new contact from Contact list leads to empty chat with skeleton

* Code style fix

* Small removals of unused stuff
2023-01-10 19:26:23 +01:00
Alexander 43da198c3f Communities join screens - add toast after joining/leaving (#14735)
* Add toast after joining/leaving a community

* leftover removal

* Better code for adding toasts

* Fixes

* Lint fix
2023-01-10 19:10:26 +01:00
Omar Basem 55d11d1a18 New chat fix (#14739)
* new chat fix
2023-01-10 20:19:53 +04:00
frank d2e8c5b52c fix #14733 (#14734) 2023-01-10 23:15:12 +08:00
Parvesh Monu 115fb3f590 fix default shell for -include targets (#14738) 2023-01-10 18:36:38 +05:30
yqrashawn 02a1c3597f feat: undo delete with toast (#14618) 2023-01-10 10:02:23 +08:00
Alexander 6f10ff4d3e Switcher button in chat is back (#14717) 2023-01-09 18:37:54 +01:00
Churikova Tetiana e289ad8968 e2e: fixes + workarounds 2023-01-09 14:46:24 +01:00
John Ngei 043e218320 show selected list item context actions view (#14676)
* show selected list item context actions view

* show selected list item context actions view

* fixed showing thumnails on communities
2023-01-09 16:36:17 +03:00
John Ngei 1cdcd298b0 Scrollable tags (#14182)
* refactored scrollable-tags to share the same logic with scrollable-tabs

* refactored tabs component to support scrollable-behaviour
2023-01-08 22:40:59 +03:00
549 changed files with 8445 additions and 11097 deletions
+38 -38
View File
@@ -1,7 +1,7 @@
status-im.utils.build/warning-handler
status-im.utils.build/get-current-sha
status-im.chat.constants/spacing-char
status-im.chat.constants/arg-wrapping-char
status-im2.constants/spacing-char
status-im2.constants/arg-wrapping-char
status-im.ios.core/init
status-im.ui.components.camera/aspects
status-im.ui.components.camera/capture-targets
@@ -46,8 +46,8 @@ status-im.utils.handlers/logged-in
status-im.multiaccounts.model/credentials
status-im.multiaccounts.login.core/contract-fleet?
status-im.multiaccounts.login.core/fetch-nodes
status-im.utils.config/rpc-networks-only?
status-im.utils.config/waku-enabled?
status-im2.config/rpc-networks-only?
status-im2.config/waku-enabled?
status-im.utils.pairing/has-paired-installations?
status-im.tribute-to-talk.core-test/user-cofx
quo.gesture-handler/tap-gesture-handler
@@ -154,40 +154,40 @@ status-im.ethereum.ens/name-hash
status-im.ethereum.ens/ABI-hash
status-im.ethereum.ens/pubkey-hash
status-im.network.core/get-network
status-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
status-im2.constants/desktop-content-types
status-im2.constants/blocks-per-hour
status-im2.constants/one-earth-day
status-im2.constants/left-pane-min-width
status-im2.constants/system
status-im2.constants/contact-discovery
status-im2.constants/send-transaction-failed-parse-response
status-im2.constants/send-transaction-failed-parse-params
status-im2.constants/send-transaction-no-account-selected
status-im2.constants/send-transaction-invalid-tx-sender
status-im2.constants/web3-get-logs
status-im2.constants/web3-transaction-receipt
status-im2.constants/web3-new-filter
status-im2.constants/web3-new-pending-transaction-filter
status-im2.constants/web3-new-block-filter
status-im2.constants/web3-uninstall-filter
status-im2.constants/web3-get-filter-changes
status-im2.constants/web3-shh-post
status-im2.constants/web3-shh-new-identity
status-im2.constants/web3-shh-has-identity
status-im2.constants/web3-shh-new-group
status-im2.constants/web3-shh-add-to-group
status-im2.constants/web3-shh-new-filter
status-im2.constants/web3-shh-uninstall-filter
status-im2.constants/web3-shh-get-filter-changes
status-im2.constants/web3-shh-get-messages
status-im2.constants/status-create-address
status-im2.constants/event-transfer-hash
status-im2.constants/regx-rtl-characters
status-im2.constants/desktop-msg-chars-hard-limit
status-im2.constants/debug-metrics
status-im2.constants/scan-qr-code
status-im2.constants/ipfs-proto-code
status-im2.constants/swarm-proto-code
status-im.multiaccounts.update.publisher/publish-update!
status-im.utils.async/task-queue
status-im.utils.async/async-periodic-run!
+17 -11
View File
@@ -1,4 +1,4 @@
.PHONY: nix-add-gcroots clean nix-clean run-metro test release _list _fix-node-perms _tmpdir-mk _tmpdir-rm _install-hooks
.PHONY: nix-add-gcroots clean nix-clean run-metro test release _list _fix-node-perms _tmpdir-rm
help: SHELL := /bin/sh
help: ##@other Show this help
@@ -118,10 +118,11 @@ _fix-node-perms: ##@prepare Fix permissions so that directory can be cleaned
$(shell test -d node_modules && chmod -R 744 node_modules)
$(shell test -d node_modules.tmp && chmod -R 744 node_modules.tmp)
_tmpdir-mk: SHELL := /bin/sh
_tmpdir-mk: ##@prepare Create a TMPDIR for temporary files
$(TMPDIR): SHELL := /bin/sh
$(TMPDIR): ##@prepare Create a TMPDIR for temporary files
@mkdir -p "$(TMPDIR)"
# Make sure TMPDIR exists every time make is called
_tmpdir-mk: $(TMPDIR)
-include _tmpdir-mk
_tmpdir-rm: SHELL := /bin/sh
@@ -154,7 +155,7 @@ pod-install: ##@prepare Run 'pod install' to install podfiles and update Podfile
update-fleets: ##@prepare Download up-to-date JSON file with current fleets state
curl -s https://fleets.status.im/ \
| jq --indent 4 --sort-keys . \
| sed 's/"warning": "/"warning": "DO NOT EDIT! /' \
> resources/config/fleets.json
$(KEYSTORE_PATH): export TARGET := keytool
@@ -285,18 +286,24 @@ endif
# Tests
#--------------
# Get all clojure files, including untracked, excluding removed
define find_all_clojure_files
$$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn)
endef
lint: export TARGET := default
lint: ##@test Run code style checks
sh scripts/lint-re-frame-in-quo-components.sh && \
@sh scripts/lint-re-frame-in-quo-components.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILE
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
lint-fix: export TARGET := default
lint-fix: ##@test Run code style checks and fix issues
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES
shadow-server: export TARGET := clojure
@@ -344,7 +351,6 @@ component-test: export COMPONENT_TEST := true
component-test: export BABEL_ENV := test
component-test: ##@test Run tests once in NodeJS
# Here we create the gyp bindings for nodejs
yarn install
yarn shadow-cljs compile component-test && \
jest --config=test/jest/jest.config.js
+1 -1
View File
@@ -4,7 +4,7 @@ library 'status-jenkins-lib@v1.6.3'
def isPRBuild = utils.isPRBuild()
pipeline {
agent { label 'macos && x86_64 && nix-2.11 && xcode-13.4' }
agent { label 'macos && arm64 && nix-2.11 && xcode-14.2' }
parameters {
string(
+1 -1
View File
@@ -58,7 +58,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 9 \
--numprocesses 4 \
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
+1 -1
View File
@@ -99,7 +99,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 9 \
--numprocesses 4 \
--rerun_count=2 \
--testrail_report=True \
-k \"${params.KEYWORD_EXPRESSION}\" \
+1 -1
View File
@@ -74,7 +74,7 @@ pipeline {
python3 -m pytest \
-m "upgrade" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--numprocesses 15 \
--numprocesses 4 \
--rerun_count=2 \
--testrail_report=True \
--apk=${params.APK_NAME} \
+14 -10
View File
@@ -35,20 +35,24 @@ abstract_target 'Status' do
target 'StatusImPR' do
end
#commented out temporarily
#use_flipper!({ 'Flipper' => '0.74.0' })
#post_install do |installer|
# flipper_post_install(installer)
#end
# some of libs wouldn't be build for x86_64 otherwise and that is
# necessary for ios simulators
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
post_install do |installer|
# some of libs wouldn't be build for x86_64 otherwise and that is
# necessary for ios simulators
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
end
end
# FIXME: Fix dependency signing broken on Xcode 14 due to lack of Team ID.
# https://github.com/CocoaPods/CocoaPods/issues/11402
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end
use_native_modules!
+2 -2
View File
@@ -640,7 +640,7 @@ SPEC CHECKSUMS:
FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469
FBReactNativeSpec: 7dfb84f624136a45727c813ed21d130cd3e61beb
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db
glog: 6934faae5afbec23475648c8aeb6047ce973af65
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c
@@ -710,6 +710,6 @@ SPEC CHECKSUMS:
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 0276e9f20976c8568e107cfc1163a8629051adc0
PODFILE CHECKSUM: a1de9468266e7f0b5273acea713782ab759690f1
PODFILE CHECKSUM: ca5d07911eadc1267649ecc15379e5127a0cc839
COCOAPODS: 1.11.3
+105 -105
View File
@@ -10,7 +10,6 @@
00E356F31AD99517003FC87E /* StatusImTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* StatusImTests.m */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1DD629CDA66802C7E5575C38 /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9674A3ACAC81C20142ABF2DC /* libPods-Status-StatusImPR.a */; };
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */; };
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 */; };
@@ -45,16 +44,17 @@
715D8133290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */; };
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
A0093AB50DA85E1D01818CCA /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E88D313E5D854BE6BC81FC1 /* libPods-Status-StatusIm-StatusImTests.a */; };
B24FC7FD1DE7195700D694FF /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FC1DE7195700D694FF /* Social.framework */; };
B24FC7FF1DE7195F00D694FF /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FE1DE7195F00D694FF /* MessageUI.framework */; };
B2A2642817FA09632CAAE2BA /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 011AA4853B13093497B93F8C /* libPods-Status-StatusIm.a */; };
B2F2D1BC1D9D531B00B7B453 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */; };
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E586E1B0E544F64AA9F5BD1 /* libz.tbd */; };
BFF6343F5A1F0F5FFFC8D020 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A4B974811E312E44D5BBE9EC /* libPods-Status-StatusIm-StatusImTests.a */; };
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE4E31B21D8695250033ED64 /* Statusgo.xcframework */; };
D1786306E0184916B11F4C37 /* Inter-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */; };
D84616FB563A48EBB1678699 /* Inter-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */; };
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B321D25F4493470980039457 /* Inter-BoldItalic.otf */; };
E9C92E7783C7FB91C9616112 /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 57CBBEA420F440D344DD99E5 /* libPods-Status-StatusImPR.a */; };
F51761A0F4D1FAE41A72435A /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 928CC6D1D5BCCF9D3BC60D6A /* libPods-Status-StatusIm.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -102,35 +102,39 @@
00E356EE1AD99517003FC87E /* StatusImTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StatusImTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* StatusImTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StatusImTests.m; sourceTree = "<group>"; };
011AA4853B13093497B93F8C /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07F961A680F5B00A75B9A /* StatusIm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StatusIm.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = StatusIm/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = StatusIm/AppDelegate.m; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = StatusIm/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = StatusIm/main.m; sourceTree = "<group>"; };
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>"; };
1E88D313E5D854BE6BC81FC1 /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
3A8F8EA924A4D31600BF206D /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
3AAD2ADC24A3A60E0075D594 /* Status PR.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Status PR.app"; sourceTree = BUILT_PRODUCTS_DIR; };
3AB1C3AD245C043900098F67 /* StatusIm-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusIm-Bridging-Header.h"; sourceTree = "<group>"; };
45E0DC52E25A332264874B0F /* 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>"; };
43341A7CBCE457435677CC51 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
4C16DE0B1F89508700AA10DB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
564309A78329EB657677709C /* 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>"; };
57CBBEA420F440D344DD99E5 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5F30F922E4B02AB10F6CB65E /* 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>"; };
65F693BD2578002500A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = System/Library/Frameworks/CoreNFC.framework; sourceTree = SDKROOT; };
65F693BF2578003600A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/System/iOSSupport/System/Library/Frameworks/CoreNFC.framework; sourceTree = DEVELOPER_DIR; };
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusImTests-Bridging-Header.h"; sourceTree = "<group>"; };
65F6941825780A4F00A45E76 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBold.otf"; path = "../resources/fonts/Inter-SemiBold.otf"; sourceTree = "<group>"; };
70ACC04C7CF0A6C6421A805D /* 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>"; };
715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "UbuntuMono-Regular.ttf"; path = "../resources/fonts/UbuntuMono-Regular.ttf"; sourceTree = "<group>"; };
74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "launch-image-universal.storyboard"; sourceTree = "<group>"; };
7AFBE28450C0239119FBDBA2 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
8B3C115CD813729DE4735219 /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
8D3CFDC9666FBD03D1AA059A /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
922C4CA61F4D5F8B0033C753 /* StatusIm.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = StatusIm.entitlements; path = StatusIm/StatusIm.entitlements; sourceTree = "<group>"; };
9674A3ACAC81C20142ABF2DC /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
928CC6D1D5BCCF9D3BC60D6A /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
9C76AF5A418D4D65A4CAD1D9 /* InterStatus-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "InterStatus-Regular.otf"; path = "../resources/fonts/InterStatus-Regular.otf"; sourceTree = "<group>"; };
9EC0135C1E06FB1900155B5C /* RCTWKWebView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWKWebView.xcodeproj; path = "../node_modules/react-native-wkwebview-reborn/ios/RCTWKWebView.xcodeproj"; sourceTree = "<group>"; };
A4B974811E312E44D5BBE9EC /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBoldItalic.otf"; path = "../resources/fonts/Inter-SemiBoldItalic.otf"; sourceTree = "<group>"; };
B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Italic.otf"; path = "../resources/fonts/Inter-Italic.otf"; sourceTree = "<group>"; };
B24FC7FC1DE7195700D694FF /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; };
@@ -138,13 +142,9 @@
B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Medium.otf"; path = "../resources/fonts/Inter-Medium.otf"; sourceTree = "<group>"; };
B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = StatusIm/Images.xcassets; sourceTree = "<group>"; };
B321D25F4493470980039457 /* Inter-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-BoldItalic.otf"; path = "../resources/fonts/Inter-BoldItalic.otf"; sourceTree = "<group>"; };
B650FC314F823A68E7CE11D5 /* 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>"; };
BB42B2C150BA8A2AA109EA43 /* 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>"; };
BF23313BEFBC84C6BB7E7677 /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
C6B1215047604CD59A4C74D6 /* Inter-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-MediumItalic.otf"; path = "../resources/fonts/Inter-MediumItalic.otf"; sourceTree = "<group>"; };
CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Bold.otf"; path = "../resources/fonts/Inter-Bold.otf"; sourceTree = "<group>"; };
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Statusgo.xcframework; path = "../modules/react-native-status/ios/RCTStatus/Statusgo.xcframework"; sourceTree = "<group>"; };
FBF6AB84EBC2085D28C3CDEF /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -152,7 +152,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A0093AB50DA85E1D01818CCA /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
BFF6343F5A1F0F5FFFC8D020 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -165,7 +165,7 @@
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */,
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */,
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
B2A2642817FA09632CAAE2BA /* libPods-Status-StatusIm.a in Frameworks */,
F51761A0F4D1FAE41A72435A /* libPods-Status-StatusIm.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -179,7 +179,7 @@
3AAD2AC224A3A60E0075D594 /* Statusgo.xcframework in Frameworks */,
3AAD2AC524A3A60E0075D594 /* libc++.tbd in Frameworks */,
3AAD2AC624A3A60E0075D594 /* libz.tbd in Frameworks */,
1DD629CDA66802C7E5575C38 /* libPods-Status-StatusImPR.a in Frameworks */,
E9C92E7783C7FB91C9616112 /* libPods-Status-StatusImPR.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -302,9 +302,9 @@
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */,
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */,
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */,
011AA4853B13093497B93F8C /* libPods-Status-StatusIm.a */,
1E88D313E5D854BE6BC81FC1 /* libPods-Status-StatusIm-StatusImTests.a */,
9674A3ACAC81C20142ABF2DC /* libPods-Status-StatusImPR.a */,
928CC6D1D5BCCF9D3BC60D6A /* libPods-Status-StatusIm.a */,
A4B974811E312E44D5BBE9EC /* libPods-Status-StatusIm-StatusImTests.a */,
57CBBEA420F440D344DD99E5 /* libPods-Status-StatusImPR.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -312,12 +312,12 @@
D0D5C8D06825D33BA2D2121E /* Pods */ = {
isa = PBXGroup;
children = (
BB42B2C150BA8A2AA109EA43 /* Pods-Status-StatusIm.debug.xcconfig */,
45E0DC52E25A332264874B0F /* Pods-Status-StatusIm.release.xcconfig */,
7AFBE28450C0239119FBDBA2 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
B650FC314F823A68E7CE11D5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
FBF6AB84EBC2085D28C3CDEF /* Pods-Status-StatusImPR.debug.xcconfig */,
BF23313BEFBC84C6BB7E7677 /* Pods-Status-StatusImPR.release.xcconfig */,
564309A78329EB657677709C /* Pods-Status-StatusIm.debug.xcconfig */,
5F30F922E4B02AB10F6CB65E /* Pods-Status-StatusIm.release.xcconfig */,
43341A7CBCE457435677CC51 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
70ACC04C7CF0A6C6421A805D /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
8D3CFDC9666FBD03D1AA059A /* Pods-Status-StatusImPR.debug.xcconfig */,
8B3C115CD813729DE4735219 /* Pods-Status-StatusImPR.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -329,11 +329,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "StatusImTests" */;
buildPhases = (
9EDBFFDF8534CA0328CECC7B /* [CP] Check Pods Manifest.lock */,
0F876BD5356F61BF142A01A0 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
BE7BAE4A16BB2298029AE05C /* [CP] Copy Pods Resources */,
6ECED279DE66BA46FFB5EE0D /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -349,14 +349,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "StatusIm" */;
buildPhases = (
3A2B06D667746967CAF851DA /* [CP] Check Pods Manifest.lock */,
119C58BA120E4E4D213DA7CD /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
20B6B6891D92C42700CC5C6A /* Embed Frameworks */,
E3914A731DF919ED00EBB515 /* Run Script */,
CBFE8A62956C05D561D73D56 /* [CP] Copy Pods Resources */,
3C1038075AE5E6FB86AC2319 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -371,14 +371,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 3AAD2AD924A3A60E0075D594 /* Build configuration list for PBXNativeTarget "StatusImPR" */;
buildPhases = (
D0BDEAC0595D0C2E7409DBA0 /* [CP] Check Pods Manifest.lock */,
50F1BA2DC5224CBE6FDD2998 /* [CP] Check Pods Manifest.lock */,
3AAD2ABB24A3A60E0075D594 /* Sources */,
3AAD2ABF24A3A60E0075D594 /* Frameworks */,
3AAD2AC924A3A60E0075D594 /* Resources */,
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */,
3AAD2AD624A3A60E0075D594 /* Embed Frameworks */,
3AAD2AD724A3A60E0075D594 /* Run Script */,
7C4DF7147D0F01A8C9DB77D3 /* [CP] Copy Pods Resources */,
E732E3E1B024946173BF6D3D /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -528,7 +528,29 @@
shellPath = /bin/sh;
shellScript = "set -o errexit\nexport NODE_BINARY=\"node\"\nexport NODE_ARGS=\" --max-old-space-size=16384 \"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ./react-native-xcode.log 2>&1";
};
3A2B06D667746967CAF851DA /* [CP] Check Pods Manifest.lock */ = {
0F876BD5356F61BF142A01A0 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusIm-StatusImTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
119C58BA120E4E4D213DA7CD /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -578,73 +600,7 @@
shellPath = /bin/sh;
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ./set_xcode_version.log 2>&1";
};
7C4DF7147D0F01A8C9DB77D3 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9EDBFFDF8534CA0328CECC7B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusIm-StatusImTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
BE7BAE4A16BB2298029AE05C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
CBFE8A62956C05D561D73D56 /* [CP] Copy Pods Resources */ = {
3C1038075AE5E6FB86AC2319 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -666,7 +622,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
D0BDEAC0595D0C2E7409DBA0 /* [CP] Check Pods Manifest.lock */ = {
50F1BA2DC5224CBE6FDD2998 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -688,6 +644,28 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
6ECED279DE66BA46FFB5EE0D /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
E3914A731DF919ED00EBB515 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
@@ -702,6 +680,28 @@
shellPath = /bin/sh;
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ./set_xcode_version.log 2>&1";
};
E732E3E1B024946173BF6D3D /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -749,7 +749,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFBE28450C0239119FBDBA2 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
baseConfigurationReference = 43341A7CBCE457435677CC51 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = .debug;
@@ -786,7 +786,7 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B650FC314F823A68E7CE11D5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
baseConfigurationReference = 70ACC04C7CF0A6C6421A805D /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = "";
@@ -819,7 +819,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BB42B2C150BA8A2AA109EA43 /* Pods-Status-StatusIm.debug.xcconfig */;
baseConfigurationReference = 564309A78329EB657677709C /* Pods-Status-StatusIm.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -893,7 +893,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 45E0DC52E25A332264874B0F /* Pods-Status-StatusIm.release.xcconfig */;
baseConfigurationReference = 5F30F922E4B02AB10F6CB65E /* Pods-Status-StatusIm.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -957,7 +957,7 @@
};
3AAD2ADA24A3A60E0075D594 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FBF6AB84EBC2085D28C3CDEF /* Pods-Status-StatusImPR.debug.xcconfig */;
baseConfigurationReference = 8D3CFDC9666FBD03D1AA059A /* Pods-Status-StatusImPR.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -1026,7 +1026,7 @@
};
3AAD2ADB24A3A60E0075D594 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = BF23313BEFBC84C6BB7E7677 /* Pods-Status-StatusImPR.release.xcconfig */;
baseConfigurationReference = 8B3C115CD813729DE4735219 /* Pods-Status-StatusImPR.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIconPR$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
+10 -127
View File
@@ -52,41 +52,15 @@
},
{
"path": "borkdude/edamame/0.0.11-alpha.28/edamame-0.0.11-alpha.28",
"path": "camel-snake-kebab/camel-snake-kebab/0.4.3/camel-snake-kebab-0.4.3",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "488f403591739aab5a68ce6e7f82c0e855c23fd6",
"sha256": "1cw712kzza733g55s02ql35q630zd8j8nmnpivcczjkg240jans4"
"sha1": "d8a86256bfd06736b84b6ee4c154a1b2518ab461",
"sha256": "1fxz1fdhppby21l4qkrci9kp38s508yn01z3cjspda56mj1plnid"
},
"jar": {
"sha1": "371f3e232e7fdb04b7b2044825eb9822280e8f93",
"sha256": "1iyxq6jypjd875cgdyllknh27mx5fnkyjz80mr927d5i94r0ywj4"
}
},
{
"path": "borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "eb3aff6c7db85d91f7e05b98e06d1354a4fce36c",
"sha256": "1bvr7cvpbvqi7swypzpbfrig16zipwvmg4m47y2x5chs5czwxv15"
},
"jar": {
"sha1": "33dfc86102e0ea400498cbca47572459c1c43b00",
"sha256": "0a5gxmj8kzc01y9bn7l4x7c1v5q9wcbvw5hdr525d3ylsyl6xfkw"
}
},
{
"path": "borkdude/sci/0.2.1-alpha.1/sci-0.2.1-alpha.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "516cb8e3a8e430d59d9c3e7a51f9f859e3b249e0",
"sha256": "1nrww29m90q1avaahw7i5418c18crc3cidhbg3ml7h7vjjplsl9y"
},
"jar": {
"sha1": "96e39dcbc3fb3a41c6bf2e628303cf0f534b28a3",
"sha256": "1cjvz85ls982rmx90igv4mcfaa53fj5z29df9mf4jplyig3l9dxb"
"sha1": "5ae08f83ceb8959971e6334596bff0214bf6fdf2",
"sha256": "1j627a99ccc4v0v83c8670vdnsp69cjk7ba0ga2xf433fwsz74c1"
}
},
@@ -116,19 +90,6 @@
}
},
{
"path": "clj-stacktrace/clj-stacktrace/0.2.8/clj-stacktrace-0.2.8",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "c5a47e6858344c9fd42eecafc7920a7a18d6126d",
"sha256": "1az0fs9k5xvzl8bz564apd77kqc83nl8sxsrvmswmbmkamvy4hd3"
},
"jar": {
"sha1": "b0654b98763199ee57182526465d823492d1cc3f",
"sha256": "1029wd82qyxv6ji9pd38m32nqia56h6845lqv4ym4dsz5i201g9a"
}
},
{
"path": "cljs-bean/cljs-bean/1.3.0/cljs-bean-1.3.0",
"host": "https://repo.clojars.org",
@@ -675,19 +636,6 @@
}
},
{
"path": "hashp/hashp/0.2.1/hashp-0.2.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "32530b9106a64fd5442d2aa27c6da4175d1f1440",
"sha256": "1z94k8c52r87rq3nhc0mqazcxff6d4phi8gy1bgndhiz4nq1mia7"
},
"jar": {
"sha1": "fb501db2eb4a028c1875382d58c17c381aec47b8",
"sha256": "1lwirzb60zvksvkb3arpwi4fk1xnp0x5ljmrca5vf7dq25lmwmsd"
}
},
{
"path": "hiccup/hiccup/1.0.5/hiccup-1.0.5",
"host": "https://repo.clojars.org",
@@ -818,32 +766,6 @@
}
},
{
"path": "mvxcvi/arrangement/1.2.0/arrangement-1.2.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "4f19bd291595870162eadd35456a0b2e76444a64",
"sha256": "1qqnl05nwcjnzhlgplcsbckrp8pqvf8n6bf8kr8rz7lz2q4px3vb"
},
"jar": {
"sha1": "036e640bb9e14c2aa95589a45a018eb8358ce3f6",
"sha256": "1m3v1rkpdmv7aym5vq2swh0mf9mg7xppdr3vrl4g6qm3s42c24b7"
}
},
{
"path": "mvxcvi/puget/1.3.1/puget-1.3.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "07104dc20a13c7e255fffee4f16de9a6873c187f",
"sha256": "1129rb3qksg7n85j03k6d3sr6868g724097vxids1r4wqj2phxkf"
},
"jar": {
"sha1": "a4f7dcf71ccd8d69d4ecd2b19f3d671dfc169308",
"sha256": "029znh7p8f1h91gri4jhzwqsa0rnn3i34yr3kav55npym2sw5sfp"
}
},
{
"path": "net/cgrand/macrovich/0.2.1/macrovich-0.2.1",
"host": "https://repo.clojars.org",
@@ -949,15 +871,15 @@
},
{
"path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2",
"path": "org/clojure/core.rrb-vector/0.1.1/core.rrb-vector-0.1.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "e9336ac820c5a7e07fe0aa431df981cbab6db3e3",
"sha256": "07q9qmxc7ggaxh27imgs34svn4j269rhslbnrs63ahrqzk5bmqlf"
"sha1": "3231642aa1dcf628c864a5f208cd293fbd6a385a",
"sha256": "18kk5sds5lg8r2kidhz9qpgyrvggkj8j4sgfdsmyyl93w3f16lnp"
},
"jar": {
"sha1": "0404feea925608b921b56acd11d3b187a0d33fe4",
"sha256": "13hkx1285f2imqlj6wbgyxki2yg8rmfr49iq1zijxm1cgfx8xyai"
"sha1": "aafb7677ec1e9f344fc834bbbdb91e8ba02af474",
"sha256": "0cqyy1vqrhilgwrdxsibd7360ch3hhwjnbbnzsak38v6i6mg66xl"
}
},
@@ -1494,32 +1416,6 @@
}
},
{
"path": "rewrite-clj/rewrite-clj/0.6.1/rewrite-clj-0.6.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "05778b423e14e8f1b054cc78df4e5d048cc0fc68",
"sha256": "0wp9xvmfp37x88msm2yhhzi8sjwd4hxz0vv4bslhal3zi97c1bj6"
},
"jar": {
"sha1": "55b399417a088ca163ef835e56db76ea962ce0a9",
"sha256": "0qq3an9nrhhw5mba753zs1m9rnk86w9l1f04n8v0hz0i2kbf1cki"
}
},
{
"path": "rewrite-cljs/rewrite-cljs/0.4.5/rewrite-cljs-0.4.5",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "378cd53218027b9a93640dcf64c040665f6c9c6b",
"sha256": "1qrhrgzhqdyqizh0ngnr4zgj9xkfzq0qhsws4pxxra3qc9ikl9cq"
},
"jar": {
"sha1": "c35be115c39dadc71a4de3f584aa8ca295e11257",
"sha256": "1dnw0jhr1hhqz80w3z5d8qdbaqdvgzg4fyhv6lffa51c9ca1dsr1"
}
},
{
"path": "ring-cors/ring-cors/0.1.8/ring-cors-0.1.8",
"host": "https://repo.clojars.org",
@@ -1648,18 +1544,5 @@
"sha1": "09af0b348e6253dcf9fd567d0d22ffebdea46176",
"sha256": "1qg2iyblykfkzmplc2c46916b9m0h5ad6lxmvrk5qn3pdxqr8vw0"
}
},
{
"path": "zprint/zprint/1.1.1/zprint-1.1.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "d7225bdc4978d3a8eac8613187cddd2efb9e39d2",
"sha256": "0yyy31h88zww238c2v4zi9va3pjp7ii76zjggglakd3wm1fdbnck"
},
"jar": {
"sha1": "3bd9bbedb188a66ccf72c1e22819e8e423a6757a",
"sha256": "1bvrarxw0dqvxlhj6gdwrv6mklzh4p79537g293fqlm07f2knfph"
}
}
]
+2 -11
View File
@@ -2,12 +2,9 @@ args4j/args4j/2.0.26/args4j-2.0.26.jar
bidi/bidi/2.1.6/bidi-2.1.6.jar
binaryage/env-config/0.2.2/env-config-0.2.2.jar
binaryage/oops/0.7.0/oops-0.7.0.jar
borkdude/edamame/0.0.11-alpha.28/edamame-0.0.11-alpha.28.jar
borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1.jar
borkdude/sci/0.2.1-alpha.1/sci-0.2.1-alpha.1.jar
camel-snake-kebab/camel-snake-kebab/0.4.3/camel-snake-kebab-0.4.3.jar
cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3.jar
cider/piggieback/0.4.1/piggieback-0.4.1.jar
clj-stacktrace/clj-stacktrace/0.2.8/clj-stacktrace-0.2.8.jar
cljs-bean/cljs-bean/1.3.0/cljs-bean-1.3.0.jar
cljsjs/react-dom-server/17.0.1-0/react-dom-server-17.0.1-0.jar
cljsjs/react-dom/17.0.1-0/react-dom-17.0.1-0.jar
@@ -50,7 +47,6 @@ day8/re-frame/test/0.1.5/test-0.1.5.jar
edn-query-language/eql/0.0.9/eql-0.0.9.jar
expound/expound/0.8.5/expound-0.8.5.jar
fipp/fipp/0.6.23/fipp-0.6.23.jar
hashp/hashp/0.2.1/hashp-0.2.1.jar
hiccup/hiccup/1.0.5/hiccup-1.0.5.jar
hickory/hickory/0.7.1/hickory-0.7.1.jar
http-kit/http-kit/2.2.0/http-kit-2.2.0.jar
@@ -61,8 +57,6 @@ javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
medley/medley/0.8.2/medley-0.8.2.jar
mvxcvi/alphabase/1.0.0/alphabase-1.0.0.jar
mvxcvi/arrangement/1.2.0/arrangement-1.2.0.jar
mvxcvi/puget/1.3.1/puget-1.3.1.jar
net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
nrepl/nrepl/0.7.0/nrepl-0.7.0.jar
org/checkerframework/checker-qual/2.0.0/checker-qual-2.0.0.jar
@@ -71,7 +65,7 @@ org/clojure/clojurescript/1.10.773/clojurescript-1.10.773.jar
org/clojure/core.async/1.3.610/core.async-1.3.610.jar
org/clojure/core.cache/1.0.207/core.cache-1.0.207.jar
org/clojure/core.memoize/1.0.236/core.memoize-1.0.236.jar
org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar
org/clojure/core.rrb-vector/0.1.1/core.rrb-vector-0.1.1.jar
org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar
org/clojure/data.json/1.0.0/data.json-1.0.0.jar
org/clojure/data.priority-map/1.0.0/data.priority-map-1.0.0.jar
@@ -113,8 +107,6 @@ re-frisk-remote/re-frisk-remote/1.6.0/re-frisk-remote-1.6.0.jar
re-frisk/sente/1.15.0/sente-1.15.0.jar
reagent/reagent/1.0.0/reagent-1.0.0.jar
refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0.jar
rewrite-clj/rewrite-clj/0.6.1/rewrite-clj-0.6.1.jar
rewrite-cljs/rewrite-cljs/0.4.5/rewrite-cljs-0.4.5.jar
ring-cors/ring-cors/0.1.8/ring-cors-0.1.8.jar
ring/ring-codec/1.1.2/ring-codec-1.1.2.jar
ring/ring-core/1.8.1/ring-core-1.8.1.jar
@@ -125,4 +117,3 @@ thheller/shadow-cljs/2.11.16/shadow-cljs-2.11.16-aot.jar
thheller/shadow-cljsjs/0.0.21/shadow-cljsjs-0.0.21.jar
thheller/shadow-util/0.7.0/shadow-util-0.7.0.jar
viebel/codox-klipse-theme/0.0.1/codox-klipse-theme-0.0.1.jar
zprint/zprint/1.1.1/zprint-1.1.1.jar
-134
View File
@@ -1,134 +0,0 @@
{
"chats": [
["Featured", [
"status",
"support",
"crypto",
"chitchat",
"defi",
"markets",
"dap-ps",
"devcon",
"eth2"
]],
["General", [
"chitchat",
"hello",
"worldnews",
"status",
"support"
]],
["Entertainment", [
"music",
"movies",
"podcasts",
"books",
"gaming",
"adult",
"tv-shows"
]],
["Interests", [
"sports",
"travel",
"design",
"food",
"automotive"
]],
["Society", [
"climatechange",
"blacklivesmatter",
"politics",
"hongkong",
"privacy"
]],
["Crypto", [
"crypto",
"markets",
"crypto-education",
"ethereum",
"bitcoin",
"chainlink",
"avalanche",
"eth2",
"eips",
"dap-ps",
"cryptolife",
"governance",
"staking",
"defi",
"cryptopayments",
"tokenomics",
"web3",
"web3design",
"devcon",
"exchange",
"validators"
]],
["Technologies", [
"tech",
"ai",
"vr-ar",
"networks"
]],
["Status", [
"status",
"support",
"statusphere",
"status-townhall-questions",
"status-core-ui",
"status-keycard",
"nimbus-general",
"status-assemble",
"status-marketing",
"status-protocol",
"status-desktop",
"status-watercooler",
"status-security",
"waku",
"status-docs",
"status-general",
"status-design"
]],
["Development", [
"ethereum-clients",
"storage",
"indexing",
"sidechains",
"layer2",
"devops",
"smart-contracts",
"embark-community",
"subspace",
"open-source",
"security"
]],
["Languages", [
"status-espanol",
"statusbrasil",
"status-german",
"status-french",
"status-italiano",
"status-dutch",
"status-russian",
"status-chinese",
"status-korean",
"status-japanese",
"status-farsi",
"status-turkish",
"status-filipino",
"status-naija",
"status-indian",
"status-arabic",
"indonesian"
]]
]
}
+194 -162
View File
@@ -1,165 +1,197 @@
{
"fleets": {
"eth.prod": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443",
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443",
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR",
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443",
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443"
}
"meta": {
"hostname": "node-01.do-ams3.sites.misc",
"timestamp": "2023-01-05T10:03:38.657813",
"warning": "DO NOT EDIT! Auto generated from Consul. Should only be used at build time."
},
"eth.staging": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443",
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443",
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu",
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.staging": "enode://088cf5a93c576fae52f6f075178467b8ff98bacf72f59e88efb16dfba5b30f80a4db78f8e3cb3d87f2f6521746ef4a8768465ef2896c6af24fd77a425e95b6dd@47.52.226.137:443",
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
"node-01.gc-us-central1-a.eth.staging": "enode://d3878441652f010326889f28360e69f2d09d06540f934fada0e17b374ce5319de64279aba3c44a5bf807d9967c6d705b3b4c6b03fa70763240e2ee6af01a539e@35.192.0.86:443"
}
},
"eth.test": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.test": "enode://daae2e72820e86e942fa2a8aa7d6e9954d4043a753483d8bd338e16be82cf962392d5c0e1ae57c3d793c3d3dddd8fd58339262e4234dc966f953cd73b535f5fa@47.52.188.149:443",
"boot-01.do-ams3.eth.test": "enode://9e0988575eb7717c25dea72fd11c7b37767dc09c1a7686f7c2ec577d308d24b377ceb675de4317474a1a870e47882732967f4fa785b02ba95d669b31d464dec0@206.189.243.164:443",
"boot-01.gc-us-central1-a.eth.test": "enode://c1e5018887c863d64e431b69bf617561087825430e4401733f5ba77c70db14236df381fefb0ebe1ac42294b9e261bbe233dbdb83e32c586c66ae26c8de70cb4c@35.188.168.137:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.test": "enode://619dbb5dda12e85bf0eb5db40fb3de625609043242737c0e975f7dfd659d85dc6d9a84f9461a728c5ab68c072fed38ca6a53917ca24b8e93cc27bdef3a1e79ac@47.52.188.196:443",
"mail-01.do-ams3.eth.test": "enode://e4865fe6c2a9c1a563a6447990d8e9ce672644ae3e08277ce38ec1f1b690eef6320c07a5d60c3b629f5d4494f93d6b86a745a0bf64ab295bbf6579017adc6ed8@206.189.243.161:443",
"mail-01.gc-us-central1-a.eth.test": "enode://707e57453acd3e488c44b9d0e17975371e2f8fb67525eae5baca9b9c8e06c86cde7c794a6c2e36203bf9f56cae8b0e50f3b33c4c2b694a7baeea1754464ce4e3@35.192.229.172:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.test": "/ip4/47.52.188.149/tcp/30703/ethv4/16Uiu2HAm9Vatqr4GfVCqnyeaPtCF3q8fz8kDDUgqXVfFG7ZfSA7w",
"boot-01.do-ams3.eth.test": "/ip4/206.189.243.164/tcp/30703/ethv4/16Uiu2HAmBCh5bgYr6V3fDuLqUzvtSAsFTQJCQ3TVHT8ta8bTu2Jm",
"boot-01.gc-us-central1-a.eth.test": "/ip4/35.188.168.137/tcp/30703/ethv4/16Uiu2HAm3MUqtGjmetyZ9L4SN2R8oHDWvACUcec25LjtDD5euiRH"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.test": "enode://ad38f94030a846cc7005b7a1f3b6b01bf4ef59d34e8d3d6f4d12df23d14ba8656702a435d34cf4df3b412c0c1923df5adcce8461321a0d8ffb9435b26e572c2a@47.52.255.194:443",
"node-01.do-ams3.eth.test": "enode://1d193635e015918fb85bbaf774863d12f65d70c6977506187ef04420d74ec06c9e8f0dcb57ea042f85df87433dab17a1260ed8dde1bdf9d6d5d2de4b7bf8e993@206.189.243.163:443",
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
}
},
"status.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.nodes.status.im"]
},
"status.test": {
"waku": {
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.nodes.status.im"]
},
"wakuv2.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/ip4/188.166.135.145/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/ip4/34.121.100.108/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im"]
},
"wakuv2.test": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im"]
"fleets": {
"eth.prod": {
"boot": {
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443",
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443"
},
"mail": {
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443",
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443"
},
"whisper": {
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443",
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443"
},
"rendezvous": {
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF",
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR"
}
},
"eth.staging": {
"boot": {
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443",
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443"
},
"mail": {
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443",
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443"
},
"whisper": {
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
"node-01.gc-us-central1-a.eth.staging": "enode://2d897c6e846949f9dcf10279f00e9b8325c18fe7fa52d658520ad7be9607c83008b42b06aefd97cfe1fdab571f33a2a9383ff97c5909ed51f63300834913237e@35.192.0.86:443",
"node-01.ac-cn-hongkong-c.eth.staging": "enode://00395686f5954662a3796e170b9e87bbaf68a050d57e9987b78a2292502dae44aae2b8803280a017ec9af9be0b3121db9d6b3693ab3a0451a866bcbedd58fdac@47.52.226.137:443"
},
"rendezvous": {
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE",
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu"
}
},
"wakuv2.prod": {
"tcp/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD"
},
"enr/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "enr:-M-4QLdAB-KyzT3QEsDoNa4LXT6RGH9BIylvTlDFLQhigWmxKEesulgc8AoKmVEUKj_4St6ThBKwyBc69tBfCe2hVTABgmlkgnY0gmlwhLymh5GKbXVsdGlhZGRyc7EALzYobm9kZS0wMS5kby1hbXMzLndha3V2Mi5wcm9kLnN0YXR1c2ltLm5ldAYfQN4DiXNlY3AyNTZrMaEDbl1X_zJIw3EAJGtmHMVn4Z2xhpSoUaP5ElsHKCv7hlWDdGNwgnZfg3VkcIIjKIV3YWt1Mg8",
"node-01.gc-us-central1-a.wakuv2.prod": "enr:-Nm4QNgc2L6L-4nk6jgllNDE1QDcn6kv2922rTRYs1wM3My_OmSsTimkMCIMh8fat6enFdYfuJ23KjWdF5whBz3zXgUBgmlkgnY0gmlwhCJ5ZGyKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS53YWt1djIucHJvZC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhA_30kHgQqfXZRioa4J_u5asgXTJ5iw_8w3lEICH4TFu_g3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "enr:-Nm4QOdTOKZJKTUUZ4O_W932CXIET-M9NamewDnL78P5u9DOGnZlK0JFZ4k0inkfe6iY-0JAaJVovZXc575VV3njeiABgmlkgnY0gmlwhAjS3ueKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy53YWt1djIucHJvZC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhAo0C-VvfgHiXrxZi3umDiooXMGY9FvYj5_d1Q4EeS7eyg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP"
},
"wss/p2p/waku": {
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA",
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/8000/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD"
}
},
"wakuv2.test": {
"tcp/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
},
"enr/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "enr:-M-4QCtJKX2WDloRYDT4yjeMGKUCRRcMlsNiZP3cnPO0HZn6IdJ035RPCqsQ5NvTyjqHzKnTM6pc2LoKliV4CeV0WrgBgmlkgnY0gmlwhIbRi9KKbXVsdGlhZGRyc7EALzYobm9kZS0wMS5kby1hbXMzLndha3V2Mi50ZXN0LnN0YXR1c2ltLm5ldAYfQN4DiXNlY3AyNTZrMaEDnr03Tuo77930a7sYLikftxnuG3BbC3gCFhA4632ooDaDdGNwgnZfg3VkcIIjKIV3YWt1Mg8",
"node-01.gc-us-central1-a.wakuv2.test": "enr:-Nm4QLHYoJ5WYQoVzyqPR-pwIeQvi3ONWs-EPwk3uUiBiDseN9Dd7fYbCvkMdeXcuZ-8U9IYdGm38VxSDf_Oq3zZ0cEBgmlkgnY0gmlwhGia74CKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS53YWt1djIudGVzdC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhA1giYsmWV9r2yJZYAiMGHJfjLlLeqAuTAokUGPN__pkxg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.ac-cn-hongkong-c.wakuv2.test": "enr:-Nm4QC0_ClHzbsutYzgT3jJm7ZY1D4shylAdd6Ac-L4uwAUha1oHM0zwoEkTORVt94W5Cpa0IiyrTcXAYLgpRXpVNUsBgmlkgnY0gmlwhC_y0kmKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy53YWt1djIudGVzdC5zdGF0dXNpbS5uZXQGH0DeA4lzZWNwMjU2azGhAhAm-P4q6mWONKcGnbLPU8WXZJ4Qs3AxIbrycvc7PVKsg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP"
},
"wss/p2p/waku": {
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS",
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/8000/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm"
}
},
"status.prod": {
"tcp/p2p/waku": {
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg",
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8"
},
"enr/p2p/waku": {
"node-01.do-ams3.status.prod": "enr:-M-4QLOTEs_ZFxCb09FgIezZd5KeTru5CWWyEtMWMN-yUABrerWxckU-pMIh3yO8VjxHpgZ4jU2WSXuK3goW4uYb6c4BgmlkgnY0gmlwhI_G-a6KbXVsdGlhZGRyc7EALzYobm9kZS0wMS5kby1hbXMzLnN0YXR1cy5wcm9kLnN0YXR1c2ltLm5ldAYBu94DiXNlY3AyNTZrMaECoVyonsTGEQvVioM562Q1fjzTb_vKD152PPIdsV7sM6SDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"node-02.do-ams3.status.prod": "enr:-M-4QIhQjPgSnoKXLsJAxbRzF8cZYYjOfdt1ysBkibcriCvXb9lWHDiRghIv11JQltK5KYFs2zrCKoQ-_ZoRXEs5FasBgmlkgnY0gmlwhKEj9HmKbXVsdGlhZGRyc7EALzYobm9kZS0wMi5kby1hbXMzLnN0YXR1cy5wcm9kLnN0YXR1c2ltLm5ldAYBu94DiXNlY3AyNTZrMaED1AYI2Ox27DnSqf2qoih5M2fNpHFq-OzJ3thREEApdiiDdGNwgnZfg3VkcIIjKIV3YWt1MgM",
"node-01.gc-us-central1-a.status.prod": "enr:-Nm4QPRAGqCjHCuu3DjbDVoLPqpE35Lfc3mjdCsmGTqdWmxjOF2NAbdYezEnukrz38TkTNXzEdslw_n_H5uUQ3hi-2EBgmlkgnY0gmlwhCPKN5mKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS5zdGF0dXMucHJvZC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAhoqdPkAZNvNRuzEecDGwnt5UbF98qwM16PZG3JmW6kUg3RjcIJ2X4N1ZHCCIyiFd2FrdTID",
"node-02.gc-us-central1-a.status.prod": "enr:-Nm4QEdveBFdGPTVPCmYBikMKtGFlvLnzvXfYLOWDLPtTejBLcV_9e5Ry7dqx5K027rn5zedG-HnNiHP_GBcdCpGnq0BgmlkgnY0gmlwhCKE1emKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDIuZ2MtdXMtY2VudHJhbDEtYS5zdGF0dXMucHJvZC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAwtASPpiz5Gq3zuFuWF4MTviQVipi3HaQGytF-4wfbdvg3RjcIJ2X4N1ZHCCIyiFd2FrdTID",
"node-01.ac-cn-hongkong-c.status.prod": "enr:-Nm4QOxEmmi5LQo3EwmHCagXOzVXzsLDGDwPDTL6ECmUCoXPYV0ldWvzMVqPOEPzXMCtECdk7xpleiNN85oKQxFiGnYBgmlkgnY0gmlwhC_yyjuKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy5zdGF0dXMucHJvZC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAgwDLi50TMXqxWTCnR_rjQP3Eeznjs645ZNBoRh5B3jhg3RjcIJ2X4N1ZHCCIyiFd2FrdTID",
"node-02.ac-cn-hongkong-c.status.prod": "enr:-Nm4QOqKQ4bi7sYE1ZXAqnryEGeJOnQxIzo9UK5xHY_GeP4healoFVspoG2FaUCSyIg8pa4X2P99BbC15iSh98NIgPYBgmlkgnY0gmlwhC_zgIaKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDIuYWMtY24taG9uZ2tvbmctYy5zdGF0dXMucHJvZC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAzE4YIBrPK5oT_9MvYEeggmaDd205iU4Nn1MAhU5xqY5g3RjcIJ2X4N1ZHCCIyiFd2FrdTID"
},
"wss/p2p/waku": {
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg",
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8"
}
},
"status.test": {
"tcp/p2p/waku": {
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76",
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi"
},
"enr/p2p/waku": {
"node-01.do-ams3.status.test": "enr:-M-4QI1qCnM3DMuZR2Y86FygFXPtm9fIRc4rFdUaDj0NbEA3Jl4In8mXAjUWgoei7W9Grc7oqtgibmIo-HIHHg7wrhMBgmlkgnY0gmlwhEDhUe2KbXVsdGlhZGRyc7EALzYobm9kZS0wMS5kby1hbXMzLnN0YXR1cy50ZXN0LnN0YXR1c2ltLm5ldAYBu94DiXNlY3AyNTZrMaECBNx5Erw5Jdsw-uI9pBjB_V2R6brvuVWE-MJwYCQKVv6DdGNwgnZfg3VkcIIjKIV3YWt1Mg8",
"node-01.gc-us-central1-a.status.test": "enr:-Nm4QFxGf89g3MGnCLYBxBgpXejyB44mvXvJSpNzjlRwNXO6BIn7hl66OJpESPWdH7ipHNemmz0e04wtJHe_wVV5woABgmlkgnY0gmlwhCJ6_HaKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS5zdGF0dXMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAzToWxPoQnnubNH_CIu7YHPV0RHadQVIKlpfMJxxC2eFg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.ac-cn-hongkong-c.status.test": "enr:-Nm4QCF2zwCuAZzxTtjjjbo5hn6vx0ICcEJBGRBMdDCfpoX5BGiApbfhEljEjpI4ePhYra_k0o5uI8eTTGYHkr6208gBgmlkgnY0gmlwhC_y6SSKbXVsdGlhZGRyc7g6ADg2MW5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy5zdGF0dXMudGVzdC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAmRvsjqPlfX7OOJ4x4F3GAOpBa4y4NQSoNHjX2XIo1lvg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP"
},
"wss/p2p/waku": {
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76",
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi"
}
},
"go-waku.prod": {
"tcp/p2p/waku": {
"node-01.do-ams3.go-waku.prod": "/dns4/node-01.do-ams3.go-waku.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkyScd7DiwgMwzfw8CFFhznH3wRzciqEUfjDzn7vyimR8c",
"node-01.gc-us-central1-a.go-waku.prod": "/dns4/node-01.gc-us-central1-a.go-waku.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmKTYnoPKebjWy63e1zPKiYRCQvm25W5mNSnCFE8EmzLga",
"node-01.ac-cn-hongkong-c.go-waku.prod": "/dns4/node-01.ac-cn-hongkong-c.go-waku.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkwUKwy66nhcSFeW7y5qijNqXC4ZD3TaMMqnoEbh3wK2xU"
},
"enr/p2p/waku": {
"node-01.do-ams3.go-waku.prod": "enr:-NC4QGRYrus1rbuI183CZmxjb1wL4_wdNMcJDKaxaTaRs-RUTXP6KQ0VxL8zGaPNNxLT45ItXS8dmQvcyBWUlTwqXfYBgmlkgnY0gmlwhIbRh8OKbXVsdGlhZGRyc7IAMDYpbm9kZS0wMS5kby1hbXMzLmdvLXdha3UucHJvZC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAjusiHwKZa-rftTSq-KnDnirfCBW-q5ClJf4YEw9N8_Jg3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.gc-us-central1-a.go-waku.prod": "enr:-Nq4QJuKC3qwV704_zzThJiIaV2Jb1YLLjRzSalpgrgAUV7vU0_fMYTQUshz6hcqds0lR3lHFzhCDEdrT6TmP1rBF1IBgmlkgnY0gmlwhCJ6XvOKbXVsdGlhZGRyc7g7ADk2Mm5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS5nby13YWt1LnByb2Quc3RhdHVzaW0ubmV0BgG73gOJc2VjcDI1NmsxoQNlE4TEM5FmqnyDaMQ4viBkHpx2FZb9SPVl_XsVCrn5q4N0Y3CCdl-DdWRwgiMohXdha3UyDw",
"node-01.ac-cn-hongkong-c.go-waku.prod": "enr:-Nq4QFd-E6Ej3RuGF_-zZWYLfIb4vpfhKNi6RiLWrt30O90oNuJnbhUo8rMvuX_sO95X6QoyHa9RaUYx9N7cywA4WWkBgmlkgnY0gmlwhAjSBH6KbXVsdGlhZGRyc7g7ADk2Mm5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy5nby13YWt1LnByb2Quc3RhdHVzaW0ubmV0BgG73gOJc2VjcDI1NmsxoQIeZXd0MFV5YU9q0pWt05cUEc0RnptCtJarNlnxV7OpJYN0Y3CCdl-DdWRwgiMohXdha3UyDw"
},
"wss/p2p/waku": {
"node-01.do-ams3.go-waku.prod": "/dns4/node-01.do-ams3.go-waku.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkyScd7DiwgMwzfw8CFFhznH3wRzciqEUfjDzn7vyimR8c",
"node-01.gc-us-central1-a.go-waku.prod": "/dns4/node-01.gc-us-central1-a.go-waku.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmKTYnoPKebjWy63e1zPKiYRCQvm25W5mNSnCFE8EmzLga",
"node-01.ac-cn-hongkong-c.go-waku.prod": "/dns4/node-01.ac-cn-hongkong-c.go-waku.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkwUKwy66nhcSFeW7y5qijNqXC4ZD3TaMMqnoEbh3wK2xU"
}
},
"go-waku.test": {
"tcp/p2p/waku": {
"node-01.do-ams3.go-waku.test": "/dns4/node-01.do-ams3.go-waku.test.statusim.net/tcp/30303/p2p/16Uiu2HAm9vnvCQgCDrynDK1h7GJoEZVGvnuzq84RyDQ3DEdXmcX7",
"node-01.gc-us-central1-a.go-waku.test": "/dns4/node-01.gc-us-central1-a.go-waku.test.statusim.net/tcp/30303/p2p/16Uiu2HAmPz63Xc6AuVkDeujz7YeZta18rcdau3Y1BzaxKAfDrBqz",
"node-01.ac-cn-hongkong-c.go-waku.test": "/dns4/node-01.ac-cn-hongkong-c.go-waku.test.statusim.net/tcp/30303/p2p/16Uiu2HAmBDbMWFiG9ki8sDw6fYtraSxo4oHU9HbuN43S2HVyq1FD"
},
"enr/p2p/waku": {
"node-01.do-ams3.go-waku.test": "enr:-NC4QKYOHGKa69sKLLKbRlcR890mmPRIboV0MUSMQtvjiwd7SISpBYqVibOpmTuS0kRlU6KmBQs_MXA9LPOBgMbRB7UBgmlkgnY0gmlwhIbRhj-KbXVsdGlhZGRyc7IAMDYpbm9kZS0wMS5kby1hbXMzLmdvLXdha3UudGVzdC5zdGF0dXNpbS5uZXQGAbveA4lzZWNwMjU2azGhAtd5TiUZInW1nFF7nZtkXrw0iuqOLyV31_f7EhuM_Fs-g3RjcIJ2X4N1ZHCCIyiFd2FrdTIP",
"node-01.gc-us-central1-a.go-waku.test": "enr:-Nq4QEb3btlua6_4EdC1SAF0wTl0JqI8Du34Bm7raZoYOAbHPmRzVt4rq-0ItCM3L4MkOpCFn_X26aTq-Q2YEK8DuGEBgmlkgnY0gmlwhCPft1uKbXVsdGlhZGRyc7g7ADk2Mm5vZGUtMDEuZ2MtdXMtY2VudHJhbDEtYS5nby13YWt1LnRlc3Quc3RhdHVzaW0ubmV0BgG73gOJc2VjcDI1NmsxoQOoVQePH5eRqlcCf-0XwZsoJPeZp1Mq59un_jYM9hUc6YN0Y3CCdl-DdWRwgiMohXdha3UyDw",
"node-01.ac-cn-hongkong-c.go-waku.test": "enr:-Nq4QCWN6qBpeK_1GiqE_F45k3MmBDxaOJ7X9fAOKO0qu_6xCPAkjOVz6Th_vn8n-CLdEizO5oJ6YOivuAiRHDdJ3q4BgmlkgnY0gmlwhAjaAm6KbXVsdGlhZGRyc7g7ADk2Mm5vZGUtMDEuYWMtY24taG9uZ2tvbmctYy5nby13YWt1LnRlc3Quc3RhdHVzaW0ubmV0BgG73gOJc2VjcDI1NmsxoQLqosp15CMf5c4k-z9MGM7_aiR0DGdmSrpjQ_xWnmsTOIN0Y3CCdl-DdWRwgiMohXdha3UyDw"
},
"wss/p2p/waku": {
"node-01.do-ams3.go-waku.test": "/dns4/node-01.do-ams3.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm9vnvCQgCDrynDK1h7GJoEZVGvnuzq84RyDQ3DEdXmcX7",
"node-01.gc-us-central1-a.go-waku.test": "/dns4/node-01.gc-us-central1-a.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPz63Xc6AuVkDeujz7YeZta18rcdau3Y1BzaxKAfDrBqz",
"node-01.ac-cn-hongkong-c.go-waku.test": "/dns4/node-01.ac-cn-hongkong-c.go-waku.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmBDbMWFiG9ki8sDw6fYtraSxo4oHU9HbuN43S2HVyq1FD"
}
}
}
},
"meta": {
"hostname": "node-01.do-ams3.proxy.misc",
"timestamp": "2021-06-07T00:00:09.836740"
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

+11 -12
View File
@@ -11,6 +11,7 @@
[cljs-bean "1.3.0"]
[com.cognitect/transit-cljs "0.8.248"]
[mvxcvi/alphabase "1.0.0"]
[camel-snake-kebab "0.4.3"]
;; dev dependencies
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
@@ -19,7 +20,6 @@
;; routing
[bidi "2.1.6"]
;; test dependencies
[camel-snake-kebab "0.4.3"]
[day8.re-frame/test "0.1.5"]
[com.taoensso/tufte "2.1.0"]]
@@ -38,7 +38,7 @@
{:mobile
{:target :react-native
:output-dir "app"
:init-fn status-im2.setup.core/init
:init-fn status-im2.core/init
;; When false, the Shadow-CLJS watcher won't automatically refresh
;; the target files (a.k.a hot reload). When false, you can manually
;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`.
@@ -47,8 +47,8 @@
:build-notify status-im2.setup.hot-reload/build-notify
:preloads [re-frisk-remote.preload]}
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es5
:closure-defines
{re-frame.trace/trace-enabled? true}
@@ -58,12 +58,11 @@
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
:local-ip #shadow/env "SHADOW_HOST"}
:chunks {:fleets status-im.fleet.default-fleet/default-fleets
:chats status-im.chat.default-chats/default-chats}
:chunks {:fleets status-im.fleet.default-fleet/default-fleets}
:release
{:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es6
;;disable for android build as there
;;is an intermittent warning with deftype
@@ -90,8 +89,8 @@
:ui-driven
true
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options
{;; needed because we override require and it
;; messes with source-map which reports callstack
@@ -113,8 +112,8 @@
:compiler-options {:optimizations :simple
:source-map false}}
:component-test {:target :npm-module
:entries [quo2.core-spec]
:ns-regexp "-component-spec$"
:entries [quo2.core-spec status-im2.core-spec]
:ns-regexp "component-spec$"
:output-dir "component-spec"
:compiler-options {:warnings-as-errors false
:static-fns false
+48 -12
View File
@@ -2,39 +2,75 @@ import { useDerivedValue, interpolate } from 'react-native-reanimated';
// Generic Worklets
// 1. kebab-case styles are not working for worklets
// so we have to convert kebab case styles into camel case styles
// 2. remove keys with nil value, else useAnimatedStyle will throw an error
// https://github.com/status-im/status-mobile/issues/14756
export function applyAnimationsToStyle(animations, style) {
return function() {
'worklet'
var animatedStyle = {}
// Normal Style
for (var key in style) {
if (key == "transform") {
var transforms = style[key];
var filteredTransforms = []
for (var transform of transforms) {
var transformKey = Object.keys(transform)[0];
var transformValue = transform[transformKey];
if(transformValue !== null) {
filteredTransforms.push(
{[transformKey.replace(/-./g, x=>x[1].toUpperCase())]: transformValue}
);
}
}
animatedStyle[key] = filteredTransforms;
} else {
var value = style[key];
if (value !== null) {
animatedStyle[key.replace(/-./g, x=>x[1].toUpperCase())] = value;
}
}
}
// Animations
for (var key in animations) {
if (key == "transform") {
var transforms = animations[key];
var animatedTransforms = []
for (var transform of transforms) {
var transformKey = Object.keys(transform)[0];
animatedTransforms.push({
[transformKey]: transform[transformKey].value
})
var transformValue = transform[transformKey].value;
if (transformValue !== null) {
animatedTransforms.push(
{[transformKey.replace(/-./g, x=>x[1].toUpperCase())]: transformValue}
);
}
}
animatedStyle[key] = animatedTransforms;
} else {
animatedStyle[key] = animations[key].value;
var animatedValue = animations[key].value;
if (animatedValue !== null) {
animatedStyle[key.replace(/-./g, x=>x[1].toUpperCase())] = animatedValue;
}
}
}
return Object.assign(animatedStyle, style);
return animatedStyle;
};
};
export function interpolateValue(sharedValue, inputRange, outputRange) {
export function interpolateValue(sharedValue, inputRange, outputRange, extrapolation) {
return useDerivedValue(
function () {
'worklet'
return interpolate(sharedValue.value, inputRange, outputRange);
return interpolate(sharedValue.value, inputRange, outputRange, extrapolation);
}
);
}
+55 -55
View File
@@ -1,8 +1,7 @@
(ns mocks.js-dependencies
(:require-macros [status-im.utils.slurp :refer [slurp]])
(:require [status-im.fleet.default-fleet :refer (default-fleets)])
(:require [status-im.utils.test :as utils.test])
(:require [status-im.chat.default-chats :refer (default-chats)]))
(:require [status-im.utils.test :as utils.test]))
;; to generate a js Proxy at js/__STATUS_MOBILE_JS_IDENTITY_PROXY__ that accept any (.xxx) call and
;; return itself
@@ -206,58 +205,60 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(def react-native-reanimated
#js
{:default #js
{:createAnimatedComponent identity
:eq nil
:greaterOrEq nil
:greaterThan nil
:lessThan nil
:lessOrEq nil
:add nil
:diff nil
:divide nil
:sub nil
:multiply nil
:abs nil
:min nil
:max nil
:neq nil
:and nil
:or nil
:not nil
:set nil
:startClock nil
:stopClock nil
:Value nil
:Clock nil
:debug nil
:log nil
:event nil
:cond nil
:block nil
:interpolateNode nil
:call nil
:timing nil
:onChange nil
:View #js {}
:Image #js {}
:ScrollView #js {}
:Text #js {}
:Extrapolate #js {:CLAMP nil}
:Code #js {}}
:EasingNode #js
{:bezier identity
:linear identity}
:clockRunning nil
:useSharedValue (fn [])
:useAnimatedStyle (fn [])
:withTiming (fn [])
:withDelay (fn [])
:Easing #js {:bezier identity}
:Keyframe (fn [])
:SlideOutUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:SlideInUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:LinearTransition js/__STATUS_MOBILE_JS_IDENTITY_PROXY__})
{:default #js
{:createAnimatedComponent identity
:eq nil
:greaterOrEq nil
:greaterThan nil
:lessThan nil
:lessOrEq nil
:add nil
:diff nil
:divide nil
:sub nil
:multiply nil
:abs nil
:min nil
:max nil
:neq nil
:and nil
:or nil
:not nil
:set nil
:startClock nil
:stopClock nil
:Value nil
:Clock nil
:debug nil
:log nil
:event nil
:cond nil
:block nil
:interpolateNode nil
:call nil
:timing nil
:onChange nil
:View #js {}
:Image #js {}
:ScrollView #js {}
:Text #js {}
:Extrapolate #js {:CLAMP nil}
:Code #js {}}
:EasingNode #js
{:bezier identity
:linear identity}
:clockRunning nil
:useSharedValue (fn [])
:useAnimatedStyle (fn [])
:withTiming (fn [])
:withDelay (fn [])
:Easing #js {:bezier identity}
:Keyframe (fn [])
:enableLayoutAnimations (fn [])
:SlideOutUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:SlideInUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:LinearTransition js/__STATUS_MOBILE_JS_IDENTITY_PROXY__})
(def react-native-gesture-handler
#js
{:default #js {}
@@ -396,7 +397,6 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
"../src/js/bottom_sheet.js" bottom-sheet
"../src/js/record_audio_worklets.js" record-audio-worklets
"./fleets.js" default-fleets
"./chats.js" default-chats
"@walletconnect/client" wallet-connect-client
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
"../translations/de.json" (js/JSON.parse (slurp "./translations/de.json"))
+1 -1
View File
@@ -134,7 +134,7 @@
:style {:width outer-dimensions
:height outer-dimensions
:border-radius outer-dimensions}}
(when (and ring? identicon?)
(when (and false (and ring? identicon?)) ;;TODO not implemented yet
[icons/icon :i/identicon-ring
{:size outer-dimensions
:no-color true}])
@@ -1,4 +1,4 @@
(ns quo2.components.banners.--tests--.banner-component-spec
(ns quo2.components.banners.banner.component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.banners.banner.view :as banner]
[reagent.core :as reagent]))
@@ -15,3 +15,13 @@
(.toBeTruthy))
(-> (js/expect (rtl/screen.getByText "5"))
(.toBeTruthy))))
(js/global.test "banner component fires an event when pressed"
(let [mock-fn (js/jest.fn)]
(fn []
(render-banner {:on-press mock-fn
:pins-count "5"
:latest-pin-text "this message"})
(rtl/fireEvent.press (rtl/screen.getByText "this message"))
(-> (js/expect mock-fn)
(.toHaveBeenCalledTimes 1)))))
+19 -11
View File
@@ -3,17 +3,25 @@
(def container
{:width "100%"
:height 50
:background-color colors/primary-50-opa-20
:flex-direction :row
:align-items :center
:padding-horizontal 20
:padding-vertical 10})
{:height 40
:background-color colors/primary-50-opa-20
:flex-direction :row
:align-items :center
:padding-right 22
:padding-left 20
:padding-vertical 10})
(def counter
{:padding-right 22
:height 20
:width 20
{:flex 1
:justify-content :center
:align-items :center})
:align-items :center})
(def icon
{:flex 1
:margin-right 10})
(defn text
[hide-pin?]
{:flex (if hide-pin? 16 15)
:margin-right 10})
+22 -16
View File
@@ -3,22 +3,28 @@
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(defn banner
[{:keys [show-pin? latest-pin-text pins-count on-press]}]
[rn/touchable-opacity
{:accessibility-label :pinned-banner
:style style/container
:active-opacity 1
:on-press on-press}
(when show-pin? [icons/icon :i/pin {:size 20}])
[text/text
{:number-of-lines 1
:size :paragraph-2
:style {:margin-left 10 :margin-right 50}}
latest-pin-text]
[rn/view
{:accessibility-label :pins-count
:style style/counter}
(when (pos? pins-count) [counter/counter {:type :secondary} pins-count])]])
[{:keys [hide-pin? latest-pin-text pins-count on-press]}]
(when (pos? pins-count)
[rn/touchable-opacity
{:accessibility-label :pinned-banner
:style style/container
:active-opacity 1
:on-press on-press}
(when-not hide-pin?
[rn/view {:style style/icon}
[icons/icon :i/pin
{:color (colors/theme-colors colors/neutral-100 colors/white)
:size 20}]])
[rn/view {:style (style/text hide-pin?)}
[text/text
{:number-of-lines 1
:size :paragraph-2}
latest-pin-text]]
[rn/view
{:accessibility-label :pins-count
:style style/counter}
(when (> pins-count 1) [counter/counter {:type :secondary} pins-count])]]))
+3 -4
View File
@@ -1,6 +1,5 @@
(ns quo2.components.code.snippet
(:require ["react-native" :as react-native]
[cljs-bean.core :as bean]
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[oops.core :as oops]
[quo2.components.buttons.button :as button]
@@ -168,8 +167,8 @@
:on-copy-press #(when on-copy-press
(on-copy-press children))})
;; Default props to adapt Highlighter for react-native.
:CodeTag react-native/View
:PreTag react-native/View
;;:CodeTag react-native/View
;;:PreTag react-native/View
:show-line-numbers false
:style #js {}
:custom-style #js {:backgroundColor nil}}
@@ -5,19 +5,8 @@
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(defn community-icon-view
[community-icon]
[rn/view
{:width 32
:height 32}
[fast-image/fast-image
{:source {:uri community-icon}
:style {:height 32
:border-radius 16
:width 32}}]])
[quo2.components.community.icon :as community-icon]
[react-native.core :as rn]))
(defn notification-view
[{:keys [muted?
@@ -54,27 +43,18 @@
unread-messages?
unread-mentions-count
community-icon
tokens
background-color]}]
tokens]}]
[rn/view
{:style (merge (style/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
{:margin-bottom 12})}
[rn/touchable-highlight
(merge {:style {:height 56
:border-radius 16}}
props)
[rn/view {:flex 1}
[rn/view
{:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8
:background-color background-color}
[rn/view]
(when community-icon
[community-icon-view community-icon])
[rn/view (style/list-info-container)
[community-icon/community-icon
{:images community-icon} 32]
[rn/view
{:flex 1
:margin-horizontal 12}
@@ -109,39 +89,36 @@
community-icon
tokens
locked?]}]
[rn/view {:margin-bottom 20}
[rn/touchable-highlight
(merge {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}}
props)
[rn/view {:flex 1}
[rn/touchable-highlight
(merge {:underlay-color (colors/theme-colors
colors/neutral-5
colors/neutral-95)
:style {:border-radius 12}}
props)
[rn/view {:flex 1}
[rn/view (style/membership-info-container)
[community-icon/community-icon
{:images community-icon} 32]
[rn/view
{:flex-direction :row
:border-radius 16
:align-items :center}
{:flex 1
:margin-left 12
:justify-content :center}
[text/text
{:accessibility-label :chat-name-text
:number-of-lines 1
:ellipsize-mode :tail
:weight :semi-bold
:size :paragraph-1}
name]]
(when community-icon
[community-icon-view community-icon])
[rn/view
{:flex 1
:margin-left 12
:justify-content :center}
[text/text
{:accessibility-label :chat-name-text
:number-of-lines 1
:ellipsize-mode :tail
:weight :semi-bold
:size :paragraph-1}
name]]
[rn/view
{:justify-content :center
:margin-right 16}
(if (= status :gated)
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]]])
[rn/view
{:justify-content :center
:margin-right 16}
(if (= status :gated)
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]])
@@ -46,12 +46,12 @@
^{:key id}
[rn/view {:margin-right 8}
[tag/tag
{:id id
:size 24
:label tag-label
:type :emoji
:labelled true
:resource resource}]])])
{:id id
:size 24
:label tag-label
:type :emoji
:labelled? true
:resource resource}]])])
(defn community-title
[{:keys [title description size] :or {size :small}}]
+1 -1
View File
@@ -10,4 +10,4 @@
:border-width 0
:border-color :transparent
:width size
:height size}}]))
:height size}}]))
+12 -11
View File
@@ -77,19 +77,20 @@
colors/white
colors/neutral-90)})
(defn list-view-content-container
(defn list-info-container
[]
{:flex-direction :row
:border-radius 16
:align-items :center
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
{:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8})
(defn list-view-chat-icon
(defn membership-info-container
[]
{:border-radius 32
:padding 12})
{:flex-direction :row
:border-radius 16
:align-items :center
:height 48})
(defn community-title-description-container
[margin-top]
@@ -107,4 +108,4 @@
[]
{:position :absolute
:top 8
:right 8})
:right 8})
@@ -1,14 +1,14 @@
(ns quo2.components.community.token-gating
(:require [quo.react-native :as rn]
[quo2.components.avatars.channel-avatar :as channel-avatar]
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
[quo2.components.buttons.button :as button]
[quo2.components.icon :as icon]
[quo2.components.info.information-box :as information-box]
[quo2.components.markdown.text :as text]
[quo2.components.tags.token-tag :as token-tag]
[quo2.foundations.colors :as colors]
[i18n.i18n :as i18n]
[status-im.ui.components.fast-image :as fast-image]))
[utils.i18n :as i18n]
[react-native.fast-image :as fast-image]
[react-native.core :as rn]))
(def ^:private token-tag-horizontal-spacing 7)
(def token-tag-vertical-spacing 5)
@@ -1,6 +1,6 @@
(ns quo2.components.drawers.--tests--.action-drawers-component-spec
(ns quo2.components.drawers.action-drawers.component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.drawers.action-drawers :as action-drawer]
[quo2.components.drawers.action-drawers.view :as action-drawer]
[reagent.core :as reagent]))
(defn render-action-drawer
@@ -50,4 +50,4 @@
:add-divider? true
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getAllByLabelText "divider"))
(.toBeTruthy))))
(.toBeTruthy))))
@@ -0,0 +1,41 @@
(ns quo2.components.drawers.action-drawers.style
(:require [quo2.foundations.colors :as colors]))
(def divider
{:border-top-width 1
:border-top-color (colors/theme-colors
colors/neutral-10
colors/neutral-90)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row})
(defn container
[sub-label]
{:border-radius 12
:height (if sub-label 58 50)
:margin-horizontal 8})
(defn row-container
[sub-label]
{:height (if sub-label 58 50)
:margin-horizontal 12
:flex-direction :row})
(def left-icon
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20})
(def text-container
{:flex 1
:justify-content :center})
(def right-icon
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20})
@@ -1,8 +1,9 @@
(ns quo2.components.drawers.action-drawers
(ns quo2.components.drawers.action-drawers.view
(:require [quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[react-native.core :as rn]
[quo2.components.drawers.action-drawers.style :as style]))
(defn- get-icon-color
[danger?]
@@ -12,14 +13,7 @@
(def divider
[rn/view
{:style {:border-top-width 1
:border-top-color (colors/theme-colors
colors/neutral-10
colors/neutral-90)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}
{:style style/divider
:accessible true
:accessibility-label :divider}])
@@ -38,32 +32,20 @@
(when add-divider? divider)
[rn/touchable-highlight
{:accessibility-label accessibility-label
:style {:border-radius 12
:height (if sub-label 58 50)
:margin-horizontal 8}
:style (style/container sub-label)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
:on-press on-press}
[rn/view
{:style
{:height (if sub-label 58 50)
:margin-horizontal 12
:flex-direction :row}}
{:style (style/row-container sub-label)}
[rn/view
{:accessibility-label :left-icon-for-action
:accessible true
:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
:style style/left-icon}
[icon/icon icon
{:color (get-icon-color danger?)
:size 20}]]
[rn/view
{:style
{:flex 1
:justify-content :center}}
{:style style/text-container}
[text/text
{:size :paragraph-1
:weight :medium
@@ -79,11 +61,7 @@
sub-label])]
(when right-icon
[rn/view
{:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}
{:style style/right-icon
:accessible true
:accessibility-label :right-icon-for-action}
[icon/icon right-icon
@@ -0,0 +1,13 @@
(ns quo2.components.drawers.permission-context.component-spec
(:require [quo2.components.drawers.permission-context.view :as permission-context]
[react-native.core :as rn]
[test-helpers.component :as h]))
(h/describe "permission context"
(h/test "it tests the default render"
(h/render [permission-context/view
[rn/text
{:accessibility-label :accessibility-id}
"a sample label"]])
(-> (js/expect (h/get-by-label-text :accessibility-id))
(.toBeTruthy))))
@@ -0,0 +1,20 @@
(ns quo2.components.drawers.permission-context.style
(:require [quo2.foundations.colors :as colors]))
(def radius 20)
(def container
{:flex-direction :row
:background-color (colors/theme-colors colors/white colors/neutral-90)
:height 82
:padding-top 16
:padding-bottom 48
:justify-content :center
:padding-right :auto
:shadow-offset {:width 0
:height 2}
:shadow-radius radius
:border-top-left-radius radius
:border-top-right-radius radius
:elevation 2
:shadow-opacity 1
:shadow-color colors/shadow})
@@ -0,0 +1,12 @@
(ns quo2.components.drawers.permission-context.view
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.drawers.permission-context.style :as style]))
(defn view
[children on-press]
[rn/touchable-highlight
{:on-press on-press
:underlay-color (colors/theme-colors :transparent colors/neutral-95-opa-70)
:style style/container}
children])
+1 -7
View File
@@ -4,16 +4,10 @@
(def icon-path "./resources/images/icons2/")
(defn combine-path
[path el]
(if (System/getenv "COMPONENT_TEST")
(str "." path el "@2x.png")
(str "." path el ".png")))
(defn require-icon
[size path]
(fn [el]
(let [s (combine-path path el)
(let [s (str "." path el ".png")
k (-> el
(string/replace "_" "-")
(string/replace " " "-")
@@ -3,8 +3,7 @@
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.messages.author.style :as style]
[react-native.core :as rn]
[status-im.utils.utils :as utils]))
[react-native.core :as rn]))
(def middle-dot "·")
@@ -35,7 +34,7 @@
profile-name])])))
(defn author
[{:keys [profile-name nickname chat-key ens-name time-str contact? verified? untrustworthy?]}]
[{:keys [profile-name nickname short-chat-key ens-name time-str contact? verified? untrustworthy?]}]
[:f>
(fn []
(let [ens? (-> ens-name string/blank? not)
@@ -85,7 +84,7 @@
{:monospace true
:size :paragraph-2
:style style/chat-key-text}
(utils/get-shortened-address chat-key)])
short-chat-key])
(when-not ens?
[text/text
{:monospace true
@@ -9,7 +9,7 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[i18n.i18n :as i18n]))
[utils.i18n :as i18n]))
(def ^:private max-reply-length
280)
+18 -12
View File
@@ -1,5 +1,5 @@
(ns quo2.components.notifications.toast
(:require [i18n.i18n :as i18n]
(:require [utils.i18n :as i18n]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
@@ -8,14 +8,14 @@
[react-native.core :as rn]))
(def ^:private themes
{:container {:light {:background-color colors/white-opa-70}
:dark {:background-color colors/neutral-80-opa-70}}
:text {:light {:color colors/neutral-100}
:dark {:color colors/white}}
:icon {:light {:color colors/neutral-100}
:dark {:color colors/white}}
:action-container {:light {:background-color :colors/neutral-80-opa-5}
:dark {:background-color :colors/white-opa-5}}})
{:container {:dark {:background-color colors/white-opa-70}
:light {:background-color colors/neutral-80-opa-70}}
:text {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:icon {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:action-container {:dark {:background-color :colors/neutral-80-opa-5}
:light {:background-color :colors/white-opa-5}}})
(defn- merge-theme-style
[component-key styles]
@@ -23,7 +23,9 @@
(defn toast-action-container
[{:keys [on-press style]} & children]
[rn/touchable-highlight {:on-press on-press}
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge
@@ -40,7 +42,8 @@
(defn toast-undo-action
[duration on-press]
[toast-action-container {:on-press on-press}
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
@@ -63,7 +66,10 @@
[rn/view {:style {:padding 2}} left]
[rn/view {:style {:padding 4 :flex 1}}
[text/text
{:size :paragraph-2 :weight :medium :style (merge-theme-style :text {})}
{:size :paragraph-2
:weight :medium
:style (merge-theme-style :text {})
:accessibility-label :toast-content}
middle]]
(when right right)]])
@@ -0,0 +1,68 @@
(ns quo2.components.profile.collectible.style
(:require [quo2.foundations.colors :as colors]))
(def tile-style-by-size
{:xl {:width 160
:height 160
:border-radius 12}
:lg {:width 104
:height 104
:border-radius 10}
:md {:width 76
:height 76
:border-radius 10}
:sm {:width 48
:height 48
:border-radius 8}
:xs {:width 36
:height 36
:border-radius 8}})
(def tile-outer-container
{:width 176
:height 176
:padding 8})
(def tile-inner-container
{:position :relative
:flex 1})
(def tile-sub-container
{:position :absolute
:width 76
:height 76
:bottom 0
:right 0})
(def top-left
{:position :absolute
:top 0
:left 0})
(def top-right
{:position :absolute
:top 0
:right 0})
(def bottom-left
{:position :absolute
:bottom 0
:left 0})
(def bottom-right
{:position :absolute
:bottom 0
:right 0})
(defn remaining-tiles
[]
(let [bg-color (colors/theme-colors colors/neutral-20 colors/neutral-80)
tile-size (tile-style-by-size :xs)]
(assoc tile-size
:justify-content :center
:align-items :center
:background-color bg-color)))
(defn remaining-tiles-text
[]
{:color (colors/theme-colors colors/neutral-60 colors/neutral-40)})
@@ -0,0 +1,97 @@
(ns quo2.components.profile.collectible.view
(:require [quo2.components.markdown.text :as text]
[quo2.components.profile.collectible.style :as style]
[react-native.core :as rn]))
(defn remaining-tiles
[amount]
[rn/view {:style (merge style/bottom-right (style/remaining-tiles))}
[text/text
{:style (style/remaining-tiles-text)
:size :paragraph-2
:weight :medium}
(str "+" amount)]])
(defn tile
[{:keys [style resource size]}]
(let [source (if (string? resource) {:uri resource} resource)]
[rn/view {:style style}
[rn/image
{:style (style/tile-style-by-size size)
:source source}]]))
(defn two-tiles
[{:keys [images size]}]
[:<>
[tile
{:style style/top-left
:size size
:resource (first images)}]
[tile
{:style style/bottom-right
:size size
:resource (second images)}]])
(defn three-tiles
[{:keys [tiles size]}]
(let [[image-1 image-2 image-3 & _] tiles]
[:<>
[tile
{:style style/top-left
:size size
:resource image-1}]
[tile
{:style style/top-right
:size size
:resource image-2}]
[tile
{:style style/bottom-left
:size size
:resource image-3}]]))
(defn tile-container
[{:keys [images]}]
(let [num-images (count images)]
(case num-images
1 [tile
{:resource (first images)
:size :xl}]
2 [two-tiles
{:images images
:size :lg}]
3 [three-tiles
{:tiles images
:size :md}]
(let [[first-three-images remaining-images] (split-at 3 images)]
[:<>
[three-tiles {:tiles first-three-images :size :md}]
[rn/view {:style style/tile-sub-container}
(case num-images
4 [tile
{:resource (nth images 3 nil)
:size :md}]
5 [two-tiles
{:images (take 2 remaining-images)
:size :sm}]
6 [three-tiles
{:tiles (take 3 remaining-images)
:size :xs}]
7 [:<>
[three-tiles
{:tiles (take 3 remaining-images)
:size :xs}]
[tile
{:style style/bottom-right
:size :xs
:resource (nth remaining-images 3 nil)}]]
[:<>
[three-tiles
{:tiles (take 3 remaining-images)
:size :xs}]
[remaining-tiles (- (count remaining-images) 3)]])]]))))
(defn collectible
[{:keys [images]}]
[rn/view {:style style/tile-outer-container}
[rn/view {:style style/tile-inner-container}
[tile-container {:images images}]]])
@@ -0,0 +1,159 @@
(ns quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec
(:require [quo2.components.record-audio.record-audio.view :as record-audio]
[status-im.audio.core :as audio]
[test-helpers.component :as h]))
(h/describe "record audio component"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/test "renders record-audio"
(h/render [record-audio/record-audio])
(-> (h/expect (h/get-by-test-id "record-audio"))
(.toBeTruthy)))
(h/test "record-audio on-start-recording works"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-start-recording event}])
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(-> (h/expect event)
(.toHaveBeenCalledTimes 1))))
(h/test "record-audio on-reviewing-audio works"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-reviewing-audio event}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))]
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/advance-timers-by-time 500)
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(-> (h/expect event)
(.toHaveBeenCalledTimes 1)))))
(h/test "record-audio on-send works after reviewing audio"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-send event}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/get-recorder-file-path (fn [] "audio-file-path")]
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/advance-timers-by-time 500)
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 80
:locationY 80}})
(-> (js/expect event)
(.toHaveBeenCalledTimes 1))
(-> (js/expect event)
(.toHaveBeenCalledWith "audio-file-path")))))
(h/test "record-audio on-send works after sliding to the send button"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-send event}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/stop-recording (fn [_ on-stop _]
(on-stop))
audio/get-recorder-file-path (fn [] "audio-file-path")]
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/advance-timers-by-time 500)
(h/fire-event
:on-responder-move
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 80
:locationY -30
:pageX 80
:pageY -30}})
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 40
:locationY 80}})
(-> (js/expect event)
(.toHaveBeenCalledTimes 1))
(-> (js/expect event)
(.toHaveBeenCalledWith "audio-file-path")))))
(h/test "record-audio on-cancel works after reviewing audio"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-cancel event}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))]
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/advance-timers-by-time 500)
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 40
:locationY 80}})
(-> (js/expect event)
(.toHaveBeenCalledTimes 1)))))
(h/test "cord-audio on-cancel works after sliding to the cancel button"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-cancel event}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/stop-recording (fn [_ on-stop _]
(on-stop))]
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX 70
:locationY 70}})
(h/advance-timers-by-time 500)
(h/fire-event
:on-responder-move
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX -30
:locationY 80
:pageX -30
:pageY 80}})
(h/fire-event
:on-responder-release
(h/get-by-test-id "record-audio")
{:nativeEvent {:locationX -10
:locationY 70}})
(-> (js/expect event)
(.toHaveBeenCalledTimes 1))))))
@@ -0,0 +1,88 @@
(ns quo2.components.record-audio.record-audio.buttons.delete-button
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
animate-easing-with-delay
animate-linear
set-value]]))
(defn delete-button
[recording? ready-to-delete? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 20)
scale (reanimated/use-shared-value 1)
connector-opacity (reanimated/use-shared-value 0)
connector-width (reanimated/use-shared-value 24)
connector-height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
start-x-animation (fn []
(animate-linear-with-delay translate-x 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
(animate-easing-with-delay connector-width 56 83.33 80)
(animate-easing-with-delay connector-height 56 83.33 80)
(animate-easing-with-delay border-radius-first-half 28 83.33 80)
(animate-easing-with-delay border-radius-second-half 28 83.33 80))
reset-x-animation (fn []
(animate-linear translate-x 0 100)
(set-value connector-opacity 0)
(set-value connector-width 24)
(set-value connector-height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))
fade-in-animation (fn []
(animate-linear translate-x 0 200)
(animate-linear opacity 1 200))
fade-out-animation (fn []
(animate-linear
translate-x
(if @reviewing-audio? 35 20)
200)
(if @reviewing-audio?
(animate-linear scale 0.75 200)
(animate-linear opacity 0 200))
(set-value connector-opacity 0)
(set-value connector-width 24)
(set-value connector-height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))
fade-out-reset-animation (fn []
(animate-linear opacity 0 200)
(animate-linear-with-delay translate-x 20 0 200)
(animate-linear-with-delay scale 1 0 200))]
(use-effect (fn []
(if @recording?
(fade-in-animation)
(fade-out-animation)))
[@recording?])
(use-effect (fn []
(when-not @reviewing-audio?
(fade-out-reset-animation)))
[@reviewing-audio?])
(use-effect (fn []
(cond
@ready-to-delete?
(start-x-animation)
@recording?
(reset-x-animation)))
[@ready-to-delete?])
[:<>
[reanimated/view {:style (style/delete-button-container opacity)}
[reanimated/view
{:style (style/delete-button-connector connector-opacity
connector-width
connector-height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
{:style (style/delete-button scale translate-x opacity)
:pointer-events :none}
[icons/icon :i/delete
{:color colors/white
:size 20}]]]))])
@@ -0,0 +1,85 @@
(ns quo2.components.record-audio.record-audio.buttons.lock-button
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
animate-easing-with-delay
animate-linear
set-value]]))
(defn lock-button
[recording? ready-to-lock? locked?]
[:f>
(fn []
(let [translate-x-y (reanimated/use-shared-value 20)
opacity (reanimated/use-shared-value 0)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 24)
height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
start-x-y-animation (fn []
(animate-linear-with-delay translate-x-y 8 50 116.66)
(animate-easing-with-delay connector-opacity 1 0 80)
(animate-easing-with-delay width 56 83.33 63.33)
(animate-easing-with-delay height 56 83.33 63.33)
(animate-easing-with-delay border-radius-first-half
28
83.33
63.33)
(animate-easing-with-delay border-radius-second-half
28
83.33
63.33))
reset-x-y-animation (fn []
(animate-linear translate-x-y 0 100)
(set-value connector-opacity 0)
(set-value width 24)
(set-value height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))
fade-in-animation (fn []
(animate-linear translate-x-y 0 220)
(animate-linear opacity 1 220))
fade-out-animation (fn []
(animate-linear translate-x-y 20 200)
(animate-linear opacity 0 200)
(set-value connector-opacity 0)
(set-value width 24)
(set-value height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))]
(use-effect (fn []
(if @recording?
(fade-in-animation)
(fade-out-animation)))
[@recording?])
(use-effect (fn []
(cond
@ready-to-lock?
(start-x-y-animation)
(and @recording? (not @locked?))
(reset-x-y-animation)))
[@ready-to-lock?])
(use-effect (fn []
(if @locked?
(fade-out-animation)
(reset-x-y-animation)))
[@locked?])
[:<>
[reanimated/view {:style (style/lock-button-container opacity)}
[reanimated/view
{:style (style/lock-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
{:style (style/lock-button translate-x-y opacity)
:pointer-events :none}
[icons/icon (if @ready-to-lock? :i/locked :i/unlocked)
{:color (colors/theme-colors colors/black colors/white)
:size 20}]]]))])
@@ -0,0 +1,28 @@
(ns quo2.components.record-audio.record-audio.buttons.record-button
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.button :as button]
[quo2.components.record-audio.record-audio.helpers :refer [set-value]]))
(defn record-button
[recording? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 1)
show-animation #(set-value opacity 1)
hide-animation #(set-value opacity 0)]
(use-effect (fn []
(if (or @recording? @reviewing-audio?)
(hide-animation)
(show-animation)))
[@recording? @reviewing-audio?])
[reanimated/view {:style (style/record-button-container opacity)}
[button/button
{:type :outline
:size 32
:width 32
:accessibility-label :mic-button}
[icons/icon :i/audio {:color (colors/theme-colors colors/neutral-100 colors/white)}]]]))])
@@ -0,0 +1,212 @@
(ns quo2.components.record-audio.record-audio.buttons.record-button-big
(:require [quo.react :refer [memo]]
[quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as reanimated]
[status-im.audio.core :as audio]
[taoensso.timbre :as log]
[cljs-bean.core :as bean]
[reagent.core :as reagent]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear
animate-linear-with-delay
animate-linear-with-delay-loop
animate-easing
set-value]]))
(def ^:private scale-to-each 1.8)
(def ^:private scale-to-total 2.6)
(def ^:private scale-padding 0.16)
(def ^:private opacity-from-lock 1)
(def ^:private opacity-from-default 0.5)
(def ^:private signal-anim-duration 3900)
(def ^:private signal-anim-duration-2 1950)
(def ^:private record-audio-worklets (js/require "../src/js/record_audio_worklets.js"))
(defn- ring-scale
[scale substract]
(.ringScale ^js record-audio-worklets
scale
substract))
(def ^:private animated-ring
(reagent/adapt-react-class
(memo
(fn [props]
(let [{:keys [scale opacity color]} (bean/bean props)]
(reagent/as-element
[reanimated/view {:style (style/animated-circle scale opacity color)}]))))))
(defn record-button-big
[recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating?
record-button-at-initial-position? locked? reviewing-audio? recording-timer recording-length-ms
clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel]
[:f>
(fn []
(let [scale (reanimated/use-shared-value 1)
opacity (reanimated/use-shared-value 0)
opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default)
animations (map
(fn [index]
(let [ring-scale (ring-scale scale (* scale-padding index))]
{:scale ring-scale
:opacity (reanimated/interpolate ring-scale
[1 scale-to-each]
[opacity-from 0])}))
(range 0 5))
rings-color (cond
@ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque
colors/neutral-80)
@ready-to-delete? colors/danger-50
:else colors/primary-50)
translate-y (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 0)
button-color colors/primary-50
icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white)
icon-opacity (reanimated/use-shared-value 1)
red-overlay-opacity (reanimated/use-shared-value 0)
gray-overlay-opacity (reanimated/use-shared-value 0)
complete-animation (fn []
(cond
(and @ready-to-lock? (not @record-button-is-animating?))
(do
(reset! locked? true)
(reset! ready-to-lock? false))
(and (not @locked?) (not @reviewing-audio?))
(audio/stop-recording
@recorder-ref
(fn []
(cond
@ready-to-send?
(when on-send
(on-send (audio/get-recorder-file-path @recorder-ref)))
@ready-to-delete?
(when on-cancel
(on-cancel)))
(reload-recorder-fn)
(reset! recording? false)
(reset! ready-to-send? false)
(reset! ready-to-delete? false)
(reset! ready-to-lock? false)
(reset! idle? true)
(js/setTimeout #(reset! idle? false) 1000)
(js/clearInterval @recording-timer)
(reset! recording-length-ms 0)
(log/debug "[record-audio] stop recording - success"))
#(log/error "[record-audio] stop recording - error: " %))))
start-animation (fn []
(set-value opacity 1)
(animate-linear scale 2.6 signal-anim-duration)
;; TODO: Research if we can implement this with withSequence method
;; from Reanimated 2
;; GitHub issue [#14561]:
;; https://github.com/status-im/status-mobile/issues/14561
(reset! clear-timeout
(js/setTimeout
(fn []
(set-value scale scale-to-each)
(animate-linear-with-delay-loop scale
scale-to-total
signal-anim-duration-2
0))
signal-anim-duration)))
stop-animation (fn []
(set-value opacity 0)
(reanimated/cancel-animation scale)
(set-value scale 1)
(when @clear-timeout (js/clearTimeout @clear-timeout)))
start-y-animation (fn []
(reset! record-button-at-initial-position? false)
(reset! record-button-is-animating? true)
(animate-easing translate-y -64 250)
(animate-linear-with-delay icon-opacity 0 33.33 76.66)
(js/setTimeout (fn []
(reset! record-button-is-animating? false)
(when-not @touch-active? (complete-animation)))
250))
reset-y-animation (fn []
(animate-easing translate-y 0 300)
(animate-linear icon-opacity 1 500)
(js/setTimeout (fn []
(reset! record-button-at-initial-position? true))
500))
start-x-animation (fn []
(reset! record-button-at-initial-position? false)
(reset! record-button-is-animating? true)
(animate-easing translate-x -64 250)
(animate-linear-with-delay icon-opacity 0 33.33 76.66)
(animate-linear red-overlay-opacity 1 33.33)
(js/setTimeout (fn []
(reset! record-button-is-animating? false)
(when-not @touch-active? (complete-animation)))
250))
reset-x-animation (fn []
(animate-easing translate-x 0 300)
(animate-linear icon-opacity 1 500)
(animate-linear red-overlay-opacity 0 100)
(js/setTimeout (fn []
(reset! record-button-at-initial-position? true))
500))
start-x-y-animation (fn []
(reset! record-button-at-initial-position? false)
(reset! record-button-is-animating? true)
(animate-easing translate-y -44 200)
(animate-easing translate-x -44 200)
(animate-linear-with-delay icon-opacity 0 33.33 33.33)
(animate-linear gray-overlay-opacity 1 33.33)
(js/setTimeout (fn []
(reset! record-button-is-animating? false)
(when-not @touch-active? (complete-animation)))
200))
reset-x-y-animation (fn []
(animate-easing translate-y 0 300)
(animate-easing translate-x 0 300)
(animate-linear icon-opacity 1 500)
(animate-linear gray-overlay-opacity 0 800)
(js/setTimeout (fn []
(reset! record-button-at-initial-position? true))
800))]
(use-effect (fn []
(cond
@recording?
(start-animation)
(not @ready-to-lock?)
(stop-animation)))
[@recording?])
(use-effect (fn []
(if @ready-to-lock?
(start-x-y-animation)
(reset-x-y-animation)))
[@ready-to-lock?])
(use-effect (fn []
(if @ready-to-send?
(start-y-animation)
(reset-y-animation)))
[@ready-to-send?])
(use-effect (fn []
(if @ready-to-delete?
(start-x-animation)
(reset-x-animation)))
[@ready-to-delete?])
[reanimated/view
{:style (style/record-button-big-container translate-x translate-y opacity)
:pointer-events :none}
[:<>
(map-indexed
(fn [id animation]
^{:key id}
[animated-ring
{:scale (:scale animation)
:opacity (:opacity animation)
:color rings-color}])
animations)]
[rn/view {:style (style/record-button-big-body button-color)}
[reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-icon-container icon-opacity)}
(if @locked?
[rn/view {:style style/stop-icon}]
[icons/icon :i/audio {:color icon-color}])]]]))])
@@ -0,0 +1,90 @@
(ns quo2.components.record-audio.record-audio.buttons.send-button
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear
animate-linear-with-delay
animate-easing-with-delay
set-value]]))
(defn send-button
[recording? ready-to-send? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 0)
translate-y (reanimated/use-shared-value 20)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 12)
height (reanimated/use-shared-value 24)
border-radius-first-half (reanimated/use-shared-value 16)
border-radius-second-half (reanimated/use-shared-value 8)
start-y-animation (fn []
(animate-linear-with-delay translate-y 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
(animate-easing-with-delay width 56 83.33 80)
(animate-easing-with-delay height 56 83.33 80)
(animate-easing-with-delay border-radius-first-half 28 83.33 80)
(animate-easing-with-delay border-radius-second-half 28 83.33 80))
reset-y-animation (fn []
(animate-linear translate-y 0 100)
(set-value connector-opacity 0)
(set-value width 12)
(set-value height 24)
(set-value border-radius-first-half 16)
(set-value border-radius-second-half 8))
fade-in-animation (fn []
(animate-linear translate-y 0 200)
(animate-linear opacity 1 200))
fade-out-animation (fn []
(animate-linear
translate-y
(if @reviewing-audio? 76 20)
200)
(when-not @reviewing-audio?
(animate-linear opacity 0 200))
(set-value connector-opacity 0)
(set-value width 24)
(set-value height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))
fade-out-reset-animation (fn []
(animate-linear opacity 0 200)
(animate-linear-with-delay translate-y 20 0 200)
(set-value connector-opacity 0)
(set-value width 24)
(set-value height 12)
(set-value border-radius-first-half 8)
(set-value border-radius-second-half 16))]
(use-effect (fn []
(if @recording?
(fade-in-animation)
(fade-out-animation)))
[@recording?])
(use-effect (fn []
(when-not @reviewing-audio?
(fade-out-reset-animation)))
[@reviewing-audio?])
(use-effect (fn []
(cond
@ready-to-send?
(start-y-animation)
@recording? (reset-y-animation)))
[@ready-to-send?])
[:<>
[reanimated/view {:style (style/send-button-container opacity)}
[reanimated/view
{:style (style/send-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
{:style (style/send-button translate-y opacity)
:pointer-events :none}
[icons/icon :i/arrow-up
{:color colors/white
:size 20
:container-style style/send-icon-container}]]]))])
@@ -0,0 +1,50 @@
(ns quo2.components.record-audio.record-audio.helpers
(:require [react-native.reanimated :as reanimated]))
(defn animate-linear
[shared-value value duration]
(reanimated/animate-shared-value-with-timing
shared-value
value
duration
:linear))
(defn animate-linear-with-delay
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
shared-value
value
duration
:linear
delay))
(defn animate-linear-with-delay-loop
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay-repeat
shared-value
value
duration
:linear
delay
-1))
(defn animate-easing
[shared-value value duration]
(reanimated/animate-shared-value-with-timing
shared-value
value
duration
:easing1))
(defn animate-easing-with-delay
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
shared-value
value
duration
:easing1
delay))
(defn set-value
[shared-value value]
(reanimated/set-shared-value shared-value value))
@@ -199,9 +199,10 @@
:z-index 0}))
(defn delete-button
[translate-x opacity]
[scale translate-x opacity]
(reanimated/apply-animations-to-style
{:transform [{:translateX translate-x}]
{:transform [{:translateX translate-x}
{:scale scale}]
:opacity opacity}
{:width 32
:height 32
@@ -221,8 +222,66 @@
{:margin-bottom 32
:margin-right 32}))
(def input-container
(def button-container
{:width 140
:height 140
:align-items :flex-end
:justify-content :flex-end})
:justify-content :flex-end
:position :absolute
:right -10})
(def bar-container
{:flex 1
:height 128})
(defn recording-bar-container
[]
{:height 4
:border-radius 2
:background-color (colors/theme-colors colors/neutral-20 colors/neutral-80)
:overflow :hidden
:position :absolute
:left 80
:right 148
:bottom 34})
(defn recording-bar
[fill-percentage ready-to-delete?]
{:width (str fill-percentage "%")
:height 4
:border-radius 2
:background-color (if ready-to-delete?
(colors/theme-colors colors/danger-50 colors/danger-60)
(colors/theme-colors colors/primary-50 colors/primary-60))})
(defn timer-container
[reviewing-audio?]
{:position :absolute
:left (if reviewing-audio? 67 20)
:bottom 28.5
:flex-direction :row
:align-items :center})
(defn timer-circle
[]
{:width 8
:height 8
:border-radius 4
:margin-right 6
:background-color (colors/theme-colors colors/danger-50 colors/danger-60)})
(defn timer-text
[]
{:color (colors/theme-colors colors/danger-50 colors/danger-60)})
(defn play-button
[]
{:position :absolute
:bottom 20
:left 20
:width 32
:height 32
:border-radius 16
:align-items :center
:justify-content :center
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-90)})
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
(ns quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec
(:require [quo2.components.record-audio.soundtrack.view :as soundtrack]
[test-helpers.component :as h]
[reagent.core :as reagent]
[status-im.audio.core :as audio]))
(h/describe "soundtrack component"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/test "renders soundtrack"
(with-redefs [audio/get-player-duration (fn [] 2000)]
(let [player-ref (reagent/atom {})
audio-current-time-ms (reagent/atom 0)]
(h/render [soundtrack/soundtrack
{:player-ref player-ref
:audio-current-time-ms audio-current-time-ms}])
(-> (h/expect (h/get-by-test-id "soundtrack"))
(.toBeTruthy)))))
(h/test "soundtrack on-sliding-start works"
(with-redefs [audio/get-player-duration (fn [] 2000)]
(let [seeking-audio? (reagent/atom false)
player-ref (reagent/atom {})
audio-current-time-ms (reagent/atom 0)]
(h/render [soundtrack/soundtrack
{:seeking-audio? seeking-audio?
:player-ref player-ref
:audio-current-time-ms audio-current-time-ms}])
(h/fire-event
:on-sliding-start
(h/get-by-test-id "soundtrack"))
(-> (h/expect @seeking-audio?)
(.toBe true)))))
(h/test "soundtrack on-sliding-complete works"
(with-redefs [audio/get-player-duration (fn [] 2000)
audio/seek-player (js/jest.fn)]
(let [seeking-audio? (reagent/atom false)
player-ref (reagent/atom {})
audio-current-time-ms (reagent/atom 0)]
(h/render [soundtrack/soundtrack
{:seeking-audio? seeking-audio?
:player-ref player-ref
:audio-current-time-ms audio-current-time-ms}])
(h/fire-event
:on-sliding-start
(h/get-by-test-id "soundtrack"))
(h/fire-event
:on-sliding-complete
(h/get-by-test-id "soundtrack")
1000)
(-> (h/expect @seeking-audio?)
(.toBe false))
(-> (h/expect audio/seek-player)
(.toHaveBeenCalledTimes 1)))))
(h/test "soundtrack on-value-change when seeking audio works"
(with-redefs [audio/get-player-duration (fn [] 2000)
audio/seek-player (js/jest.fn)]
(let [seeking-audio? (reagent/atom false)
player-ref (reagent/atom {})
audio-current-time-ms (reagent/atom 0)]
(h/render [soundtrack/soundtrack
{:seeking-audio? seeking-audio?
:player-ref player-ref
:audio-current-time-ms audio-current-time-ms}])
(h/fire-event
:on-sliding-start
(h/get-by-test-id "soundtrack"))
(h/fire-event
:on-value-change
(h/get-by-test-id "soundtrack")
1000)
(-> (h/expect @audio-current-time-ms)
(.toBe 1000))))))
@@ -0,0 +1,16 @@
(ns quo2.components.record-audio.soundtrack.style
(:require [react-native.platform :as platform]))
(defn player-slider-container
[]
(merge
{:position :absolute
:left (if platform/ios? 115 104)
:right (if platform/ios? 108 92)
:bottom (if platform/ios? 16 27)}
(when platform/android?
;; Workaround to increase the thickness of the slider track on Android
;; which is currently not supported by the Slider library and remove
;; the thumb shadow that appears when dragging.
{:transform [{:scaleY 2}]
:background-color :transparent})))
@@ -0,0 +1,38 @@
(ns quo2.components.record-audio.soundtrack.view
(:require [quo2.components.record-audio.soundtrack.style :as style]
[quo2.foundations.colors :as colors]
[status-im.audio.core :as audio]
[taoensso.timbre :as log]
[react-native.platform :as platform]
[react-native.slider :as slider]))
(def ^:private thumb-light (js/require "../resources/images/icons2/12x12/thumb-light.png"))
(def ^:private thumb-dark (js/require "../resources/images/icons2/12x12/thumb-dark.png"))
(defn soundtrack
[{:keys [audio-current-time-ms player-ref seeking-audio?]}]
[:f>
(fn []
(let [audio-duration-ms (audio/get-player-duration @player-ref)]
[:<>
[slider/slider
{:test-ID "soundtrack"
:style (style/player-slider-container)
:minimum-value 0
:maximum-value audio-duration-ms
:value @audio-current-time-ms
:on-sliding-start #(reset! seeking-audio? true)
:on-sliding-complete (fn [seek-time]
(reset! seeking-audio? false)
(audio/seek-player
@player-ref
seek-time
#(log/debug "[record-audio] on seek - seek time: " seek-time)
#(log/error "[record-audio] on seek - error: " %)))
:on-value-change #(when @seeking-audio?
(reset! audio-current-time-ms %))
:thumb-image (if (colors/dark?) thumb-dark thumb-light)
:minimum-track-tint-color (colors/theme-colors colors/primary-50 colors/primary-60)
:maximum-track-tint-color (colors/theme-colors
(if platform/ios? colors/neutral-20 colors/neutral-40)
(if platform/ios? colors/neutral-80 colors/neutral-60))}]]))])
+137 -130
View File
@@ -28,28 +28,6 @@
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}}
[notification-dot]])
(defn tabs
[{:keys [default-active on-change style]}]
(let [active-tab-id (reagent/atom default-active)]
(fn [{:keys [data size] :or {size default-tab-size}}]
[rn/view (merge {:flex-direction :row} style)
(doall
(for [{:keys [label id notification-dot? accessibility-label]} data]
^{:key id}
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
(when notification-dot?
[indicator])
[tab/tab
{:id id
:size size
:accessibility-label accessibility-label
:active (= id @active-tab-id)
:on-press (fn []
(reset! active-tab-id id)
(when on-change
(on-change id)))}
label]]))])))
(defn- calculate-fade-end-percentage
[{:keys [offset-x content-width layout-width max-fade-percentage]}]
(let [fade-percentage (max max-fade-percentage
@@ -60,30 +38,35 @@
0.99
(utils.number/naive-round fade-percentage 2))))
(defn scrollable-tabs
"Just like the component `tabs`, displays horizontally scrollable tabs with
extra options to control if/how the end of the scroll view fades.
Tabs are rendered using ReactNative's FlatList, which offers the convenient
`scrollToIndex` method. FlatList accepts VirtualizedList and ScrollView props,
and so does this component.
Usage:
[tabs/scrollable-tabs
{:scroll-on-press? true
:fade-end? true
:on-change #(...)
:default-active :tab-a
:data [{:id :tab-a :label \"Tab A\"}
{:id :tab-b :label \"Tab B\"}]}]]
(defn tabs
"Usage:
{:type :icon/:emoji/:label
:component tag/tab
:size 32/24
:on-press fn
:blurred? true/false
:labelled? true/false
:disabled? true/false
:scrollable? false
:scroll-on-press? true
:fade-end? true
:on-change fn
:default-active tag-id
:data [{:id :label \"\" :resource \"url\"}
{:id :label \"\" :resource \"url\"}]}
Opts:
- `size` number
- `scroll-on-press?` When non-nil, clicking on a tab centers it the middle
- `component` this is to determine which component is to be rendered since the
logic in this view is shared between tab and tag component
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false
- `size` number
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
(with animation enabled).
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
- `fade-end-percentage` Percentage where fading starts relative to the total
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
- `fade-end-percentage` Percentage where fading starts relative to the total
layout width of the `flat-list` data."
[{:keys [default-active fade-end-percentage]
:or {fade-end-percentage 0.8}}]
(let [active-tab-id (reagent/atom default-active)
@@ -97,99 +80,123 @@
on-scroll
scroll-event-throttle
scroll-on-press?
scrollable?
style
size
blur?
override-theme]
:or {fade-end-percentage fade-end-percentage
fade-end? false
scroll-event-throttle 64
scrollable? false
scroll-on-press? false
size default-tab-size}
:as props}]
(let [maybe-mask-wrapper (if fade-end?
[masked-view/masked-view
{:mask-element
(reagent/as-element
[linear-gradient/linear-gradient
{:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage) 1]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:pointer-events :none
:style {:width "100%"
:height "100%"}}])}]
[:<>])]
(conj
maybe-mask-wrapper
[rn/flat-list
(merge
(dissoc props
:default-active
:fade-end-percentage
:fade-end?
:on-change
:scroll-on-press?
:size)
(when scroll-on-press?
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
{:ref #(reset! flat-list-ref %)
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle scroll-event-throttle
:shows-horizontal-scroll-indicator false
:data data
:key-fn (comp str :id)
:on-scroll-to-index-failed identity
:on-scroll (fn [^js e]
(when fade-end?
(let [offset-x (oget
e
"nativeEvent.contentOffset.x")
content-width (oget
e
"nativeEvent.contentSize.width")
layout-width
(oget e "nativeEvent.layoutMeasurement.width")
new-percentage
(calculate-fade-end-percentage
{:offset-x offset-x
:content-width content-width
:layout-width layout-width
:max-fade-percentage fade-end-percentage})]
;; Avoid unnecessary re-rendering.
(when (not= new-percentage
(get @fading :fade-end-percentage))
(swap! fading assoc
:fade-end-percentage
new-percentage))))
(when on-scroll
(on-scroll e)))
:render-fn (fn [{:keys [id label]} index]
[rn/view
{:style {:margin-right (if (= size default-tab-size)
12
8)
:padding-right (when (= index
(dec (count data)))
(get-in props
[:style
:padding-left]))}}
[tab/tab
{:id id
:size size
:override-theme override-theme
:blur? blur?
:active (= id @active-tab-id)
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex ^js
@flat-list-ref
#js
{:animated true
:index index
:viewPosition
0.5}))
(when on-change
(on-change id)))}
label]])})])))))
(if scrollable?
(let [maybe-mask-wrapper (if fade-end?
[masked-view/masked-view
{:mask-element
(reagent/as-element
[linear-gradient/linear-gradient
{:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage) 1]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:pointer-events :none
:style {:width "100%"
:height "100%"}}])}]
[:<>])]
(conj
maybe-mask-wrapper
[rn/flat-list
(merge
(dissoc props
:default-active
:fade-end-percentage
:fade-end?
:on-change
:scroll-on-press?
:size)
(when scroll-on-press?
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
{:ref #(reset! flat-list-ref %)
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle scroll-event-throttle
:shows-horizontal-scroll-indicator false
:data data
:key-fn (comp str :id)
:on-scroll-to-index-failed identity
:on-scroll (fn [^js e]
(when fade-end?
(let [offset-x (oget
e
"nativeEvent.contentOffset.x")
content-width
(oget
e
"nativeEvent.contentSize.width")
layout-width
(oget e
"nativeEvent.layoutMeasurement.width")
new-percentage
(calculate-fade-end-percentage
{:offset-x offset-x
:content-width content-width
:layout-width layout-width
:max-fade-percentage fade-end-percentage})]
;; Avoid unnecessary re-rendering.
(when (not= new-percentage
(get @fading :fade-end-percentage))
(swap! fading assoc
:fade-end-percentage
new-percentage))))
(when on-scroll
(on-scroll e)))
:render-fn (fn [{:keys [id label]} index]
[rn/view
{:style {:margin-right (if (= size default-tab-size)
12
8)
:padding-right (when (= index
(dec (count data)))
(get-in props
[:style
:padding-left]))}}
[tab/tab
{:id id
:size size
:override-theme override-theme
:blur? blur?
:active (= id @active-tab-id)
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex
^js
@flat-list-ref
#js
{:animated true
:index index
:viewPosition
0.5}))
(when on-change
(on-change id)))}
label]])})]))
[rn/view (merge {:flex-direction :row} style)
(doall
(for [{:keys [label id notification-dot? accessibility-label]} data]
^{:key id}
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
(when notification-dot?
[indicator])
[tab/tab
{:id id
:size size
:accessibility-label accessibility-label
:active (= id @active-tab-id)
:on-press (fn []
(reset! active-tab-id id)
(when on-change
(on-change id)))}
label]]))]))))
+5 -9
View File
@@ -16,25 +16,21 @@
{:width size})))
(defn base-tag
"opts
{:type :icon/:emoji/:label/:permission
:size 32/24}
:labelled true"
[_]
(fn [{:keys [id size disabled border-color border-width background-color on-press
accessibility-label label type]
(fn [{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label labelled? type]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled
disabled?
border-color
border-width
background-color
label
labelled?
type))}
children]]))
+1 -1
View File
@@ -64,7 +64,7 @@
[rn/image
{:style {:width 20
:border-radius 10
:background-color :red
:background-color :white
:height 20}
:source photo}]
[rn/view
+32 -18
View File
@@ -68,26 +68,40 @@
label])])
(defn tag
"opts
{:type :icon/:emoji/:label
:size 32/24
:on-press fn
:blurred? true/false
:resource icon/image
:labelled? true/false
:disabled? true/false}
opts
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[_ _]
(fn [{:keys [id on-press disabled size resource active accessibility-label
label type labelled blurred icon-color]
(fn [{:keys [id on-press disabled? size resource active accessibility-label
label type labelled? blurred? icon-color]
:or {size 32}}]
(let [state (cond disabled :disabled
active :active
:else :default)
(let [state (cond disabled? :disabled
active :active
:else :default)
{:keys [border-color blurred-border-color text-color]}
(get-in themes [(theme/get-theme) state])]
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled disabled
:type type
:label label}
[tag-resources size type resource icon-color label text-color labelled]])))
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]])))
+169 -25
View File
@@ -1,29 +1,173 @@
(ns quo2.components.tags.tags
(:require [quo2.components.tags.tag :as tag]
(:require [reagent.core :as reagent]
[oops.core :refer [oget]]
[quo2.components.tags.tag :as tag]
[utils.number :as number-utils]
[react-native.core :as rn]
[reagent.core :as reagent]))
[react-native.masked-view :as masked-view]
[react-native.linear-gradient :as linear-gradient]
[utils.collection :as utils.collection]))
(def default-tab-size 32)
(defn calculate-fade-end-percentage
[{:keys [offset-x content-width layout-width max-fade-percentage]}]
(let [fade-percentage (max max-fade-percentage
(/ (+ layout-width offset-x)
content-width))]
;; Truncate to avoid unnecessary rendering.
(if (> fade-percentage 0.99)
0.99
(number-utils/naive-round fade-percentage 2))))
(defn tags
[{:keys [default-active on-change]}]
(let [active-tab-id (reagent/atom default-active)]
(fn [{:keys [data size type labelled disabled blurred icon-color] :or {size 32}}]
(let [active-id @active-tab-id]
[rn/view {:flex-direction :row}
(for [{:keys [tag-label id resource]} data]
^{:key id}
[rn/view {:margin-right 8}
[tag/tag
(merge {:id id
:size size
:type type
:label (if labelled tag-label (when (= type :label) tag-label))
:active (= id active-id)
:disabled disabled
:blurred blurred
:icon-color icon-color
:labelled (if (= type :label) true labelled)
:resource (if (= type :icon)
:i/placeholder
resource)
:on-press #(do (reset! active-tab-id %)
(when on-change (on-change %)))})]])]))))
"Usage:
{:type :icon/:emoji/:label
:component tag/tab
:size 32/24
:on-press fn
:blurred? true/false
:labelled? true/false
:disabled? true/false
:scroll-on-press? true
:scrollable? false
:fade-end? true
:on-change fn
:default-active tag-id
:data [{:id :label \"\" :resource \"url\"}
{:id :label \"\" :resource \"url\"}]}
Opts:
- `component` this is to determine which component is to be rendered since the
logic in this view is shared between tab and tag component
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false
- `size` number
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
(with animation enabled).
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
- `fade-end-percentage` Percentage where fading starts relative to the total
layout width of the `flat-list` data."
[{:keys [default-active fade-end-percentage]
:or {fade-end-percentage 0.8}}]
(let [active-tab-id (reagent/atom default-active)
fading (reagent/atom {:fade-end-percentage fade-end-percentage})
flat-list-ref (atom nil)]
(fn
[{:keys [data
fade-end-percentage
fade-end?
on-change
on-scroll
scroll-event-throttle
scrollable?
scroll-on-press?
size
type
labelled?
disabled?
blurred?
icon-color]
:or {fade-end-percentage fade-end-percentage
fade-end? false
scroll-event-throttle 64
scrollable? false
scroll-on-press? false
size default-tab-size}
:as props}]
(let [maybe-mask-wrapper (if fade-end?
[masked-view/masked-view
{:mask-element (reagent/as-element
[linear-gradient/linear-gradient
{:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage)
1]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:pointer-events :none
:style {:width "100%"
:height "100%"}}])}]
[:<>])]
(if scrollable?
(conj
maybe-mask-wrapper
[rn/flat-list
(merge
(dissoc props
:default-active
:fade-end-percentage
:fade-end?
:on-change
:scroll-on-press?
:size)
(when scroll-on-press?
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
{:ref #(reset! flat-list-ref %)
:extra-data (str @active-tab-id)
:horizontal true
:scroll-event-throttle scroll-event-throttle
:shows-horizontal-scroll-indicator false
:data data
:key-fn (comp str :id)
:on-scroll (fn [^js e]
(when fade-end?
(let [offset-x (oget e "nativeEvent.contentOffset.x")
content-width (oget e "nativeEvent.contentSize.width")
layout-width (oget e "nativeEvent.layoutMeasurement.width")
new-percentage (calculate-fade-end-percentage
{:offset-x offset-x
:content-width content-width
:layout-width layout-width
:max-fade-percentage fade-end-percentage})]
;; Avoid unnecessary re-rendering.
(when (not= new-percentage (get @fading :fade-end-percentage))
(swap! fading assoc :fade-end-percentage new-percentage))))
(when on-scroll
(on-scroll e)))
:render-fn (fn [{:keys [id label resource]} index]
[rn/view
{:style {:margin-right (if (= size default-tab-size) 12 8)
:padding-right (when (= index (dec (count data)))
(get-in props [:style :padding-left]))}}
[tag/tag
{:id id
:size size
:active (= id @active-tab-id)
:resource resource
:blurred? blurred?
:icon-color icon-color
:disabled? disabled?
:label label
:type type
:labelled? labelled?
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex ^js @flat-list-ref
#js
{:animated true
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
label]])})])
[rn/view {:style {:flex-direction :row}}
(for [{:keys [label id resource]} data]
^{:key id}
[rn/view {:style {:margin-right 8}}
[tag/tag
(merge {:id id
:size size
:type type
:label (if labelled? label (when (= type :label) label))
:active (= id active-tab-id)
:disabled? disabled?
:blurred? blurred?
:icon-color icon-color
:labelled? (if (= type :label) true labelled?)
:resource (if (= type :icon)
:i/placeholder
resource)
:on-press #(do (reset! active-tab-id %)
(when on-change (on-change %)))})]])])))))
+18 -7
View File
@@ -20,7 +20,8 @@
quo2.components.dividers.date
quo2.components.dividers.divider-label
quo2.components.dividers.new-messages
quo2.components.drawers.action-drawers
quo2.components.drawers.action-drawers.view
quo2.components.drawers.permission-context.view
quo2.components.dropdowns.dropdown
quo2.components.header
quo2.components.icon
@@ -41,6 +42,7 @@
quo2.components.notifications.info-count
quo2.components.notifications.notification-dot
quo2.components.notifications.toast
quo2.components.profile.profile-card.view
quo2.components.reactions.reaction
quo2.components.selectors.disclaimer.view
quo2.components.selectors.filter.view
@@ -52,8 +54,10 @@
quo2.components.tabs.tabs
quo2.components.tags.context-tags
quo2.components.tags.status-tags
quo2.components.profile.profile-card.view
quo2.components.tags.tags))
quo2.components.tags.permission-tag
quo2.components.tags.tag
quo2.components.tags.tags
quo2.components.tags.token-tag))
(def toast quo2.components.notifications.toast/toast)
(def button quo2.components.buttons.button/button)
@@ -63,7 +67,6 @@
(def separator quo2.components.separator/separator)
(def counter quo2.components.counter.counter/counter)
(def header quo2.components.header/header)
(def action-drawer quo2.components.drawers.action-drawers/action-drawer)
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
(def info-message quo2.components.info.info-message/info-message)
(def information-box quo2.components.info.information-box/information-box)
@@ -71,17 +74,14 @@
(def system-message quo2.components.messages.system-message/system-message)
(def reaction quo2.components.reactions.reaction/reaction)
(def add-reaction quo2.components.reactions.reaction/add-reaction)
(def tags quo2.components.tags.tags/tags)
(def user-avatar-tag quo2.components.tags.context-tags/user-avatar-tag)
(def context-tag quo2.components.tags.context-tags/context-tag)
(def group-avatar-tag quo2.components.tags.context-tags/group-avatar-tag)
(def audio-tag quo2.components.tags.context-tags/audio-tag)
(def community-tag quo2.components.tags.context-tags/community-tag)
(def tabs quo2.components.tabs.tabs/tabs)
(def scrollable-tabs quo2.components.tabs.tabs/scrollable-tabs)
(def account-selector quo2.components.tabs.account-selector/account-selector)
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
(def status-tag quo2.components.tags.status-tags/status-tag)
(def page-nav quo2.components.navigation.page-nav/page-nav)
(def disclaimer quo2.components.selectors.disclaimer.view/view)
(def checkbox quo2.components.selectors.selectors/checkbox)
@@ -119,6 +119,10 @@
(def new-messages quo2.components.dividers.new-messages/new-messages)
(def divider-date quo2.components.dividers.date/date)
;;;; DRAWERS
(def action-drawer quo2.components.drawers.action-drawers.view/action-drawer)
(def permission-context quo2.components.drawers.permission-context.view/view)
;;;; LIST ITEMS
(def channel-list-item quo2.components.list-items.channel/list-item)
(def menu-item quo2.components.list-items.menu-item/menu-item)
@@ -136,3 +140,10 @@
;;;; SETTINGS
(def privacy-option quo2.components.settings.privacy-option/card)
(def account quo2.components.settings.accounts.view/account)
;;;; TAGS
(def tag quo2.components.tags.tag/tag)
(def tags quo2.components.tags.tags/tags)
(def permission-tag quo2.components.tags.permission-tag/tag)
(def status-tag quo2.components.tags.status-tags/status-tag)
(def token-tag quo2.components.tags.token-tag/tag)
+6 -3
View File
@@ -1,9 +1,12 @@
(ns quo2.core-spec
(:require [quo2.components.banners.--tests--.banner-component-spec]
(:require [quo2.components.banners.banner.component-spec]
[quo2.components.buttons.--tests--.buttons-component-spec]
[quo2.components.counter.--tests--.counter-component-spec]
[quo2.components.dividers.--tests--.divider-label-component-spec]
[quo2.components.drawers.--tests--.action-drawers-component-spec]
[quo2.components.drawers.action-drawers.component-spec]
[quo2.components.drawers.permission-context.component-spec]
[quo2.components.markdown.--tests--.text-component-spec]
[quo2.components.selectors.--tests--.selectors-component-spec]
[quo2.components.selectors.filter.component-spec]))
[quo2.components.selectors.filter.component-spec]
[quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec]
[quo2.components.record-audio.soundtrack.--tests--.soundtrack-component-spec]))
+71
View File
@@ -0,0 +1,71 @@
(ns quo2.foundations.shadows
(:require [quo2.foundations.colors :as colors]
[quo2.theme :as theme]))
(defn- get-inverted
[inverted? number]
(if inverted? (* -1 number) number))
(defn- get-scales
[inverted?]
(if (theme/dark?)
{:shadow-1 {:shadow-color (colors/alpha colors/neutral-100 0.5)
:shadow-offset {:width 0
:height (get-inverted inverted? 4)}
:elevation 3
:shadow-opacity 1
:shadow-radius 20}
:shadow-2 {:shadow-color (colors/alpha colors/neutral-100 0.64)
:shadow-offset {:width 0
:height (get-inverted inverted? 4)}
:elevation 4
:shadow-opacity 1
:shadow-radius 20}
:shadow-3 {:shadow-color (colors/alpha colors/neutral-100 0.64)
:shadow-offset {:width 0
:height (get-inverted inverted? 12)}
:elevation 8
:shadow-opacity 1
:shadow-radius 20}
:shadow-4 {:shadow-color (colors/alpha colors/neutral-100 0.72)
:shadow-offset {:width 0
:height (get-inverted inverted? 16)}
:shadow-opacity 1
:shadow-radius 20
:elevation 15}}
{:shadow-1 {:shadow-color (colors/alpha colors/neutral-100 0.04)
:shadow-offset {:width 0
:height (get-inverted inverted? 4)}
:elevation 1
:shadow-opacity 1
:shadow-radius 16}
:shadow-2 {:shadow-color (colors/alpha colors/neutral-100 0.08)
:shadow-offset {:width 0
:height (get-inverted inverted? 4)}
:elevation 2
:shadow-opacity 1
:shadow-radius 16}
:shadow-3 {:shadow-color (colors/alpha colors/neutral-100 0.12)
:shadow-offset {:width 0
:height (get-inverted inverted? 12)}
:elevation 5
:shadow-opacity 1
:shadow-radius 16}
:shadow-4 {:shadow-color (colors/alpha colors/neutral-100 0.16)
:shadow-offset {:width 0
:height (get-inverted inverted? 16)}
:shadow-opacity 1
:shadow-radius 16
:elevation 13}}))
(def normal-scale (get-scales false))
(def inverted-scale (get-scales true))
(def inner-shadow
{:shadow-color (colors/alpha colors/neutral-100 0.08)
:shadow-offset {:width 0
:height 0}
:shadow-opacity 1
:shadow-radius 16
:elevation 13})
+5
View File
@@ -0,0 +1,5 @@
(ns react-native.blur
(:require ["@react-native-community/blur" :as blur]
[reagent.core :as reagent]))
(def view (reagent/adapt-react-class (.-BlurView blur)))
+10
View File
@@ -0,0 +1,10 @@
(ns react-native.clipboard
(:require ["@react-native-community/clipboard" :default Clipboard]))
(defn set-string
[text]
(.setString ^js Clipboard text))
(defn get-string
[callback]
(.then (.getString ^js Clipboard) #(callback %)))
+36 -9
View File
@@ -1,6 +1,5 @@
(ns react-native.core
(:require ["@react-native-community/blur" :as blur]
["react" :as react]
(:require ["react" :as react]
["react-native" :as react-native]
[cljs-bean.core :as bean]
[oops.core :as oops]
@@ -10,7 +9,6 @@
[reagent.core :as reagent]))
(def app-state ^js (.-AppState ^js react-native))
(def blur-view (reagent/adapt-react-class (.-BlurView blur)))
(def view (reagent/adapt-react-class (.-View ^js react-native)))
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
@@ -90,15 +88,44 @@
props)]
children))
(defn use-effect
([effect] (use-effect effect []))
([effect deps]
(react/useEffect effect (bean/->js deps))))
(def create-ref react/createRef)
(def use-ref react/useRef)
(defn use-effect-once [effect] (use-effect effect))
(defn use-effect
([effect-fn]
(use-effect effect-fn []))
([effect-fn deps]
(react/useEffect
#(let [ret (effect-fn)]
(if (fn? ret) ret js/undefined))
(bean/->js deps))))
(defn use-effect-once
[effect-fn]
(use-effect effect-fn))
(defn use-unmount
[f]
(let [fn-ref (use-ref f)]
(oops/oset! fn-ref "current" f)
(use-effect-once (fn [] #((oops/oget fn-ref "current"))))))
(use-effect-once (fn [] (fn [] (oops/ocall! fn-ref "current"))))))
(def layout-animation (.-LayoutAnimation ^js react-native))
(def configure-next (.-configureNext ^js layout-animation))
(def layout-animation-presets
{:ease-in-ease-out (-> ^js layout-animation .-Presets .-easeInEaseOut)
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def find-node-handle (.-findNodeHandle ^js react-native))
(defn selectable-text-input-manager
[]
(when (exists? (.-NativeModules ^js react-native))
(.-RNSelectableTextInputManager ^js (.-NativeModules ^js react-native))))
(defonce selectable-text-input
(reagent/adapt-react-class
(.requireNativeComponent ^js react-native "RNSelectableTextInput")))
+40
View File
@@ -0,0 +1,40 @@
(ns react-native.permissions
(:require ["react-native-permissions" :refer (check requestMultiple PERMISSIONS RESULTS)]
[react-native.platform :as platform]))
(def permissions-map
{:read-external-storage (cond
platform/android? (.-READ_EXTERNAL_STORAGE (.-ANDROID PERMISSIONS)))
:write-external-storage (cond
platform/low-device? (.-WRITE_EXTERNAL_STORAGE (.-ANDROID PERMISSIONS)))
:camera (cond
platform/android? (.-CAMERA (.-ANDROID PERMISSIONS))
platform/ios? (.-CAMERA (.-IOS PERMISSIONS)))
:record-audio (cond
platform/android? (.-RECORD_AUDIO (.-ANDROID PERMISSIONS))
platform/ios? (.-MICROPHONE (.-IOS PERMISSIONS)))})
(defn all-granted?
[permissions]
(let [permission-vals (distinct (vals permissions))]
(and (= (count permission-vals) 1)
(not (#{(.-BLOCKED RESULTS) (.-DENIED RESULTS)} (first permission-vals))))))
(defn request-permissions
[{:keys [permissions on-allowed on-denied]
:or {on-allowed #()
on-denied #()}}]
(let [permissions (remove nil? (mapv #(get permissions-map %) permissions))]
(if (empty? permissions)
(on-allowed)
(-> (requestMultiple (clj->js permissions))
(.then #(if (all-granted? (js->clj %))
(on-allowed)
(on-denied)))
(.catch on-denied)))))
(defn permission-granted?
[permission on-result on-error]
(-> (check (get permissions-map permission))
(.then #(on-result (not (#{(.-BLOCKED RESULTS) (.-DENIED RESULTS)} %))))
(.catch #(on-error %))))
+18 -28
View File
@@ -1,6 +1,7 @@
(ns react-native.reanimated
(:require ["react-native" :as rn]
["react-native-linear-gradient" :default LinearGradient]
["@react-native-community/blur" :as blur]
["react-native-reanimated" :default reanimated :refer
(useSharedValue useAnimatedStyle
withTiming
@@ -13,8 +14,8 @@
SlideInUp
SlideOutUp
LinearTransition)]
[clojure.string :as string]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[utils.collection]))
;; Animations
(def slide-in-up-animation SlideInUp)
@@ -29,6 +30,7 @@
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
(def linear-gradient (create-animated-component LinearGradient))
(def blur-view (create-animated-component (.-BlurView blur)))
;; Hooks
(def use-shared-value useSharedValue)
@@ -54,44 +56,32 @@
;; Helper functions
(defn get-shared-value
[anim]
(.-value anim))
(when anim
(.-value anim)))
(defn set-shared-value
[anim val]
(set! (.-value anim) val))
(defn kebab-case->camelCase
[k]
(let [words (string/split (name k) #"-")]
(->> (map string/capitalize (rest words))
(apply str (first words))
keyword)))
(defn map-keys
[f m]
(->> (map (fn [[k v]] [(f k) v]) m)
(into {})))
(when (and anim (some? val))
(set! (.-value anim) val)))
;; Worklets
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
(defn interpolate
[shared-value input-range output-range]
(.interpolateValue ^js worklet-factory
shared-value
(clj->js input-range)
(clj->js output-range)))
([shared-value input-range output-range]
(interpolate shared-value input-range output-range nil))
([shared-value input-range output-range extrapolation]
(.interpolateValue ^js worklet-factory
shared-value
(clj->js input-range)
(clj->js output-range)
(clj->js extrapolation))))
;;;; Component Animations
;; kebab-case styles are not working for worklets
;; so first convert kebab case styles into camel case styles
(defn apply-animations-to-style
[animations style]
(let [animations (map-keys kebab-case->camelCase animations)
style (apply dissoc (map-keys kebab-case->camelCase style) (keys animations))]
(use-animated-style
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style)))))
(use-animated-style
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style))))
;; Animators
(defn animate-shared-value-with-timing
+2 -3
View File
@@ -5,12 +5,11 @@
(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext)))
(def provider (reagent/adapt-react-class SafeAreaProvider))
(defn consumer
[component]
[consumer-raw
(fn [^js insets]
(reagent/as-element
[component (js->clj insets :keywordize-keys true)]))])
(def safe-area-provider (reagent/adapt-react-class SafeAreaProvider))
(def safe-area-consumer consumer-raw)
+5
View File
@@ -0,0 +1,5 @@
(ns react-native.slider
(:require ["@react-native-community/slider" :default Slider]
[reagent.core :as reagent]))
(def slider (reagent/adapt-react-class Slider))
View File
+3 -3
View File
@@ -2,12 +2,12 @@
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.add-new.db :as db]
[status-im.chat.models :as chat]
[status-im2.contexts.chat.events :as chat]
[status-im.contact.core :as contact]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.ens :as ens]
[status-im.ethereum.stateofus :as stateofus]
[i18n.i18n :as i18n]
[utils.i18n :as i18n]
[status-im.router.core :as router]
[status-im.utils.db :as utils.db]
[utils.re-frame :as rf]
@@ -91,7 +91,7 @@
(i18n/label :t/use-valid-contact-code)
:yourself
(i18n/label :t/can-not-add-yourself))
:on-dismiss #(re-frame/dispatch [:pop-to-root-tab :chat-stack])}})))
:on-dismiss #(re-frame/dispatch [:pop-to-root-tab :shell-stack])}})))
(rf/defn qr-code-scanned
{:events [:contact/qr-code-scanned]}
+3 -3
View File
@@ -1,7 +1,7 @@
(ns status-im.add-new.db
(:require [cljs.spec.alpha :as spec]
[status-im.ethereum.ens :as ens]
[status-im.utils.db :as utils.db]))
[status-im2.utils.validators :as validators]))
(defn own-public-key?
[{:keys [multiaccount]} public-key]
@@ -10,7 +10,7 @@
(defn validate-pub-key
[db public-key]
(cond
(or (not (utils.db/valid-public-key? public-key))
(or (not (validators/valid-public-key? public-key))
(= public-key ens/default-key))
:invalid
(own-public-key? db public-key)
@@ -27,4 +27,4 @@
[topic]
(and topic
(spec/valid? ::topic topic)
(not (utils.db/valid-public-key? topic))))
(not (validators/valid-public-key? topic))))
+31 -24
View File
@@ -46,15 +46,16 @@
[player on-prepared on-error]
(when (and player (.-canPrepare ^js player))
(.prepare ^js player
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-prepared)))))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-prepared))))))
(defn prepare-recorder
[recorder on-prepared on-error]
(when (and recorder (.-canPrepare ^js recorder))
(.prepare ^js recorder
(fn [err _]
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-prepared))))))
@@ -66,42 +67,47 @@
(.-canRecord ^js recorder)
(.-canPrepare ^js recorder)))
(.record ^js recorder
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-start)))))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-start))))))
(defn stop-recording
[recorder on-stop on-error]
(if (and recorder (#{RECORDING PAUSED} (get-state recorder)))
(.stop ^js recorder
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-stop)))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-stop))))
(on-stop)))
(defn pause-recording
[recorder on-pause on-error]
(when (and recorder (.-isRecording ^js recorder))
(.pause ^js recorder
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-pause)))))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-pause))))))
(defn start-playing
[player on-start on-error]
(when (and player (.-canPlay ^js player))
(.play ^js player
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-start)))))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-start))))))
(defn stop-playing
[player on-stop on-error]
(if (and player (.-isPlaying ^js player))
(.stop ^js player
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-stop)))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-stop))))
(on-stop)))
(defn get-recorder-file-path
@@ -123,7 +129,7 @@
[player on-play on-pause on-error]
(when (and player (.-canPlay ^js player))
(.playPause ^js player
(fn [error pause?]
(fn [^js error pause?]
(if error
(on-error {:error (.-err error) :message (.-message error)})
(if pause?
@@ -135,9 +141,10 @@
(when (and player (.-canPlay ^js player))
(.seek ^js player
value
#(if %
(on-error {:error (.-err %) :message (.-message %)})
(on-seek)))))
(fn [^js err]
(if err
(on-error {:error (.-err err) :message (.-message err)})
(on-seek))))))
(defn can-play?
[player]
@@ -155,4 +162,4 @@
(stop-playing player
#(when (and player (not= (get-state player) IDLE))
(.destroy ^js player))
#()))
#()))
+1 -1
View File
@@ -1,7 +1,7 @@
(ns status-im.bootnodes.core
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[i18n.i18n :as i18n]
[utils.i18n :as i18n]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[utils.re-frame :as rf]
[status-im2.navigation.events :as navigation]))
+2 -2
View File
@@ -8,10 +8,10 @@
[status-im.browser.eip3326 :as eip3326]
[status-im.browser.permissions :as browser.permissions]
[status-im.browser.webview-ref :as webview-ref]
[status-im.constants :as constants]
[status-im2.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.ens :as ens]
[i18n.i18n :as i18n]
[utils.i18n :as i18n]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.native-module.core :as status]
[status-im.signing.core :as signing]
+1 -1
View File
@@ -3,7 +3,7 @@
(ns status-im.browser.eip3085
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im2.constants :as constants]
[status-im.network.core :as network]
[status-im.ui.screens.browser.eip3085.sheet :as sheet]
[utils.re-frame :as rf]
+1 -1
View File
@@ -1,7 +1,7 @@
;reference https://eips.ethereum.org/EIPS/eip-3326 EIP-3326: Wallet Switch Ethereum Chain RPC Method
;(`wallet_switchEthereumChain`)
(ns status-im.browser.eip3326
(:require [status-im.constants :as constants]
(:require [status-im2.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.ui.screens.browser.eip3326.sheet :as sheet]
[utils.re-frame :as rf]))
+2 -2
View File
@@ -1,6 +1,6 @@
(ns status-im.browser.permissions
(:require [status-im.constants :as constants]
[i18n.i18n :as i18n]
(:require [status-im2.constants :as constants]
[utils.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner]
[utils.re-frame :as rf]
[status-im2.navigation.events :as navigation]))
-16
View File
@@ -1,16 +0,0 @@
(ns status-im.chat.constants)
(def command-char "/")
(def spacing-char " ")
(def arg-wrapping-char "\"")
(def spam-message-frequency-threshold 4)
(def spam-interval-ms 1000)
(def default-cooldown-period-ms 10000)
(def cooldown-reset-threshold 3)
(def cooldown-periods-ms
{1 2000
2 5000
3 10000})
(def max-text-size 4096)
-99
View File
@@ -1,99 +0,0 @@
(ns status-im.chat.db
(:require [status-im.constants :as constants]))
(defn group-chat-name
[{:keys [public? name]}]
(str (when public? "#") name))
(defn datemark?
[{:keys [type]}]
(= type :datemark))
(defn intersperse-datemark
"Reduce step which expects the input list of messages to be sorted by clock value.
It makes best effort to group them by day.
We cannot sort them by :timestamp, as that represents the clock of the sender
and we have no guarantees on the order.
We naively and arbitrarly group them assuming that out-of-order timestamps
fall in the previous bucket.
A sends M1 to B with timestamp 2000-01-01T00:00:00
B replies M2 with timestamp 1999-12-31-23:59:59
M1 needs to be displayed before M2
so we bucket both in 1999-12-31"
[{:keys [acc last-timestamp last-datemark]} {:keys [whisper-timestamp datemark] :as msg}]
(cond
(empty? acc) ; initial element
{:last-timestamp whisper-timestamp
:last-datemark datemark
:acc (conj acc msg)}
(and (not= last-datemark datemark) ; not the same day
(< whisper-timestamp last-timestamp)) ; not out-of-order
{:last-timestamp whisper-timestamp
:last-datemark datemark
:acc (conj acc
{:value last-datemark ; intersperse datemark message
:type :datemark}
msg)}
:else
{:last-timestamp (min whisper-timestamp last-timestamp) ; use last datemark
:last-datemark last-datemark
:acc (conj acc (assoc msg :datemark last-datemark))}))
(defn add-datemarks
"Add a datemark in between an ordered seq of messages when two datemarks are not
the same. Ignore messages with out-of-order timestamps"
[messages]
(when (seq messages)
(let [messages-with-datemarks (:acc (reduce intersperse-datemark {:acc []} messages))]
; Append last datemark
(conj messages-with-datemarks
{:value (:datemark (peek messages-with-datemarks))
:type :datemark}))))
(defn last-gap
"last-gap is a special gap that is put last in the message stream"
[chat-id synced-from]
{:message-id "0x123"
:message-type constants/message-type-gap
:chat-id chat-id
:content-type constants/content-type-gap
:gap-ids #{:first-gap}
:gap-parameters {:from synced-from}})
(defn collapse-gaps
"collapse-gaps will take an array of messages and collapse any gap next to
each other in a single gap.
It will also append one last gap if the last message is a non-gap"
[messages chat-id synced-from now chat-type joined loading-messages?]
(let [messages-with-gaps (reduce
(fn [acc {:keys [gap-parameters message-id] :as message}]
(let [last-element (peek acc)]
(cond
;; If it's a message, just add
(empty? gap-parameters)
(conj acc message)
;; Both are gaps, merge them
(and
(seq (:gap-parameters last-element))
(seq gap-parameters))
(conj (pop acc) (update last-element :gap-ids conj message-id))
;; it's a gap
:else
(conj acc (assoc message :gap-ids #{message-id})))))
[]
messages)]
(if (or loading-messages? ; it's loading messages from the database
(nil? synced-from) ; it's still syncing
(= constants/timeline-chat-type chat-type) ; it's a timeline chat
(= constants/profile-chat-type chat-type) ; it's a profile chat
(and (not (nil? synced-from)) ; it's not more than a month
(<= synced-from (- (quot now 1000) constants/one-month)))
(and (= constants/private-group-chat-type chat-type) ; it's a private group chat
(or (not (pos? joined)) ; we haven't joined
(>= (quot joined 1000) synced-from))) ; the history goes before we joined
(:gap-ids (peek messages-with-gaps))) ; there's already a gap on top of the chat history
messages-with-gaps ; don't add an extra gap
(conj messages-with-gaps (last-gap chat-id synced-from)))))
-44
View File
@@ -1,44 +0,0 @@
(ns status-im.chat.db-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.chat.db :as db]))
(deftest group-chat-name
(testing "it prepends # if it's a public chat"
(is (= "#withhash"
(db/group-chat-name {:group-chat true
:chat-id "1"
:public? true
:name "withhash"}))))
(testing "it leaves the name unchanged if it's a group chat"
(is (= "unchanged"
(db/group-chat-name {:group-chat true
:chat-id "1"
:name "unchanged"})))))
(deftest intersperse-datemarks
(testing "it mantains the order even when timestamps are across days"
(let [message-1 {:datemark "Dec 31, 1999"
:whisper-timestamp 946641600000} ; 1999}
message-2 {:datemark "Jan 1, 2000"
:whisper-timestamp 946728000000} ; 2000 this will displayed in 1999
message-3 {:datemark "Dec 31, 1999"
:whisper-timestamp 946641600000} ; 1999
message-4 {:datemark "Jan 1, 2000"
:whisper-timestamp 946728000000} ; 2000
ordered-messages [message-4
message-3
message-2
message-1]
[m1 d1 m2 m3 m4 d2] (db/add-datemarks ordered-messages)]
(is (= "Jan 1, 2000"
(:datemark m1)))
(is (= {:type :datemark
:value "Jan 1, 2000"}
d1))
(is (= "Dec 31, 1999"
(:datemark m2)
(:datemark m3)
(:datemark m4)))
(is (= {:type :datemark
:value "Dec 31, 1999"}
d2)))))
-4
View File
@@ -1,4 +0,0 @@
(ns status-im.chat.default-chats (:require-macros [status-im.utils.slurp :refer [slurp]]))
(def default-chats
(slurp "resources/chats.json"))
+9 -505
View File
@@ -1,342 +1,12 @@
(ns status-im.chat.models
(:require [clojure.set :as set]
[quo.design-system.colors :as colors]
(:require [utils.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.add-new.db :as new-public-chat.db]
[status-im.chat.models.loading :as loading]
[status-im.chat.models.message-list :as message-list]
[status-im.constants :as constants]
[status-im.data-store.chats :as chats-store]
[status-im.data-store.contacts :as contacts-store]
[i18n.i18n :as i18n]
[status-im.mailserver.core :as mailserver]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.ui.screens.chat.state :as chat.state]
[status-im.utils.clocks :as utils.clocks]
[utils.re-frame :as rf]
[status-im.utils.types :as types]
[status-im.utils.utils :as utils]
[status-im2.contexts.chat.messages.delete-message-for-me.events :as delete-for-me]
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
[status-im2.navigation.events :as navigation]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.add-new.db :as new-public-chat.db]
[status-im.data-store.chats :as chats-store]))
(defn chats
[]
(:chats (types/json->clj (js/require "./chats.js"))))
(defn- get-chat
[cofx chat-id]
(get-in cofx [:db :chats chat-id]))
(defn multi-user-chat?
([chat]
(:group-chat chat))
([cofx chat-id]
(multi-user-chat? (get-chat cofx chat-id))))
(def one-to-one-chat?
(complement multi-user-chat?))
(defn public-chat?
([chat]
(:public? chat))
([cofx chat-id]
(public-chat? (get-chat cofx chat-id))))
(defn community-chat?
([{:keys [chat-type]}]
(= chat-type constants/community-chat-type))
([cofx chat-id]
(community-chat? (get-chat cofx chat-id))))
(defn active-chat?
[cofx chat-id]
(let [chat (get-chat cofx chat-id)]
(:active chat)))
(defn foreground-chat?
[{{:keys [current-chat-id view-id]} :db} chat-id]
(and (= current-chat-id chat-id)
(= view-id :chat)))
(defn group-chat?
([chat]
(and (multi-user-chat? chat)
(not (public-chat? chat))))
([cofx chat-id]
(group-chat? (get-chat cofx chat-id))))
(defn timeline-chat?
([chat]
(:timeline? chat))
([cofx chat-id]
(timeline-chat? (get-chat cofx chat-id))))
(defn profile-chat?
([chat]
(:profile-public-key chat))
([cofx chat-id]
(profile-chat? (get-chat cofx chat-id))))
(defn set-chat-ui-props
"Updates ui-props in active chat by merging provided kvs into them"
[{:keys [current-chat-id] :as db} kvs]
(update-in db [:chat-ui-props current-chat-id] merge kvs))
(defn- create-new-chat
[chat-id {:keys [db now]}]
(let [name (get-in db [:contacts/contacts chat-id :name])]
{:chat-id chat-id
:name (or name "")
:color (rand-nth colors/chat-colors)
:chat-type constants/one-to-one-chat-type
:group-chat false
:timestamp now
:contacts #{chat-id}
:last-clock-value 0}))
(defn map-chats
[{:keys [db] :as cofx}]
(fn [val]
(assoc
(merge
(or (get (:chats db) (:chat-id val))
(create-new-chat (:chat-id val) cofx))
val)
:invitation-admin
(:invitation-admin val))))
(defn filter-chats
[db]
(fn [val]
(and (not (get-in db [:chats (:chat-id val)])) (:public? val))))
(rf/defn leave-removed-chat
[{{:keys [view-id current-chat-id chats]} :db
:as cofx}]
(when (and (= view-id :chat)
(not (contains? chats current-chat-id)))
(navigation/navigate-back cofx)))
(rf/defn ensure-chats
"Add chats to db and update"
[{:keys [db] :as cofx} chats]
(let [{:keys [all-chats chats-home-list removed-chats]}
(reduce
(fn [acc {:keys [chat-id profile-public-key timeline? community-id active muted] :as chat}]
(if (not (or active muted))
(update acc :removed-chats conj chat-id)
(cond-> acc
(and (not profile-public-key) (not timeline?) (not community-id) active)
(update :chats-home-list conj chat-id)
:always
(assoc-in [:all-chats chat-id] chat))))
{:all-chats {}
:chats-home-list #{}
:removed-chats #{}}
(map (map-chats cofx) chats))]
(rf/merge
cofx
(merge {:db (-> db
(update :chats merge all-chats)
(update :chats-home-list set/union chats-home-list)
(update :chats #(apply dissoc % removed-chats))
(update :chats-home-list set/difference removed-chats))}
(when (not-empty removed-chats)
{:clear-message-notifications
[removed-chats
(get-in db [:multiaccount :remote-push-notifications-enabled?])]}))
leave-removed-chat)))
(rf/defn clear-history
"Clears history of the particular chat"
[{:keys [db] :as cofx} chat-id remove-chat?]
(let [{:keys [last-message public?
deleted-at-clock-value]}
(get-in db [:chats chat-id])
last-message-clock-value (if (and public? remove-chat?)
0
(or (:clock-value last-message)
deleted-at-clock-value
(utils.clocks/send 0)))]
{:db (-> db
(assoc-in [:messages chat-id] {})
(update-in [:message-lists] dissoc chat-id)
(update :chats
(fn [chats]
(if (contains? chats chat-id)
(update chats
chat-id
merge
{:last-message nil
:unviewed-messages-count 0
:unviewed-mentions-count 0
:deleted-at-clock-value last-message-clock-value})
chats))))}))
(rf/defn clear-history-handler
"Clears history of the particular chat"
{:events [:chat.ui/clear-history]}
[{:keys [db] :as cofx} chat-id remove-chat?]
(rf/merge cofx
{:db db
:json-rpc/call [{:method "wakuext_clearHistory"
:params [{:id chat-id}]
:on-success #(re-frame/dispatch [::history-cleared chat-id %])
:on-error #(log/error "failed to clear history " chat-id %)}]}
(clear-history chat-id remove-chat?)))
(rf/defn chat-deactivated
{:events [::chat-deactivated]}
[_ chat-id]
(log/debug "chat deactivated" chat-id))
(rf/defn deactivate-chat
"Deactivate chat in db, no side effects"
[{:keys [db now] :as cofx} chat-id]
(rf/merge
cofx
{:db (-> (if (get-in db [:chats chat-id :muted])
(assoc-in db [:chats chat-id :active] false)
(update db :chats dissoc chat-id))
(update :chats-home-list disj chat-id)
(assoc :current-chat-id nil))
:json-rpc/call [{:method "wakuext_deactivateChat"
:params [{:id chat-id}]
:on-success #(re-frame/dispatch [::chat-deactivated chat-id])
:on-error #(log/error "failed to create public chat" chat-id %)}]}
(clear-history chat-id true)))
(rf/defn offload-messages
{:events [:offload-messages]}
[{:keys [db]} chat-id]
(merge {:db (-> db
(update :messages dissoc chat-id)
(update :message-lists dissoc chat-id)
(update :pagination-info dissoc chat-id))}
(when (and (= chat-id constants/timeline-chat-id) (= (:view-id db) :status))
{:dispatch [:init-timeline-chat]})))
(rf/defn close-chat
{:events [:close-chat]}
[{:keys [db] :as cofx}]
(when-let [chat-id (:current-chat-id db)]
(chat.state/reset-visible-item)
(rf/merge cofx
{:db (dissoc db :current-chat-id)}
(delete-for-me/sync-all)
(delete-message/send-all)
(offload-messages chat-id))))
(rf/defn force-close-chat
[{:keys [db] :as cofx} chat-id]
(do
(chat.state/reset-visible-item)
(rf/merge cofx
{:db (dissoc db :current-chat-id)}
(offload-messages chat-id))))
(rf/defn remove-chat
"Removes chat completely from app, producing all necessary effects for that"
{:events [:chat.ui/remove-chat]}
[{:keys [db now] :as cofx} chat-id]
(rf/merge cofx
{:clear-message-notifications
[[chat-id] (get-in db [:multiaccount :remote-push-notifications-enabled?])]}
(deactivate-chat chat-id)
(offload-messages chat-id)))
(rf/defn show-more-chats
{:events [:chat.ui/show-more-chats]}
[{:keys [db]}]
(when (< (:home-items-show-number db) (count (:chats db)))
{:db (update db :home-items-show-number + 40)}))
(rf/defn preload-chat-data
"Takes chat-id and coeffects map, returns effects necessary when navigating to chat"
{:events [:chat.ui/preload-chat-data]}
[cofx chat-id]
(loading/load-messages cofx chat-id))
(rf/defn navigate-to-chat
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
{:events [:chat.ui/navigate-to-chat]}
[{db :db :as cofx} chat-id]
(rf/merge cofx
{:dispatch [:navigate-to :chat]}
(navigation/change-tab :chat)
(when-not (= (:view-id db) :community)
(navigation/pop-to-root-tab :chat-stack))
(close-chat)
(force-close-chat chat-id)
(fn [{:keys [db]}]
{:db (assoc db :current-chat-id chat-id)})
(preload-chat-data chat-id)
#(when (group-chat? cofx chat-id)
(loading/load-chat % chat-id))))
(rf/defn navigate-to-chat-nav2
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
{:events [:chat.ui/navigate-to-chat-nav2]}
[{db :db :as cofx} chat-id from-shell?]
(rf/merge cofx
{:dispatch [:navigate-to-nav2 :chat chat-id from-shell?]}
(when-not (= (:view-id db) :community)
(navigation/pop-to-root-tab :shell-stack))
(close-chat)
(force-close-chat chat-id)
(fn [{:keys [db]}]
{:db (assoc db :current-chat-id chat-id)})
(preload-chat-data chat-id)
#(when (group-chat? cofx chat-id)
(loading/load-chat % chat-id))))
(rf/defn handle-clear-history-response
{:events [::history-cleared]}
[{:keys [db]} chat-id response]
(let [chat (chats-store/<-rpc (first (:chats response)))]
{:db (assoc-in db [:chats chat-id] chat)}))
(rf/defn handle-one-to-one-chat-created
{:events [::one-to-one-chat-created]}
[{:keys [db]} chat-id response]
(let [chat (chats-store/<-rpc (first (:chats response)))
contact-rpc (first (:contacts response))
contact (when contact-rpc (contacts-store/<-rpc contact-rpc))]
{:db (cond-> db
contact
(assoc-in [:contacts/contacts chat-id] contact)
:always
(assoc-in [:chats chat-id] chat)
:always
(update :chats-home-list conj chat-id))
:dispatch [:chat.ui/navigate-to-chat chat-id]}))
(rf/defn navigate-to-user-pinned-messages
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
{:events [:chat.ui/navigate-to-pinned-messages]}
[cofx chat-id]
(navigation/navigate-to cofx :chat-pinned-messages {:chat-id chat-id}))
(rf/defn start-chat
"Start a chat, making sure it exists"
{:events [:chat.ui/start-chat]}
[{:keys [db] :as cofx} chat-id ens-name]
;; don't allow to open chat with yourself
(when (not= (multiaccounts.model/current-public-key cofx) chat-id)
{:json-rpc/call [{:method "wakuext_createOneToOneChat"
:params [{:id chat-id :ensName ens-name}]
:on-success #(re-frame/dispatch [::one-to-one-chat-created chat-id %])
:on-error #(log/error "failed to create one-to-on chat" chat-id %)}]}))
(defn profile-chat-topic
[public-key]
(str "@" public-key))
(defn my-profile-chat-topic
[db]
(profile-chat-topic (get-in db [:multiaccount :public-key])))
;; OLD
(rf/defn handle-public-chat-created
{:events [::public-chat-created]}
@@ -344,7 +14,7 @@
{:db (-> db
(assoc-in [:chats chat-id] (chats-store/<-rpc (first (:chats response))))
(update :chats-home-list conj chat-id))
:dispatch [:chat.ui/navigate-to-chat chat-id]})
:dispatch [:chat/navigate-to-chat chat-id]})
(rf/defn create-public-chat-go
[_ chat-id]
@@ -358,174 +28,8 @@
{:events [:chat.ui/start-public-chat]}
[cofx topic]
(if (new-public-chat.db/valid-topic? topic)
(if (active-chat? cofx topic)
(navigate-to-chat cofx topic)
(create-public-chat-go
cofx
topic))
(create-public-chat-go
cofx
topic)
{:utils/show-popup {:title (i18n/label :t/cant-open-public-chat)
:content (i18n/label :t/invalid-public-chat-topic)}}))
(rf/defn profile-chat-created
{:events [::profile-chat-created]}
[{:keys [db] :as cofx} chat-id response navigate-to?]
(rf/merge
cofx
{:db db}
#(when response
(let [chat (chats-store/<-rpc (first (:chats response)))]
{:db (assoc-in db [:chats chat-id] chat)}))
#(when navigate-to?
{:dispatch-n [[:chat.ui/preload-chat-data chat-id]
[:open-modal :profile]]})))
(rf/defn start-profile-chat
"Starts a new profile chat"
{:events [:start-profile-chat]}
[cofx profile-public-key navigate-to?]
(let [chat-id (profile-chat-topic profile-public-key)]
(if (active-chat? cofx chat-id)
{:dispatch [::profile-chat-created chat-id nil navigate-to?]}
{:json-rpc/call [{:method "wakuext_createProfileChat"
:params [{:id profile-public-key}]
:on-success #(re-frame/dispatch [::profile-chat-created chat-id % navigate-to?])
:on-error #(log/error "failed to create profile chat" chat-id %)}]})))
(rf/defn disable-chat-cooldown
"Turns off chat cooldown (protection against message spamming)"
{:events [:chat/disable-cooldown]}
[{:keys [db]}]
{:db (assoc db :chat/cooldown-enabled? false)})
;; effects
(re-frame/reg-fx
:show-cooldown-warning
(fn [_]
(utils/show-popup nil
(i18n/label :cooldown/warning-message)
#())))
(rf/defn mute-chat-failed
{:events [::mute-chat-failed]}
[{:keys [db] :as cofx} chat-id muted? error]
(log/error "mute chat failed" chat-id error)
{:db (assoc-in db [:chats chat-id :muted] (not muted?))})
(rf/defn mute-chat-toggled-successfully
{:events [::mute-chat-toggled-successfully]}
[_ chat-id]
(log/debug "muted chat successfully" chat-id))
(rf/defn mute-chat
{:events [::mute-chat-toggled]}
[{:keys [db] :as cofx} chat-id muted?]
(let [method (if muted? "wakuext_muteChat" "wakuext_unmuteChat")]
{:db (assoc-in db [:chats chat-id :muted] muted?)
:json-rpc/call [{:method method
:params [chat-id]
:on-error #(re-frame/dispatch [::mute-chat-failed chat-id muted? %])
:on-success #(re-frame/dispatch [::mute-chat-toggled-successfully chat-id])}]}))
(rf/defn show-profile
{:events [:chat.ui/show-profile]}
[{:keys [db] :as cofx} identity ens-name]
(let [my-public-key (get-in db [:multiaccount :public-key])]
(when (not= my-public-key identity)
(rf/merge
cofx
{:db (-> db
(assoc :contacts/identity identity)
(assoc :contacts/ens-name ens-name))}
(start-profile-chat identity true)))))
(rf/defn clear-history-pressed
{:events [:chat.ui/clear-history-pressed]}
[_ chat-id]
{:ui/show-confirmation
{:title (i18n/label :t/clear-history-title)
:content (i18n/label :t/clear-history-confirmation-content)
:confirm-button-text (i18n/label :t/clear-history-action)
:on-accept #(do
(re-frame/dispatch [:bottom-sheet/hide])
(re-frame/dispatch [:chat.ui/clear-history chat-id false]))}})
(rf/defn gaps-failed
{:events [::gaps-failed]}
[{:keys [db]} chat-id gap-ids error]
(log/error "failed to fetch gaps" chat-id gap-ids error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-failed
{:events [::sync-chat-from-sync-from-failed]}
[{:keys [db]} chat-id error]
(log/error "failed to sync chat" chat-id error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-success
{:events [::sync-chat-from-sync-from-success]}
[{:keys [db] :as cofx} chat-id synced-from]
(log/debug "synced success" chat-id synced-from)
{:db
(-> db
(assoc-in [:chats chat-id :synced-from] synced-from)
(dissoc :mailserver/fetching-gaps-in-progress))})
(rf/defn gaps-filled
{:events [::gaps-filled]}
[{:keys [db] :as cofx} chat-id message-ids]
(rf/merge
cofx
{:db (-> db
(update-in [:messages chat-id] (fn [messages] (apply dissoc messages message-ids)))
(dissoc :mailserver/fetching-gaps-in-progress))}
(message-list/rebuild-message-list chat-id)))
(rf/defn fill-gaps
[cofx chat-id gap-ids]
{:json-rpc/call [{:method "wakuext_fillGaps"
:params [chat-id gap-ids]
:on-success #(re-frame/dispatch [::gaps-filled chat-id gap-ids %])
:on-error #(re-frame/dispatch [::gaps-failed chat-id gap-ids %])}]})
(rf/defn sync-chat-from-sync-from
[cofx chat-id]
(log/debug "syncing chat from sync from")
{:json-rpc/call [{:method "wakuext_syncChatFromSyncedFrom"
:params [chat-id]
:on-success #(re-frame/dispatch [::sync-chat-from-sync-from-success chat-id %])
:on-error #(re-frame/dispatch [::sync-chat-from-sync-from-failed chat-id %])}]})
(rf/defn chat-ui-fill-gaps
{:events [:chat.ui/fill-gaps]}
[{:keys [db] :as cofx} chat-id gap-ids]
(let [use-status-nodes? (mailserver/fetch-use-mailservers? {:db db})]
(log/info "filling gaps if use-status-nodes = true" chat-id gap-ids)
(when use-status-nodes?
(rf/merge cofx
{:db (assoc db :mailserver/fetching-gaps-in-progress gap-ids)}
(if (= gap-ids #{:first-gap})
(sync-chat-from-sync-from chat-id)
(fill-gaps chat-id gap-ids))))))
(rf/defn chat-ui-remove-chat-pressed
{:events [:chat.ui/remove-chat-pressed]}
[_ chat-id]
{:ui/show-confirmation
{:title (i18n/label :t/delete-confirmation)
:content (i18n/label :t/delete-chat-confirmation)
:confirm-button-text (i18n/label :t/delete)
:on-accept #(do
(re-frame/dispatch [:bottom-sheet/hide])
(re-frame/dispatch [:chat.ui/remove-chat chat-id]))}})
(rf/defn decrease-unviewed-count
{:events [:chat/decrease-unviewed-count]}
[{:keys [db]} chat-id {:keys [count countWithMentions]}]
{:db (-> db
;; There might be some other requests being fired,
;; so we need to make sure the count has not been set to
;; 0 in the meantime
(update-in [:chats chat-id :unviewed-messages-count]
#(max (- % count) 0))
(update-in [:chats chat-id :unviewed-mentions-count]
#(max (- % countWithMentions) 0)))})
+63
View File
@@ -0,0 +1,63 @@
(ns status-im.chat.models.gaps
(:require [utils.re-frame :as rf]
[taoensso.timbre :as log]
[status-im2.contexts.chat.messages.list.events :as message-list]
[status-im.mailserver.core :as mailserver]))
(rf/defn gaps-filled
{:events [:gaps/filled]}
[{:keys [db] :as cofx} chat-id message-ids]
(rf/merge
cofx
{:db (-> db
(update-in [:messages chat-id] (fn [messages] (apply dissoc messages message-ids)))
(dissoc :mailserver/fetching-gaps-in-progress))}
(message-list/rebuild-message-list chat-id)))
(rf/defn gaps-failed
{:events [:gaps/failed]}
[{:keys [db]} chat-id gap-ids error]
(log/error "failed to fetch gaps" chat-id gap-ids error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-failed
{:events [::sync-chat-from-sync-from-failed]}
[{:keys [db]} chat-id error]
(log/error "failed to sync chat" chat-id error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-success
{:events [::sync-chat-from-sync-from-success]}
[{:keys [db] :as cofx} chat-id synced-from]
(log/debug "synced success" chat-id synced-from)
{:db
(-> db
(assoc-in [:chats chat-id :synced-from] synced-from)
(dissoc :mailserver/fetching-gaps-in-progress))})
(rf/defn fill-gaps
[_ chat-id gap-ids]
{:json-rpc/call [{:method "wakuext_fillGaps"
:params [chat-id gap-ids]
:on-success #(rf/dispatch [:gaps/filled chat-id gap-ids %])
:on-error #(rf/dispatch [:gaps/failed chat-id gap-ids %])}]})
(rf/defn sync-chat-from-sync-from
[_ chat-id]
(log/debug "syncing chat from sync from")
{:json-rpc/call [{:method "wakuext_syncChatFromSyncedFrom"
:params [chat-id]
:on-success #(rf/dispatch [::sync-chat-from-sync-from-success chat-id %])
:on-error #(rf/dispatch [::sync-chat-from-sync-from-failed chat-id %])}]})
(rf/defn chat-ui-fill-gaps
{:events [:chat.ui/fill-gaps]}
[{:keys [db] :as cofx} chat-id gap-ids]
(let [use-status-nodes? (mailserver/fetch-use-mailservers? {:db db})]
(log/info "filling gaps if use-status-nodes = true" chat-id gap-ids)
(when use-status-nodes?
(rf/merge cofx
{:db (assoc db :mailserver/fetching-gaps-in-progress gap-ids)}
(if (= gap-ids #{:first-gap})
(sync-chat-from-sync-from chat-id)
(fill-gaps chat-id gap-ids))))))
+24 -35
View File
@@ -3,11 +3,10 @@
["react-native-blob-util" :default ReactNativeBlobUtil]
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.chat.models :as chat]
[i18n.i18n :as i18n]
[utils.i18n :as i18n]
[status-im.ui.components.permissions :as permissions]
[status-im.ui.components.react :as react]
[status-im.utils.config :as config]
[status-im2.config :as config]
[status-im.utils.fs :as fs]
[utils.re-frame :as rf]
[status-im.utils.image-processing :as image-processing]
@@ -98,10 +97,10 @@
(re-frame/reg-fx
::image-selected
(fn [[uri chat-id]]
(fn [[image chat-id]]
(resize-and-call
uri
#(re-frame/dispatch [:chat.ui/image-selected chat-id uri %]))))
(:uri image)
#(re-frame/dispatch [:chat.ui/image-selected chat-id image %]))))
(re-frame/reg-fx
::camera-roll-get-photos
@@ -112,9 +111,18 @@
(-> (if end-cursor
(.getPhotos
CameraRoll
#js {:first num :after end-cursor :assetType "Photos" :groupTypes "All"})
#js
{:first num
:after end-cursor
:assetType "Photos"
:groupTypes "All"
:include (clj->js ["imageSize"])})
(.getPhotos CameraRoll
#js {:first num :assetType "Photos" :groupTypes "All"}))
#js
{:first num
:assetType "Photos"
:groupTypes "All"
:include (clj->js ["imageSize"])}))
(.then #(let [response (types/js->clj %)]
(re-frame/dispatch [:on-camera-roll-get-photos (:edges response)
(:page_info response) end-cursor])))
@@ -151,7 +159,7 @@
[{:keys [db] :as cofx} photos page-info end-cursor]
(let [photos_x (when end-cursor (:camera-roll/photos db))]
{:db (-> db
(assoc :camera-roll/photos (concat photos_x (map #(get-in % [:node :image :uri]) photos)))
(assoc :camera-roll/photos (concat photos_x (map #(get-in % [:node :image]) photos)))
(assoc :camera-roll/end-cursor (:end_cursor page-info))
(assoc :camera-roll/has-next-page (:has_next_page page-info))
(assoc :camera-roll/loading-more false))}))
@@ -167,21 +175,17 @@
(let [current-chat-id (or chat-id (:current-chat-id db))]
(clear-sending-images cofx current-chat-id)))
(rf/defn cancel-sending-image-timeline
{:events [:chat.ui/cancel-sending-image-timeline]}
[{:keys [db] :as cofx}]
(cancel-sending-image cofx (chat/my-profile-chat-topic db)))
(rf/defn image-selected
{:events [:chat.ui/image-selected]}
[{:keys [db]} current-chat-id original uri]
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image original] merge {:uri uri})})
{:db
(update-in db [:chat/inputs current-chat-id :metadata :sending-image uri] merge original {:uri uri})})
(rf/defn image-unselected
{:events [:chat.ui/image-unselected]}
[{:keys [db]} original]
(let [current-chat-id (:current-chat-id db)]
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc original)}))
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc (:uri original))}))
(rf/defn chat-open-image-picker
{:events [:chat.ui/open-image-picker]}
@@ -191,11 +195,6 @@
(when (< (count images) config/max-images-batch)
{::chat-open-image-picker current-chat-id})))
(rf/defn chat-open-image-picker-timeline
{:events [:chat.ui/open-image-picker-timeline]}
[{:keys [db] :as cofx}]
(chat-open-image-picker cofx (chat/my-profile-chat-topic db)))
(rf/defn chat-show-image-picker-camera
{:events [:chat.ui/show-image-picker-camera]}
[{:keys [db]} chat-id]
@@ -204,27 +203,17 @@
(when (< (count images) config/max-images-batch)
{::chat-open-image-picker-camera current-chat-id})))
(rf/defn chat-show-image-picker-camera-timeline
{:events [:chat.ui/show-image-picker-camera-timeline]}
[{:keys [db] :as cofx}]
(chat-show-image-picker-camera cofx (chat/my-profile-chat-topic db)))
(rf/defn camera-roll-pick
{:events [:chat.ui/camera-roll-pick]}
[{:keys [db]} uri chat-id]
[{:keys [db]} image chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(if (get-in db [:chats current-chat-id :timeline?])
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-image] {})
::image-selected [uri current-chat-id]}
::image-selected [image current-chat-id]}
(when (and (< (count images) config/max-images-batch)
(not (get images uri)))
{::image-selected [uri current-chat-id]}))))
(rf/defn camera-roll-pick-timeline
{:events [:chat.ui/camera-roll-pick-timeline]}
[{:keys [db] :as cofx} uri]
(camera-roll-pick cofx uri (chat/my-profile-chat-topic db)))
(not (some #(= (:uri image) (:uri %)) images)))
{::image-selected [image current-chat-id]}))))
(rf/defn save-image-to-gallery
{:events [:chat.ui/save-image-to-gallery]}
+53 -100
View File
@@ -3,17 +3,15 @@
[clojure.string :as string]
[goog.object :as object]
[re-frame.core :as re-frame]
[status-im.chat.constants :as chat.constants]
[status-im.chat.models :as chat]
[status-im.chat.models.mentions :as mentions]
[status-im.chat.models.message :as chat.message]
[status-im.chat.models.message-content :as message-content]
[status-im.constants :as constants]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[i18n.i18n :as i18n]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.ui.screens.chat.components.input :as input]))
(defn text->emoji
"Replaces emojis in a specified `text`"
@@ -25,6 +23,14 @@
(.-char ^js emoji-map)
original))))
;; effects
(re-frame/reg-fx
:show-cooldown-warning
(fn [_]
(utils/show-popup nil
(i18n/label :cooldown/warning-message)
#())))
(rf/defn set-chat-input-text
"Set input text for current-chat. Takes db and input text and cofx
as arguments and returns new fx. Always clear all validation messages."
@@ -33,13 +39,6 @@
(let [current-chat-id (or chat-id (:current-chat-id db))]
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))}))
(rf/defn set-timeline-input-text
{:events [:chat.ui/set-timeline-input-text]}
[{db :db} new-input]
{:db (assoc-in db
[:chat/inputs (chat/my-profile-chat-topic db) :input-text]
(text->emoji new-input))})
(rf/defn select-mention
{:events [:chat.ui/select-mention]}
[{:keys [db] :as cofx} text-input-ref {:keys [alias name searched-text match] :as user}]
@@ -49,9 +48,10 @@
cursor (+ at-sign-idx (count name) 2)]
(rf/merge
cofx
{:db (-> db
(assoc-in [:chats/cursor chat-id] cursor)
(assoc-in [:chats/mention-suggestions chat-id] nil))}
{:db (-> db
(assoc-in [:chats/cursor chat-id] cursor)
(assoc-in [:chats/mention-suggestions chat-id] nil))
:set-text-input-value [chat-id new-text text-input-ref]}
(set-chat-input-text new-text chat-id)
;; NOTE(rasom): Some keyboards do not react on selection property passed to
;; text input (specifically Samsung keyboard with predictive text set on).
@@ -73,80 +73,45 @@
:end end}))
(mentions/recheck-at-idxs {alias user}))))
(defn- start-cooldown
[{:keys [db]} cooldowns]
{:dispatch-later [{:dispatch [:chat/disable-cooldown]
:ms (chat.constants/cooldown-periods-ms
cooldowns
chat.constants/default-cooldown-period-ms)}]
:show-cooldown-warning nil
:db (assoc db
:chat/cooldowns (if
(=
chat.constants/cooldown-reset-threshold
cooldowns)
0
cooldowns)
:chat/spam-messages-frequency 0
:chat/cooldown-enabled? true)})
(rf/defn process-cooldown
"Process cooldown to protect against message spammers"
[{{:keys [chat/last-outgoing-message-sent-at
chat/cooldowns
chat/spam-messages-frequency
current-chat-id]
:as db}
:db
:as cofx}]
(when (chat/public-chat? cofx current-chat-id)
(let [spamming-fast? (< (- (datetime/timestamp) last-outgoing-message-sent-at)
(+ chat.constants/spam-interval-ms (* 1000 cooldowns)))
spamming-frequently? (= chat.constants/spam-message-frequency-threshold
spam-messages-frequency)]
(cond-> {:db (assoc db
:chat/last-outgoing-message-sent-at (datetime/timestamp)
:chat/spam-messages-frequency (if spamming-fast?
(inc spam-messages-frequency)
0))}
(and spamming-fast? spamming-frequently?)
(start-cooldown (inc cooldowns))))))
(rf/defn disable-chat-cooldown
"Turns off chat cooldown (protection against message spamming)"
{:events [:chat/disable-cooldown]}
[{:keys [db]}]
{:db (assoc db :chat/cooldown-enabled? false)})
(rf/defn reply-to-message
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/reply-to-message]}
[{:keys [db] :as cofx} message]
[{:keys [db]} message]
(let [current-chat-id (:current-chat-id db)]
(rf/merge cofx
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))})))
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))}))
(rf/defn edit-message
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/edit-message]}
[{:keys [db] :as cofx} message]
(let [current-chat-id (:current-chat-id db)
text (get-in message [:content :text])]
{:dispatch [:chat.ui.input/set-chat-input-text text current-chat-id]
:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))}))
(rf/merge cofx
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message]
message)
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))}
(input/set-input-text text current-chat-id))))
(rf/defn show-contact-request-input
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/send-contact-request]}
[{:keys [db] :as cofx}]
[{:keys [db]}]
(let [current-chat-id (:current-chat-id db)]
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request]
@@ -182,15 +147,20 @@
:ens-name preferred-name})))
(defn build-image-messages
[{db :db} chat-id]
[{db :db} chat-id input-text]
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
album-id (str (random-uuid))]
(mapv (fn [[_ {:keys [uri]}]]
(mapv (fn [[_ {:keys [uri width height]}]]
{:chat-id chat-id
:album-id album-id
:content-type constants/content-type-image
:image-path (utils/safe-replace uri #"file://" "")
:text (i18n/label :t/update-to-see-image {"locale" "en"})})
:image-width width
:image-height height
;; TODO: message not received if text field is
;; nil or empty, issue:
;; https://github.com/status-im/status-mobile/issues/14754
:text (or input-text "placeholder")})
images)))
(rf/defn clean-input
@@ -216,27 +186,13 @@
(rf/defn send-messages
[{:keys [db] :as cofx} input-text current-chat-id]
(let [image-messages (build-image-messages cofx current-chat-id)
text-message (build-text-message cofx input-text current-chat-id)
(let [image-messages (build-image-messages cofx current-chat-id input-text)
text-message (when-not (seq image-messages)
(build-text-message cofx input-text current-chat-id))
messages (keep identity (conj image-messages text-message))]
(when (seq messages)
(rf/merge cofx
(clean-input (:current-chat-id db))
(process-cooldown)
(chat.message/send-messages messages)))))
(rf/defn send-my-status-message
"when not empty, proceed by sending text message with public key topic"
{:events [:profile.ui/send-my-status-message]}
[{db :db :as cofx}]
(let [current-chat-id (chat/my-profile-chat-topic db)
{:keys [input-text]} (get-in db [:chat/inputs current-chat-id])
image-messages (build-image-messages cofx current-chat-id)
text-message (build-text-message cofx input-text current-chat-id)
messages (keep identity (conj image-messages text-message))]
(when (seq messages)
(rf/merge cofx
(clean-input current-chat-id)
(chat.message/send-messages messages)))))
(rf/defn send-audio-message
@@ -274,8 +230,7 @@
:js-response true
:on-error #(log/error "failed to edit message " %)
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}
(cancel-message-edit)
(process-cooldown)))
(cancel-message-edit)))
(rf/defn send-current-message
"Sends message from current chat input"
@@ -304,8 +259,7 @@
:on-success #(re-frame/dispatch [:transport/message-sent %])}]}
(mentions/clear-mentions)
(mentions/clear-cursor)
(clean-input (:current-chat-id db))
(process-cooldown)))
(clean-input (:current-chat-id db))))
(rf/defn cancel-contact-request
"Cancels contact request"
@@ -316,8 +270,7 @@
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-contact-request] nil)}
(mentions/clear-mentions)
(mentions/clear-cursor)
(clean-input (:current-chat-id db))
(process-cooldown))))
(clean-input (:current-chat-id db)))))
(rf/defn chat-send-sticker
{:events [:chat/send-sticker]}
+2 -72
View File
@@ -1,79 +1,9 @@
(ns status-im.chat.models.input-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.chat.constants :as constants]
[status-im.chat.models.input :as input]
[utils.datetime :as datetime]))
(:require [cljs.test :refer-macros [deftest is]]
[status-im.chat.models.input :as input]))
(deftest text->emoji
(is (nil? (input/text->emoji nil)))
(is (= "" (input/text->emoji "")))
(is (= "test" (input/text->emoji "test")))
(is (= "word1 \uD83D\uDC4D word2" (input/text->emoji "word1 :+1: word2"))))
(deftest process-cooldown-fx
(let [db {:current-chat-id "chat"
:chats {"chat" {:public? true}}
:chat/cooldowns 0
:chat/spam-messages-frequency 0
:chat/cooldown-enabled? false}]
(with-redefs [datetime/timestamp (constantly 1527675198542)]
(testing "no spamming detected"
(let [expected {:db (assoc db :chat/last-outgoing-message-sent-at 1527675198542)}
actual (input/process-cooldown {:db db})]
(is (= expected actual))))
(testing "spamming detected in 1-1"
(let [db (assoc db
:chats {"chat" {:public? false}}
:chat/spam-messages-frequency constants/spam-message-frequency-threshold
:chat/last-outgoing-message-sent-at (- 1527675198542 900))
expected nil
actual (input/process-cooldown {:db db})]
(is (= expected actual))))
(testing "spamming detected"
(let [db (assoc db
:chat/last-outgoing-message-sent-at (- 1527675198542 900)
:chat/spam-messages-frequency constants/spam-message-frequency-threshold)
expected {:db (assoc db
:chat/last-outgoing-message-sent-at 1527675198542
:chat/cooldowns 1
:chat/spam-messages-frequency 0
:chat/cooldown-enabled? true)
:show-cooldown-warning nil
:dispatch-later [{:dispatch [:chat/disable-cooldown]
:ms (constants/cooldown-periods-ms 1)}]}
actual (input/process-cooldown {:db db})]
(is (= expected actual))))
(testing "spamming detected twice"
(let [db (assoc db
:chat/cooldowns 1
:chat/last-outgoing-message-sent-at (- 1527675198542 900)
:chat/spam-messages-frequency constants/spam-message-frequency-threshold)
expected {:db (assoc db
:chat/last-outgoing-message-sent-at 1527675198542
:chat/cooldowns 2
:chat/spam-messages-frequency 0
:chat/cooldown-enabled? true)
:show-cooldown-warning nil
:dispatch-later [{:dispatch [:chat/disable-cooldown]
:ms (constants/cooldown-periods-ms 2)}]}
actual (input/process-cooldown {:db db})]
(is (= expected actual))))
(testing "spamming reaching cooldown threshold"
(let [db (assoc db
:chat/cooldowns (dec constants/cooldown-reset-threshold)
:chat/last-outgoing-message-sent-at (- 1527675198542 900)
:chat/spam-messages-frequency constants/spam-message-frequency-threshold)
expected {:db (assoc db
:chat/last-outgoing-message-sent-at 1527675198542
:chat/cooldowns 0
:chat/spam-messages-frequency 0
:chat/cooldown-enabled? true)
:show-cooldown-warning nil
:dispatch-later [{:dispatch [:chat/disable-cooldown]
:ms (constants/cooldown-periods-ms 3)}]}
actual (input/process-cooldown {:db db})]
(is (= expected actual)))))))
-119
View File
@@ -1,119 +0,0 @@
(ns status-im.chat.models.link-preview
(:require [re-frame.core :as re-frame]
[status-im.communities.core :as models.communities]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[utils.re-frame :as rf]
[taoensso.timbre :as log]))
(rf/defn enable
{:events [::enable]}
[{{:keys [multiaccount]} :db :as cofx} site enabled?]
(rf/merge cofx
(multiaccounts.update/multiaccount-update
:link-previews-enabled-sites
(if enabled?
(conj (get multiaccount :link-previews-enabled-sites #{}) site)
(disj (get multiaccount :link-previews-enabled-sites #{}) site))
{})))
(rf/defn enable-all
{:events [::enable-all]}
[{{:keys [multiaccount]} :db :as cofx} link-previews-whitelist enabled?]
(rf/merge cofx
(multiaccounts.update/multiaccount-update
:link-previews-enabled-sites
(if enabled?
(into #{} (map :title link-previews-whitelist))
#{})
{})))
(defn community-resolved
[db community-id]
(update db :communities/resolve-community-info dissoc community-id))
(defn community-failed-to-resolve
[db community-id]
(update db :communities/resolve-community-info dissoc community-id))
(defn community-resolving
[db community-id]
(assoc-in db [:communities/resolve-community-info community-id] true))
(rf/defn handle-community-failed-to-resolve
{:events [::community-failed-to-resolve]}
[{:keys [db]} community-id]
{:db (community-failed-to-resolve db community-id)})
(defn community-link
[id]
(str "https://join.status.im/c/" id))
(rf/defn handle-community-resolved
{:events [::community-resolved]}
[{:keys [db] :as cofx} community-id community]
(rf/merge cofx
(cond-> {:db (community-resolved db community-id)}
(some? community)
(assoc :dispatch
[::cache-link-preview-data
(community-link community-id) community]))
(models.communities/handle-community community)))
(rf/defn resolve-community-info
{:events [::resolve-community-info]}
[{:keys [db]} community-id]
{:db (community-resolving db community-id)
:json-rpc/call [{:method "wakuext_requestCommunityInfoFromMailserver"
:params [community-id]
:on-success #(re-frame/dispatch [::community-resolved community-id %])
:on-error #(do
(re-frame/dispatch [::community-failed-to-resolve community-id])
(log/error "Failed to request community info from mailserver"))}]})
(rf/defn load-link-preview-data
{:events [::load-link-preview-data]}
[cofx link]
{:json-rpc/call [{:method "wakuext_getLinkPreviewData"
:params [link]
:on-success #(re-frame/dispatch [::cache-link-preview-data link %])
:on-error #(re-frame/dispatch
[::cache-link-preview-data
link
{:error (str "Can't get preview data for " link)}])}]})
(rf/defn cache-link-preview-data
{:events [::cache-link-preview-data]}
[{{:keys [multiaccount]} :db :as cofx} site data]
(multiaccounts.update/optimistic
cofx
:link-previews-cache
(assoc (get multiaccount :link-previews-cache {}) site data)))
(defn cache-community-preview-data
[{:keys [id] :as community}]
(re-frame/dispatch [::cache-link-preview-data
(community-link id)
community]))
(rf/defn should-suggest-link-preview
{:events [::should-suggest-link-preview]}
[{:keys [db] :as cofx} enabled?]
(multiaccounts.update/multiaccount-update
cofx
:link-preview-request-enabled
(boolean enabled?)
{}))
(rf/defn request-link-preview-whitelist
[_]
{:json-rpc/call [{:method "wakuext_getLinkPreviewWhitelist"
:params []
:on-success #(re-frame/dispatch [::link-preview-whitelist-received %])
:on-error #(log/error "Failed to get link preview whitelist")}]})
(rf/defn save-link-preview-whitelist
{:events [::link-preview-whitelist-received]}
[{:keys [db]} whitelist]
{:db (assoc db
:link-previews-whitelist
whitelist)})
+6 -7
View File
@@ -1,10 +1,9 @@
(ns status-im.chat.models.loading
(:require [re-frame.core :as re-frame]
[status-im.chat.models.message-list :as message-list]
[status-im.constants :as constants]
[status-im2.contexts.chat.messages.list.events :as message-list]
[status-im2.constants :as constants]
[status-im.data-store.chats :as data-store.chats]
[status-im.data-store.messages :as data-store.messages]
[status-im2.contexts.activity-center.events :as activity-center]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
@@ -69,15 +68,15 @@
(rf/defn handle-mark-all-read-successful
{:events [::mark-all-read-successful]}
[cofx]
(activity-center/notifications-fetch-unread-count cofx))
[_]
{:dispatch [:activity-center.notifications/fetch-unread-count]})
(rf/defn handle-mark-all-read-in-community-successful
{:events [::mark-all-read-in-community-successful]}
[{:keys [db] :as cofx} chat-ids]
(rf/merge cofx
{:db (reduce mark-chat-all-read db chat-ids)}
(activity-center/notifications-fetch-unread-count)))
{:db (reduce mark-chat-all-read db chat-ids)
:dispatch [:activity-center.notifications/fetch-unread-count]}))
(rf/defn handle-mark-all-read
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}
+1 -1
View File
@@ -3,7 +3,7 @@
[quo.react :as react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im2.constants :as constants]
[status-im.contact.db :as contact.db]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.native-module.core :as status]
+2 -42
View File
@@ -1,14 +1,12 @@
(ns status-im.chat.models.message
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.chat.models :as chat-model]
[status-im.chat.models.loading :as chat.loading]
[status-im.chat.models.mentions :as mentions]
[status-im.chat.models.message-list :as message-list]
[status-im.constants :as constants]
[status-im2.contexts.chat.messages.list.events :as message-list]
[status-im.data-store.messages :as data-store.messages]
[status-im.transport.message.protocol :as protocol]
[status-im.ui.screens.chat.state :as view.state]
[status-im2.contexts.chat.messages.list.state :as view.state]
[utils.re-frame :as rf]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.platform :as platform]
@@ -56,20 +54,6 @@
{:db db}
messages))
(defn timeline-message?
[db chat-id]
(and
(get-in db [:pagination-info constants/timeline-chat-id :messages-initialized?])
(or
(= chat-id (chat-model/my-profile-chat-topic db))
(when-let [pub-key (get-in db [:chats chat-id :profile-public-key])]
(get-in db [:contacts/contacts pub-key :added])))))
(defn get-timeline-message
[db chat-id message-js]
(when (timeline-message? db chat-id)
(data-store.messages/<-rpc (types/js->clj message-js))))
(defn add-message
[{:keys [db] :as acc} message-js chat-id message-id cursor-clock-value]
(let [{:keys [replace from clock-value] :as message}
@@ -148,30 +132,6 @@
(when (seq senders)
[{:ms 100 :dispatch [:chat/add-senders-to-chat-users (vals senders)]}]))}))
(defn reduce-js-statuses
[db ^js message-js]
(let [chat-id (.-localChatId message-js)
profile-initialized (get-in db [:pagination-info chat-id :messages-initialized?])
timeline-message (timeline-message? db chat-id)
old-message (get-in db [:messages chat-id (.-id message-js)])]
(if (and (or profile-initialized timeline-message) (nil? old-message))
(let [{:keys [message-id] :as message} (data-store.messages/<-rpc (types/js->clj message-js))]
(cond-> db
profile-initialized
(update-in [:messages chat-id] assoc message-id message)
profile-initialized
(update-in [:message-lists chat-id] message-list/add message)
timeline-message
(update-in [:messages constants/timeline-chat-id] assoc message-id message)
timeline-message
(update-in [:message-lists constants/timeline-chat-id] message-list/add message)))
db)))
(rf/defn process-statuses
{:events [:process-statuses]}
[{:keys [db]} statuses]
{:db (reduce reduce-js-statuses db statuses)})
(rf/defn update-db-message-status
[{:keys [db] :as cofx} chat-id message-id status]
(when (get-in db [:messages chat-id message-id])

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