Compare commits

..
2 Commits
Author SHA1 Message Date
Ibrahem Khalil 9abb794785 Merge branch 'develop' into 18877 2024-02-18 14:02:46 +02:00
ibrkhalil aefb0338ec Use placeholder value if no wallet name is supplied 2024-02-17 20:14:36 +02:00
92 changed files with 1022 additions and 986 deletions
+2 -2
View File
@@ -195,5 +195,5 @@ test/appium/tests/users.py
## git hooks
lefthook.yml
## build time logs
/logs/*.log
## metro server logs
metro-server-logs.log
+5 -4
View File
@@ -36,8 +36,6 @@ endif
export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG)
# This has to be specified for both the Node.JS server process and the Qt process.
export REACT_SERVER_PORT ?= 5001
# Default metro port used by scripts/run-android.sh.
export RCT_METRO_PORT ?= 8081
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
export NODE_OPTIONS += --openssl-legacy-provider
# The path can be anything, but home is usually safest.
@@ -296,8 +294,11 @@ show-ios-devices: ##@other shows connected ios device and its name
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios-device: export TARGET := ios
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64
run-ios-device: ##@run iOS app and start it on the first connected iPhone
@scripts/run-ios-device.sh
run-ios-device: ##@run iOS app and start it on a connected device by its name
ifndef DEVICE_NAME
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
endif
react-native run-ios --device "$(DEVICE_NAME)"
#--------------
# Tests
+1 -1
View File
@@ -1 +1 @@
2.27.0
1.25.0
-2
View File
@@ -28,8 +28,6 @@
[Contributing to status-go](status-go-changes.md)
[Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf))
## Testing
[How to run local tests](testing.md)
-18
View File
@@ -1,18 +0,0 @@
# Description
This directory is the destination of logs created during build time of debug builds.
# Logs
* `xcrun_device_install.log` - Output from `status-mobile/scripts/run-ios-device.sh`.
- Created by redirecting output of `xcrun simctl install "$UDID" "$APP_PATH"`.
* `xcrun_device_process_launch.log` - Output from `status-mobile/scripts/run-ios-device.sh`.
- Created by specifying `--json-output` flag for `xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}"`.
* `xcrun_device_process_resume.log` - Output from `status-mobile/scripts/run-ios-device.sh`.
- Created by redirecting output of `xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}"`.
* `adb_install.log` - Output from `scripts/run-android.sh`.
- Created by redirecting output of `adb install -r ./result/app-debug.apk`.
* `adb_shell_monkey.log` - Output from `status-mobile/scripts/run-android.sh`.
- Created by redirecting output of `adb shell monkey -p im.status.ethereum.debug 1 >`.
* `ios_simulators_list.log` - Output from `status-mobile/scripts/run-ios.sh`.
- Created by redirecting output of `xcrun simctl list devices -j`.
+1 -1
View File
@@ -20,8 +20,8 @@ in {
buildInputs = with pkgs; [
xcodeWrapper watchman procps
flock # used in nix/scripts/node_modules.sh
ios-deploy # used in 'make run-ios-device'
xcbeautify # used in 'make run-ios'
libimobiledevice # used in `make run-ios-device`
];
# WARNING: Executes shellHook in reverse order.
+12
View File
@@ -26,6 +26,18 @@ in {
react-native = callPackage ./deps/react-native { };
};
# Fix for missing libarclite_macosx.a in Xcode 14.3.
# https://github.com/ios-control/ios-deploy/issues/580
ios-deploy = super.darwin.ios-deploy.overrideAttrs (old: rec {
version = "1.12.2";
src = super.fetchFromGitHub {
owner = "ios-control";
repo = "ios-deploy";
rev = version;
sha256 = "sha256-TVGC+f+1ow3b93CK3PhIL70le5SZxxb2ug5OkIg8XCA";
};
});
# Clojure's linter receives frequent upgrades, and we want to take advantage
# of the latest available rules.
clj-kondo = super.clj-kondo.override rec {
+39 -16
View File
@@ -1,9 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
set -m # needed to access jobs
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
ADB_INSTALL_LOG_FILE="${GIT_ROOT}/logs/adb_install.log"
ADB_SHELL_MONKEY_LOG_FILE="${GIT_ROOT}/logs/adb_shell_monkey.log"
# We run Metro in background while calling adb.
cleanupMetro() {
pkill -f run-metro.sh
rm -f metro-server-logs.log
}
# Using function gives a neater jobspec name.
runMetro() {
nohup "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 \
| tee metro-server-logs.log
}
waitForMetro() {
set +e # Allow grep command to fail in the loop.
TIMEOUT=5
echo "Waiting for Metro server..." >&2
while ! grep -q "Welcome to Metro" metro-server-logs.log; do
echo -n "." >&2
sleep 1
if ((TIMEOUT == 0)); then
echo -e "\nMetro server timed out, exiting" >&2
set -e # Restore errexit for rest of script.
return 1
fi
((TIMEOUT--))
done
set -e # Restore errexit for rest of script.
}
# Generate android debug build.
export ANDROID_ABI_INCLUDE=$("${GIT_ROOT}/scripts/adb_devices_abis.sh")
@@ -12,19 +40,14 @@ export BUILD_TYPE=debug
"${GIT_ROOT}/scripts/build-android.sh"
# Install the APK on running emulator or android device.
installAndLaunchApp() {
adb install -r ./result/app-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1
"${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1
# connected android devices need this port to be exposed for metro
adb reverse "tcp:${RCT_METRO_PORT}" "tcp:${RCT_METRO_PORT}"
adb shell monkey -p im.status.ethereum.debug 1 > "${ADB_SHELL_MONKEY_LOG_FILE}" 2>&1
}
adb install ./result/app-debug.apk
showAdbLogs() {
cat "${ADB_INSTALL_LOG_FILE}" >&2;
cat "${ADB_SHELL_MONKEY_LOG_FILE}" >&2;
}
trap cleanupMetro EXIT ERR INT QUIT
runMetro &
waitForMetro
trap showAdbLogs EXIT ERR INT QUIT
installAndLaunchApp &
exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1
# Start the installed app.
adb shell monkey -p im.status.ethereum.debug 1
# bring metro job to foreground
fg 'runMetro'
-55
View File
@@ -1,55 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
set -m # needed to access jobs
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
XCRUN_DEVICE_INSTALL_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_install.log"
XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_launch.log"
XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_resume.log"
# Install on the connected device
installAndLaunchApp() {
xcrun devicectl device install app --device "${DEVICE_UUID}" "${APP_PATH}" --json-output "${XCRUN_DEVICE_INSTALL_LOG_DIR}" 2>&1
# Extract installationURL
INSTALLATION_URL=$(jq -r '.result.installedApplications[0].installationURL' "${XCRUN_DEVICE_INSTALL_LOG_DIR}")
# launch the app and put it in background
xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}" --json-output "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}"
# Extract background PID of status app
STATUS_PID=$(jq -r '.result.process.processIdentifier' "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}")
"${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1
# now that metro is ready, resume the app from background
xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}" > "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" 2>&1
}
showXcrunLogs() {
cat "${XCRUN_DEVICE_INSTALL_LOG_DIR}" >&2;
cat "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}" >&2;
cat "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" >&2;
}
# find the first connected iPhone's UUID
DEVICE_UUID=$(idevice_id -l)
# Check if any device is connected
if [ -z "${DEVICE_UUID}" ]; then
echo "No connected iPhone device detected."
exit 1
else
echo "Connected iPhone UDID: ${DEVICE_UUID}"
fi
BUILD_DIR="${GIT_ROOT}/build"
#iOS build of debug scheme
xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${DEVICE_UUID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify
APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphoneos/StatusIm.app"
trap showXcrunLogs EXIT ERR INT QUIT
installAndLaunchApp &
exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1
+46 -36
View File
@@ -3,21 +3,34 @@ set -euo pipefail
set -m # needed to access jobs
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
XCRUN_INSTALL_LOG_FILE="${GIT_ROOT}/logs/xcrun_install.log"
XCRUN_LAUNCH_LOG_FILE="${GIT_ROOT}/logs/xcrun_launch.log"
XCRUN_SIMULATOR_JSON_FILE="${GIT_ROOT}/logs/ios_simulators_list.log"
# Install on the simulator
installAndLaunchApp() {
xcrun simctl install "$UDID" "$APP_PATH" > "${XCRUN_INSTALL_LOG_FILE}" 2>&1
"${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1
xcrun simctl launch "$UDID" im.status.ethereum.debug > "${XCRUN_LAUNCH_LOG_FILE}" 2>&1
# We run Metro in background while calling adb.
cleanupMetro() {
pkill -f run-metro.sh
rm -f metro-server-logs.log
}
showXcrunLogs() {
cat "${XCRUN_INSTALL_LOG_FILE}" >&2;
cat "${XCRUN_LAUNCH_LOG_FILE}" >&2;
# Using function gives a neater jobspec name.
runMetro() {
nohup "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 \
| tee metro-server-logs.log
}
waitForMetro() {
set +e # Allow grep command to fail in the loop.
TIMEOUT=5
echo "Waiting for Metro server..." >&2
while ! grep -q "Welcome to Metro" metro-server-logs.log; do
echo -n "." >&2
sleep 1
if ((TIMEOUT == 0)); then
echo -e "\nMetro server timed out, exiting" >&2
set -e # Restore errexit for rest of script.
return 1
fi
((TIMEOUT--))
done
set -e # Restore errexit for rest of script.
}
# Check if the first argument is provided
@@ -26,44 +39,41 @@ if [ -z "${1-}" ]; then
exit 1
fi
# fetch available iOS Simulators
xcrun simctl list devices -j > "${XCRUN_SIMULATOR_JSON_FILE}"
SIMULATOR=${1}
# get the first available UDID for Simulators that match the name
read -r UDID SIMULATOR_STATE IS_AVAILABLE < <(jq --raw-output --arg simulator "${SIMULATOR}" '
[ .devices[] | .[] | select(.name == $simulator) ] |
map(select(.isAvailable)) + map(select(.isAvailable | not)) |
first |
"\(.udid) \(.state) \(.isAvailable)"
' "${XCRUN_SIMULATOR_JSON_FILE}")
# get our desired UUID
UUID=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk -F '[()]' '{print $2}')
if [ "${IS_AVAILABLE}" == false ] || [ "${UDID}" == null ]; then
echo "Error: Simulator ${SIMULATOR} is not available, Please find and install them."
echo "For help please refer"
echo "https://developer.apple.com/documentation/safari-developer-tools/adding-additional-simulators#Add-and-remove-Simulators " >&2
exit 1
fi
# get simulator status
SIMULATOR_STATE=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk '{print $NF}')
# sometimes a simulator is already running, shut it down to avoid errors
if [ "${SIMULATOR_STATE}" != "Shutdown" ]; then
xcrun simctl shutdown "${UDID}"
if [ "$SIMULATOR_STATE" != "(Shutdown)" ]; then
xcrun simctl shutdown "$UUID"
fi
# boot up iOS for simulator
xcrun simctl boot "${UDID}"
xcrun simctl boot "$UUID"
# start the simulator
open -a Simulator --args -CurrentDeviceUDID "${UDID}"
open -a Simulator --args -CurrentDeviceUDID "$UUID"
BUILD_DIR="${GIT_ROOT}/build"
#iOS build of debug scheme
xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${UDID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify
xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="$UUID" -derivedDataPath "${BUILD_DIR}" | xcbeautify
APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphonesimulator/StatusIm.app"
trap showXcrunLogs EXIT ERR INT QUIT
installAndLaunchApp &
exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1
# Install on the simulator
xcrun simctl install "$UUID" "$APP_PATH"
trap cleanupMetro EXIT ERR INT QUIT
runMetro &
waitForMetro
# launch the app when metro is ready
xcrun simctl launch "$UUID" im.status.ethereum.debug
# bring metro job to foreground
fg 'runMetro'
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
TIMEOUT=10 # Metro should not take this long to start.
while [ "${TIMEOUT}" -gt 0 ]; do
if ! lsof -i:8081 &> /dev/null; then
echo "."
sleep 1
((TIMEOUT--))
else
break
fi
done
@@ -1,6 +1,6 @@
(ns legacy.status-im.data-store.activities-test
(:require
[cljs.test :refer [deftest is]]
[cljs.test :refer [deftest is testing]]
[legacy.status-im.data-store.activities :as store]
[status-im.constants :as constants]
[status-im.contexts.shell.activity-center.notification-types :as notification-types]))
@@ -18,6 +18,89 @@
:name chat-name
:replyMessage {}})
(deftest <-rpc-test
(testing "renames keys"
(is (= {:name chat-name
:chat-id chat-id
:contact-verification-status constants/contact-verification-status-pending}
(-> raw-notification
store/<-rpc
(dissoc :last-message :message :reply-message)))))
(testing "transforms messages from RPC response"
(is
(= {:last-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:link-previews []
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}
:message nil
:reply-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:link-previews []
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}}
(-> raw-notification
store/<-rpc
(select-keys [:last-message :message :reply-message])))))
(testing "augments notification based on its type"
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/reply)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/mention)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:group-chat true
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/private-group-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/one-to-one-chat-type
:group-chat false
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/one-to-one-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))))
(deftest remove-pending-contact-request-test
(is (true? (store/pending-contact-request?
"contact-id"
@@ -4,6 +4,13 @@
[clojure.walk :as walk]
[status-im.constants :as constants]))
(defn rpc->channel-permissions
[rpc-channels-permissions]
(update-vals rpc-channels-permissions
(fn [{:keys [viewAndPostPermissions viewOnlyPermissions]}]
{:view-only (set/rename-keys viewOnlyPermissions {:satisfied :satisfied?})
:view-and-post (set/rename-keys viewAndPostPermissions {:satisfied :satisfied?})})))
(defn <-revealed-accounts-rpc
[accounts]
(mapv
@@ -27,9 +34,8 @@
(assoc acc
(name k)
(-> v
(assoc :token-gated? (:tokenGated v)
:can-post? (:canPost v))
(dissoc :canPost :tokenGated)
(assoc :can-post? (:canPost v))
(dissoc :canPost)
(update :members walk/stringify-keys))))
{}
chats))
@@ -0,0 +1,23 @@
(ns legacy.status-im.data-store.communities-test
(:require
[cljs.test :refer [deftest is]]
[legacy.status-im.data-store.communities :as sut]))
(def permissions
{"community-id-chat-1"
{:viewOnlyPermissions {:satisfied false
:permissions {:token-permission-id-01 {:criteria [false]}}}
:viewAndPostPermissions {:satisfied true :permissions {}}}
"community-id-chat-2"
{:viewOnlyPermissions {:satisfied true :permissions {}}
:viewAndPostPermissions {:satisfied true :permissions {}}}})
(deftest rpc->channel-permissions-test
(is (= {"community-id-chat-1"
{:view-only {:satisfied? false
:permissions {:token-permission-id-01 {:criteria [false]}}}
:view-and-post {:satisfied? true :permissions {}}}
"community-id-chat-2"
{:view-only {:satisfied? true :permissions {}}
:view-and-post {:satisfied? true :permissions {}}}}
(sut/rpc->channel-permissions permissions))))
@@ -53,14 +53,7 @@
:new :new?
:albumImagesCount :album-images-count
:displayName :display-name
:linkPreviews :link-previews
:statusLinkPreviews :status-link-previews
:bridgeMessage :bridge-message})
(update :bridge-message
set/rename-keys
{:bridgeName :bridge-name
:userName :user-name
:userAvatar :user-avatar})
:linkPreviews :link-previews})
(update :link-previews #(map <-link-preview-rpc %))
(update :quoted-message
set/rename-keys
@@ -21,7 +21,6 @@
:image nil
:response-to "a"
:links nil}
:bridge-message nil
:whisper-timestamp 1
:contact-verification-state 1
:contact-request-state 2
@@ -31,6 +31,7 @@
(let [key-uid (get-in db [:profile/profile :key-uid])]
(rf/merge cofx
{:set-root :progress
:chat.ui/clear-inputs nil
:effects.shell/reset-state nil
:hide-popover nil
::logout nil
@@ -53,7 +53,7 @@
:style {:color (colors/theme-colors colors/danger-50 colors/danger-60 theme)}}
error-message]])
(when (and (= description :top) role)
(when (= description :top)
[rn/view
{:style style/description-top}
[text/text
@@ -5,19 +5,19 @@
(h/describe "tests for markdown/list component"
(h/test "renders component with title"
(h/render-with-theme-provider [list/view {:title "test title"}])
(h/render [list/view {:title "test title"}])
(h/is-truthy (h/get-by-text "test title")))
(h/test "renders component with description"
(h/render-with-theme-provider [list/view
{:title "test title"
:description "test description"}])
(h/render [list/view
{:title "test title"
:description "test description"}])
(h/is-truthy (h/get-by-text "test description")))
(h/test "renders component with title and description"
(h/render-with-theme-provider [list/view
{:title "test title"
:description "test description"}])
(h/render [list/view
{:title "test title"
:description "test description"}])
(h/is-truthy (h/get-by-text "test title"))
(h/is-truthy (h/get-by-text "test description")))
@@ -29,11 +29,11 @@
(h/is-truthy (h/get-by-label-text :step-counter)))
(h/test "renders decription with a context tag component and description after the tag"
(h/render-with-theme-provider [list/view
{:step-number 1
:description "Lorem ipsum "
:tag-name "dolor"
:description-after-tag "text after tag"}])
(h/render [list/view
{:step-number 1
:description "Lorem ipsum "
:tag-name "dolor"
:description-after-tag "text after tag"}])
(h/is-truthy (h/get-by-text "Lorem ipsum"))
(h/is-truthy (h/get-by-label-text :user-avatar))
(h/is-truthy (h/get-by-text "dolor"))
@@ -32,7 +32,7 @@
"
[{:keys [icon new-notifications? notification-indicator counter-label
on-press pass-through? icon-color-anim accessibility-label test-ID
customization-color]
customization-color on-long-press]
:or {customization-color :blue}}]
(let [icon-animated-style (reanimated/apply-animations-to-style
{:tint-color icon-color-anim}
@@ -48,6 +48,7 @@
:border-radius 10})]
[rn/touchable-without-feedback
{:test-ID test-ID
:on-long-press on-long-press ;;NOTE - this is temporary while supporting old wallet
:allow-multiple-presses? true
:on-press on-press
:on-press-in #(toggle-background-color background-color false pass-through?)
@@ -12,47 +12,47 @@
(h/describe "Settings list tests"
(h/test "Default render of Setting list component"
(h/render-with-theme-provider [settings-item/view props])
(h/render [settings-item/view props])
(h/is-truthy (h/get-by-label-text :settings-item)))
(h/test "It renders a title"
(h/render-with-theme-provider [settings-item/view props])
(h/render [settings-item/view props])
(h/is-truthy (h/get-by-text "Account")))
(h/test "its gets passed an on press event"
(let [event (h/mock-fn)]
(h/render-with-theme-provider [settings-item/view
(merge props {:on-press event})])
(h/render [settings-item/view
(merge props {:on-press event})])
(h/fire-event :press (h/get-by-text "Account"))
(h/was-called event)))
(h/test "on change event gets fired for toggle"
(let [on-change (h/mock-fn)]
(h/render-with-theme-provider [settings-item/view
(merge props
{:action :selector
:action-props {:on-change on-change}})])
(h/render [settings-item/view
(merge props
{:action :selector
:action-props {:on-change on-change}})])
(h/fire-event :press (h/get-by-label-text :toggle-off))
(h/was-called on-change)))
(h/test "It renders a label"
(h/render-with-theme-provider [settings-item/view (merge props {:label :color})])
(h/render [settings-item/view (merge props {:label :color})])
(h/is-truthy (h/get-by-label-text :label-component)))
(h/test "It renders a status tag component"
(h/render-with-theme-provider [settings-item/view
(merge props
{:tag :context
:tag-props {:context "Test Tag"
:icon :i/placeholder}})])
(h/render [settings-item/view
(merge props
{:tag :context
:tag-props {:context "Test Tag"
:icon :i/placeholder}})])
(h/is-truthy (h/get-by-text "Test Tag")))
(h/test "on press event gets fired for button"
(let [event (h/mock-fn)]
(h/render-with-theme-provider [settings-item/view
(merge props
{:action :button
:action-props {:button-text "test button"
:on-press event}})])
(h/render [settings-item/view
(merge props
{:action :button
:action-props {:button-text "test button"
:on-press event}})])
(h/fire-event :press (h/get-by-text "test button"))
(h/was-called event))))
@@ -83,35 +83,35 @@
(h/is-truthy (h/get-by-label-text :gif)))
(h/test "Status: Read, Type: Audio, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :audio
:title "Title"
:content {:duration "00:32"}}])
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :audio
:title "Title"
:content {:duration "00:32"}}])
(h/is-truthy (h/get-by-text (utils/subtitle :audio nil)))
(h/is-truthy (h/get-by-text "00:32")))
(h/test "Status: Read, Type: Community, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :community
:title "Title"
:content {:community-avatar coinbase-community
:community-name "Coinbase"}}])
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :community
:title "Title"
:content {:community-avatar coinbase-community
:community-name "Coinbase"}}])
(h/is-truthy (h/get-by-text (utils/subtitle :community nil)))
(h/is-truthy (h/get-by-label-text :group-avatar))
(h/is-truthy (h/get-by-text "Coinbase")))
(h/test "Status: Read, Type: Link, Avatar: true"
(h/render-with-theme-provider [group-messaging-card/view
{:avatar true
:status :read
:type :link
:title "Title"
:content {:icon :placeholder
:text "Rolling St..."}}])
(h/render [group-messaging-card/view
{:avatar true
:status :read
:type :link
:title "Title"
:content {:icon :placeholder
:text "Rolling St..."}}])
(h/is-truthy (h/get-by-text (utils/subtitle :link nil)))
(h/is-truthy (h/get-by-label-text :group-avatar))
(h/is-truthy (h/get-by-text "Rolling St..."))))
@@ -1,103 +0,0 @@
(ns quo.components.tags.context-tag.schema
(:require [malli.core :as malli]))
(def ^:private ?context-base
[:map
[:type {:optional true}
[:maybe
[:enum :default :multiuser :group :channel :community :token :network :multinetwork :account
:collectible :address :icon :audio]]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:theme :schema.common/theme]
[:blur? {:optional true} [:maybe :boolean]]
[:state {:optional true} [:maybe [:enum :selected :default]]]])
(def ^:private ?size
[:map
[:size {:optional true} [:maybe [:enum 24 32]]]])
(def ^:private ?default
[:map
[:profile-picture {:optional true} [:maybe :schema.common/image-source]]
[:full-name {:optional true} [:maybe :string]]])
(def ^:private ?multiuser
[:map
[:users {:optional true}
[:maybe
[:sequential
[:map [:profile-picture {:optional true} [:maybe :schema.common/image-source]]
[:full-name {:optional true} [:maybe :string]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]]]])
(def ^:private ?group
[:map
[:group-name {:optional true} [:maybe :string]]])
(def ^:private ?channel
[:map
[:community-name {:optional true} [:maybe :string]]
[:channel-name {:optional true} [:maybe :string]]])
(def ^:private ?community
[:map
[:community-name {:optional true} [:maybe :string]]])
(def ^:private ?token
[:map
[:amount {:optional true} [:maybe [:or :string :int]]]
[:token {:optional true} [:maybe :string]]])
(def ^:private ?network
[:map
[:network-logo {:optional true} [:maybe :schema.common/image-source]]
[:network-name {:optional true} [:maybe :string]]])
(def ^:private ?multinetwork
[:map
[:networks {:optional true} [:maybe [:sequential ?network]]]])
(def ^:private ?account
[:map
[:account-name {:optional true} [:maybe :string]]
[:emoji {:optional true} [:maybe :string]]])
(def ^:private ?collectible
[:map
[:collectible {:optional true} [:maybe :schema.common/image-source]]
[:collectible-name {:optional true} [:maybe :string]]
[:collectible-number {:optional true} [:maybe [:or :string :int]]]])
(def ^:private ?address
[:map
[:address {:optional true} [:maybe :string]]])
(def ^:private ?icon
[:map
[:icon {:optional true} [:maybe :keyword]]
[:context {:optional true} [:maybe :string]]])
(def ^:private ?audio
[:map
[:duration {:optional true} [:maybe :string]]])
(def ?schema
[:=>
[:catn
[:props
[:multi {:dispatch :type}
[::malli/default [:merge ?default ?size ?context-base]]
[:default [:merge ?default ?size ?context-base]]
[:multiuser [:merge ?multiuser ?context-base]]
[:group [:merge ?group ?size ?context-base]]
[:channel [:merge ?channel ?size ?context-base]]
[:community [:merge ?community ?size ?context-base]]
[:token [:merge ?token ?size ?context-base]]
[:network [:merge ?network ?context-base]]
[:multinetwork [:merge ?multinetwork ?context-base]]
[:account [:merge ?account ?size ?context-base]]
[:collectible [:merge ?collectible ?size ?context-base]]
[:address [:merge ?address ?size ?context-base]]
[:icon [:merge ?icon ?size ?context-base]]
[:audio [:merge ?audio ?context-base]]]]]
:any])
+65 -5
View File
@@ -6,13 +6,11 @@
[quo.components.icon :as icons]
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.schema :as component-schema]
[quo.components.tags.context-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
[react-native.core :as rn]))
(defn- tag-skeleton
[{:keys [theme size text] :or {size 24}} logo-component]
@@ -159,5 +157,67 @@
nil)])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
"Properties:
type, state, blur? & customization-color
Depending on the `type` selected, different properties are accepted:
- `:default` or `nil`:
- size
- profile-picture
- full-name
- `:multiuser`:
- users (vector of {:profile-picture pic, :full-name \"a name\"})
- `:group`
- size
- group-name
- `:community`
- size
- community-logo (valid rn/image :source value)
- community-name
- `:channel`
- size
- community-logo (valid rn/image :source value)
- community-name
- channel-name
- `:token`
- size
- amount
- token
- `:network`
- size
- network-logo (valid rn/image :source value)
- network-name
- `:multinetworks`
- networks (vector of {:network-logo pic, :network-name \"a name\"})
- `:account`
- size
- account-name
- emoji (string containing an emoji)
- `:collectible`
- size
- collectible (valid rn/image :source value)
- collectible-name
- collectible-number
- `:address`
- size
- address (string)
- `:icon`
- size
- icon
- context (string)
- `:audio`
- duration (string)
"
(quo.theme/with-theme view-internal))
+9 -15
View File
@@ -27,19 +27,6 @@
:blurred-border-color colors/white-opa-10
:text-color {:style {:color colors/white}}}}})
(defn- emoji-comp
[size resource]
(let [dimension (case size
32 20
24 12
nil)]
(if (string? resource)
[rn/text {:style {:margin-right 4 :font-size dimension}}
resource]
[rn/image
{:source resource
:style {:margin-right 4 :width dimension :height dimension}}])))
(defn tag-resources
[size type resource icon-color label text-color labelled?]
[rn/view
@@ -60,7 +47,13 @@
24 12)
:color icon-color}])
(when (= type :emoji)
[emoji-comp size resource])
[text/text
{:style {:margin-right 4}
:size (case size
32 :paragraph-1
24 :paragraph-2
nil)}
resource])
(when labelled?
[text/text
(merge {:size (case size
@@ -80,7 +73,7 @@
:size 32/24
:on-press fn
:blurred? true/false
:resource icon/image/text(emojis)
:resource icon/image
:labelled? true/false
:disabled? true/false}
@@ -114,3 +107,4 @@
[tag-resources size type resource icon-color label text-color labelled?]]]))
(def tag (quo.theme/with-theme tag-internal))
@@ -37,26 +37,26 @@
(h/is-truthy (h/get-by-text "This is a textual description")))
(h/test "Context tag"
(h/render-with-theme-provider [page-top/view
{:title "Title"
:description :context-tag
:context-tag context-tag-data}])
(h/render [page-top/view
{:title "Title"
:description :context-tag
:context-tag context-tag-data}])
(h/is-truthy (h/get-by-text "Title"))
(h/is-truthy (h/get-by-label-text :context-tag)))
(h/test "Summary"
(h/render-with-theme-provider [page-top/view
{:title "Title"
:description :summary
:summary {:row-1 {:text-1 "Send"
:text-2 "from"
:context-tag-1 context-tag-data
:context-tag-2 context-tag-data}
:row-2 {:text-1 "to"
:text-2 "via"
:context-tag-1 context-tag-data
:context-tag-2 context-tag-data}}}])
(h/render [page-top/view
{:title "Title"
:description :summary
:summary {:row-1 {:text-1 "Send"
:text-2 "from"
:context-tag-1 context-tag-data
:context-tag-2 context-tag-data}
:row-2 {:text-1 "to"
:text-2 "via"
:context-tag-1 context-tag-data
:context-tag-2 context-tag-data}}}])
(h/is-truthy (h/get-by-text "Title"))
(h/is-truthy (h/get-by-text "Send"))
@@ -21,7 +21,6 @@
(defn view-internal
[{:keys [container-style
title
title-number-of-lines
avatar
title-accessibility-label
description
@@ -29,8 +28,7 @@
button-icon
button-on-press
customization-color
emoji-hash]
:or {title-number-of-lines 1}}]
emoji-hash]}]
[rn/view {:style container-style}
[rn/view
{:style {:flex-direction :row
@@ -43,7 +41,7 @@
{:accessibility-label title-accessibility-label
:weight :semi-bold
:ellipsize-mode :tail
:number-of-lines title-number-of-lines
:number-of-lines 1
:size :heading-1}
title]]
(when button-icon
+1 -1
View File
@@ -15,7 +15,7 @@
[:token {:optional true} [:maybe [:or keyword? string?]]]
[:style {:optional true} map?]
;; Ignores `token` and uses this as parameter to `rn/image`'s source.
[:image-source {:optional true} [:maybe :schema.common/image-source]]]]
[:image-source {:optional true} [:maybe [:or :schema.common/image-source :string]]]]]
:any])
(defn- size->number
@@ -9,7 +9,7 @@
(def ^:private ?default-keypair
[:map
[:user-name {:optional true} [:maybe :string]]
[:profile-picture {:optional true} [:maybe :schema.common/image-source]]
[:profile-picture {:optional true} [:maybe [:or :schema.common/image-source :string]]]
[:derivation-path {:optional true} [:maybe :string]]
[:on-press {:optional true} [:maybe fn?]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]])
@@ -1,5 +1,5 @@
(ns quo.components.wallet.account-permissions.schema
(:require [quo.components.wallet.required-tokens.schema :as required-tokens-schema]))
(:require [quo.components.wallet.required-tokens.view :as required-tokens]))
(def ?schema
[:=>
@@ -12,7 +12,7 @@
[:address [:maybe :string]]
[:emoji [:maybe :string]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]
[:token-details {:optional true} [:maybe [:sequential required-tokens-schema/?schema]]]
[:token-details {:optional true} [:maybe [:sequential required-tokens/?schema]]]
[:keycard? {:optional true} [:maybe :boolean]]
[:checked? {:optional true} [:maybe :boolean]]
[:disabled? {:optional true} [:maybe :boolean]]
@@ -1,11 +0,0 @@
(ns quo.components.wallet.network-amount.schema)
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:amount {:optional true} [:maybe :string]]
[:token {:optional true} [:or :keyword :string]]
[:theme :schema.common/theme]]]]
:any])
@@ -3,12 +3,21 @@
[clojure.string :as string]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.network-amount.schema :as network-amount-schema]
[quo.components.wallet.network-amount.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:amount {:optional true} [:maybe :string]]
[:token {:optional true} [:or :keyword :string]]
[:theme :schema.common/theme]]]]
:any])
(defn- view-internal
[{:keys [amount token theme]}]
[rn/view {:style style/container}
@@ -21,4 +30,4 @@
[rn/view
{:style (style/divider theme)}]])
(def view (quo.theme/with-theme (schema/instrument #'view-internal network-amount-schema/?schema)))
(def view (quo.theme/with-theme (schema/instrument #'view-internal ?schema)))
@@ -1,17 +0,0 @@
(ns quo.components.wallet.network-bridge.schema)
(def ^:private ?network-bridge-status
[:enum :add :loading :locked :disabled :default])
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:network {:optional true} [:maybe :keyword]]
[:status {:optional true} [:maybe ?network-bridge-status]]
[:amount {:optional true} [:maybe :string]]
[:container-style {:optional true} [:maybe :map]]
[:on-press {:optional true} [:maybe fn?]]]]]
:any])
@@ -3,7 +3,6 @@
[clojure.string :as string]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.wallet.network-bridge.schema :as network-bridge-schema]
[quo.components.wallet.network-bridge.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.resources :as resources]
@@ -26,6 +25,22 @@
(= network :ethereum) "Mainnet"
:else (string/capitalize (name network))))
(def ^:private ?network-bridge-status
[:enum :add :loading :locked :disabled :default])
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:network {:optional true} [:maybe :keyword]]
[:status {:optional true} [:maybe ?network-bridge-status]]
[:amount {:optional true} [:maybe :string]]
[:container-style {:optional true} [:maybe :map]]
[:on-press {:optional true} [:maybe fn?]]]]]
:any])
(defn view-internal
[{:keys [theme network status amount container-style on-press] :as args}]
(if (= status :add)
@@ -66,4 +81,4 @@
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal network-bridge-schema/?schema)))
(schema/instrument #'view-internal ?schema)))
@@ -1,14 +0,0 @@
(ns quo.components.wallet.network-link.schema)
(def ^:private ?networks [:enum :optimism :arbitrum :ethereum])
(def ?schema
[:=>
[:catn
[:props
[:map
[:shape {:optional true} [:maybe [:enum :linear :1x :2x]]]
[:source {:optional true} [:maybe ?networks]]
[:destination {:optional true} [:maybe ?networks]]
[:theme :schema.common/theme]]]]
:any])
@@ -1,11 +1,9 @@
(ns quo.components.wallet.network-link.view
(:require
[quo.components.wallet.network-link.schema :as component-schema]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.svg :as svg]
[schema.core :as schema]))
[react-native.svg :as svg]))
(defn link-linear
[{:keys [source theme]}]
@@ -86,6 +84,4 @@
:1x [link-1x props]
:2x [link-2x props])])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
(def view (quo.theme/with-theme view-internal))
@@ -1,17 +0,0 @@
(ns quo.components.wallet.network-routing.schema)
(def ?schema
[:=>
[:catn
[:props
[:map
[:networks {:optional true}
[:maybe
[:sequential
[:map
[:amount :int]
[:max-amount :int]
[:network-name [:or :string :keyword]]]]]]
[:container-style {:optional true} [:maybe :map]]
[:theme :schema.common/theme]]]]
:any])
@@ -2,7 +2,6 @@
(:require
[oops.core :as oops]
[quo.components.wallet.network-routing.animation :as animation]
[quo.components.wallet.network-routing.schema :as network-routing-schema]
[quo.components.wallet.network-routing.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
@@ -174,6 +173,22 @@
[rn/view {:style (style/max-limit-bar-background network-name)}]
[dashed-line network-name]])]))))
(def ?schema
[:=>
[:catn
[:props
[:map
[:networks {:optional true}
[:maybe
[:sequential
[:map
[:amount :int]
[:max-amount :int]
[:network-name [:or :string :keyword]]]]]]
[:container-style {:optional true} [:maybe :map]]
[:theme :schema.common/theme]]]]
:any])
(defn view-internal
[{:keys [networks container-style theme] :as params}]
(reagent/with-let [total-width (reagent/atom nil)]
@@ -190,4 +205,4 @@
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal network-routing-schema/?schema)))
(schema/instrument #'view-internal ?schema)))
@@ -1,12 +0,0 @@
(ns quo.components.wallet.progress-bar.schema)
(def ?schema
[:=>
[:catn
[:props
[:map
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:theme :schema.common/theme]
[:progressed-value {:optional true} [:maybe [:or :string :int]]]
[:full-width? {:optional true} [:maybe :boolean]]]]]
:any])
@@ -1,11 +1,21 @@
(ns quo.components.wallet.progress-bar.view
(:require
[quo.components.wallet.progress-bar.schema :as progress-bar-schema]
[quo.components.wallet.progress-bar.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:theme :schema.common/theme]
[:progressed-value {:optional true} [:maybe [:or :string :int]]]
[:full-width? {:optional true} [:maybe :boolean]]]]]
:any])
(defn- view-internal
[{:keys [full-width?] :as props}]
[rn/view
@@ -16,4 +26,4 @@
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal progress-bar-schema/?schema)))
(schema/instrument #'view-internal ?schema)))
@@ -1,17 +0,0 @@
(ns quo.components.wallet.required-tokens.schema)
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type [:enum :token :collectible]]
[:amount {:optional true} [:maybe [:or :string :int]]]
[:token {:optional true} [:maybe :string]]
[:token-img-src {:optional true} [:maybe :schema.common/image-source]]
[:collectible-img-src {:optional true} [:maybe :schema.common/image-source]]
[:collectible-name {:optional true} [:maybe :string]]
[:divider? {:optional true} [:maybe :boolean]]
[:theme :schema.common/theme]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
@@ -1,12 +1,27 @@
(ns quo.components.wallet.required-tokens.view
(:require [quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.required-tokens.schema :as required-tokens-schema]
[quo.components.wallet.required-tokens.style :as style]
quo.theme
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type [:enum :token :collectible]]
[:amount {:optional true} [:maybe [:or :string :int]]]
[:token {:optional true} [:maybe :string]]
[:token-img-src {:optional true} [:maybe :schema.common/image-source]]
[:collectible-img-src {:optional true} [:maybe :schema.common/image-source]]
[:collectible-name {:optional true} [:maybe :string]]
[:divider? {:optional true} [:maybe :boolean]]
[:theme :schema.common/theme]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [type amount token token-img-src collectible-img-src collectible-name divider? theme
container-style]}]
@@ -38,4 +53,4 @@
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal required-tokens-schema/?schema)))
(schema/instrument #'view-internal ?schema)))
@@ -1,13 +0,0 @@
(ns quo.components.wallet.summary-info.schema)
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:type [:enum :status-account :saved-account :account :user]]
[:account-props {:optional true} [:maybe :map]]
[:networks? {:optional true} [:maybe :boolean]]
[:values {:optional true} [:maybe :map]]]]]
:any])
@@ -4,7 +4,6 @@
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.markdown.text :as text]
[quo.components.wallet.summary-info.schema :as summary-info-schema]
[quo.components.wallet.summary-info.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.resources :as resources]
@@ -53,6 +52,18 @@
:amount (str (:amount arbitrum) " " (or (:token-symbol arbitrum) "ARB"))
:theme theme}])]))
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:type [:enum :status-account :saved-account :account :user]]
[:account-props {:optional true} [:maybe :map]]
[:networks? {:optional true} [:maybe :boolean]]
[:values {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [theme type account-props networks? values]}]
[rn/view
@@ -95,4 +106,4 @@
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal summary-info-schema/?schema)))
(schema/instrument #'view-internal ?schema)))
@@ -5,15 +5,15 @@
(h/describe "Wallet: Token Input"
(h/test "Token label renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
(h/render [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "SNT")))
(h/test "Amount renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
(h/render [token-input/view
{:token :snt
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "€0.00"))))
@@ -1,19 +0,0 @@
(ns quo.components.wallet.token-input.schema)
(def ?schema
[:=>
[:catn
[:props
[:map
[:token {:optional true} [:maybe :keyword]]
[:currency {:optional true} [:maybe :keyword]]
[:error? {:optional true} [:maybe :boolean]]
[:title {:optional true} [:maybe :string]]
[:conversion {:optional true} [:maybe :double]]
[:show-keyboard? {:optional true} [:maybe :boolean]]
[:networks {:optional true}
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:value {:optional true} [:maybe :string]]
[:theme :schema.common/theme]]]]
:any])
@@ -7,13 +7,11 @@
[quo.components.markdown.text :as text]
[quo.components.tags.network-tags.view :as network-tag]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.schema :as component-schema]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.common :as common]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]
[schema.core :as schema]))
[reagent.core :as reagent]))
(defn fiat-format
[currency num-value conversion]
@@ -151,6 +149,4 @@
:crypto? @crypto?
:amount (or value @value-atom))]]))))
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
(def view (quo.theme/with-theme view-internal))
@@ -1,25 +0,0 @@
(ns quo.components.wallet.transaction-progress.schema)
(def ^:private ?network
[:map
[:network {:optional true} [:maybe [:enum :mainnet :optimism :arbitrum]]]
[:state {:optional true} [:maybe [:enum :pending :sending :confirmed :finalising :finalized :error]]]
[:counter {:optional true} [:maybe :int]]
[:total-box {:optional true} [:maybe :int]]
[:epoch-number {:optional true} [:maybe :string]]
[:progress {:optional true} [:maybe :int]]])
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:title {:optional true} [:maybe :string]]
[:tag-name {:optional true} [:maybe :string]]
[:tag-number {:optional true} [:maybe [:or :string :int]]]
[:tag-photo {:optional true} [:maybe :schema.common/image-source]]
[:on-press {:optional true} [:maybe fn?]]
[:networks {:optional true} [:maybe [:sequential ?network]]]]]]
:any])
@@ -4,12 +4,10 @@
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.view :as context-tag]
[quo.components.wallet.confirmation-progress.view :as confirmation-progress]
[quo.components.wallet.transaction-progress.schema :as component-schema]
[quo.components.wallet.transaction-progress.style :as style]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]
[utils.i18n :as i18n]))
(def ^:private max-mainnet-verifications 4)
@@ -186,6 +184,4 @@
^{:key (:network network)}
[view-network (assoc-props (:network network))]))]])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
(def view (quo.theme/with-theme view-internal))
@@ -5,20 +5,24 @@
(h/describe "Transaction summary"
(h/test "default render"
(h/render-with-theme-provider [transaction-summary/view {}])
(h/render [transaction-summary/view {}])
(h/is-truthy (h/query-by-label-text :transaction-summary)))
(h/test "incorrect setting doesn't crash render"
(h/render [transaction-summary/view {:transaction :unknown}])
(h/is-truthy (h/query-by-label-text :transaction-summary)))
(h/test "icon displayed"
(h/render-with-theme-provider [transaction-summary/view {:transaction :send}])
(h/render [transaction-summary/view {:transaction :send}])
(h/is-truthy (h/query-by-label-text :header-icon)))
(h/test "Context tag rendered"
(h/render-with-theme-provider [transaction-summary/view
{:transaction :send
:first-tag {:size 24
:type :token
:token "SNT"
:amount 1500}}])
(h/render [transaction-summary/view
{:transaction :send
:first-tag {:size 24
:type :token
:token "SNT"
:amount 1500}}])
(h/is-truthy (h/query-by-label-text :context-tag))))
@@ -1,23 +0,0 @@
(ns quo.components.wallet.transaction-summary.schema
(:require [quo.components.tags.context-tag.schema :as context-tag-schema]))
(def ?schema
[:=>
[:catn
[:props
[:map
[:theme :schema.common/theme]
[:transaction {:optional true} [:maybe [:enum :send :swap :bridge]]]
[:first-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:second-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:third-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:fourth-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:fifth-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:second-tag-prefix {:optional true} [:maybe :keyword]]
[:third-tag-prefix {:optional true} [:maybe :keyword]]
[:fourth-tag-prefix {:optional true} [:maybe :keyword]]
[:max-fees {:optional true} [:maybe :string]]
[:nonce {:optional true} [:maybe :int]]
[:input-data {:optional true} [:maybe :string]]
[:on-press {:optional true} [:maybe fn?]]]]]
:any])
@@ -3,11 +3,9 @@
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.view :as context-tag]
[quo.components.wallet.transaction-summary.schema :as component-schema]
[quo.components.wallet.transaction-summary.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]
[utils.i18n :as i18n]))
(def transaction-translation
@@ -103,5 +101,24 @@
:theme theme}]]])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
"Properties:
- :transaction - type of transaction`. Possible values:
- :send
- :swap
- :bridge
- :first-tag - props for context tag component that will be first on the first line
- :second-tag - props for context tag component that will be second on the first line
- :third-tag - props for context tag component that will be first on the second line
- :fourth-tag - props for context tag component that will be second on the second line
- :fifth-tag - props for context tag component that will be second on the second line
- :second-tag-prefix - translation keyword to be used with label before second context tag
- :third-tag-prefix - translation keyword to be used with label before third context tag
- :fourth-tag-prefix - translation keyword to be used with label before fourth context tag
- :max-fees - string
- :nonce - digit
- :input data - string
"
(quo.theme/with-theme view-internal))
@@ -5,12 +5,12 @@
(h/describe "Wallet activity"
(h/test "default render"
(h/render-with-theme-provider [wallet-activity/view {}])
(h/render [wallet-activity/view {}])
(h/is-truthy (h/query-by-label-text :wallet-activity)))
(h/test "Should call :on-press"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider [wallet-activity/view {:on-press on-press}])
(h/render [wallet-activity/view {:on-press on-press}])
(h/is-truthy (h/query-by-label-text :wallet-activity))
(h/fire-event :press (h/query-by-label-text :wallet-activity))
(h/was-called on-press))))
@@ -1,24 +0,0 @@
(ns quo.components.wallet.wallet-activity.schema
(:require [quo.components.tags.context-tag.schema :as context-tag-schema]))
(def ?schema
[:=>
[:catn
[:props
[:map
[:transaction {:optional true} [:maybe [:enum :receive :send :swap :bridge :buy :destroy :mint]]]
[:status {:optional true} [:maybe [:enum :pending :confirmed :finalised :failed]]]
[:counter {:optional true} [:maybe :int]]
[:timestamp {:optional true} [:maybe :string]]
[:blur? {:optional true} [:maybe :boolean]]
[:on-press {:optional true} [:maybe fn?]]
[:state {:optional true} [:maybe [:= :disabled]]]
[:theme :schema.common/theme]
[:second-tag-prefix {:optional true} [:maybe :keyword]]
[:third-tag-prefix {:optional true} [:maybe :keyword]]
[:fourth-tag-prefix {:optional true} [:maybe :keyword]]
[:first-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:second-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:third-tag {:optional true} [:maybe context-tag-schema/?schema]]
[:fourth-tag {:optional true} [:maybe context-tag-schema/?schema]]]]]
:any])
@@ -3,13 +3,11 @@
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.view :as context-tag]
[quo.components.wallet.wallet-activity.schema :as component-schema]
[quo.components.wallet.wallet-activity.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[reagent.core :as reagent]
[schema.core :as schema]
[utils.i18n :as i18n]))
(def transaction-translation
@@ -134,5 +132,35 @@
(when fourth-tag [prop-tag fourth-tag blur?])]]]])))
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
"Properties:
- :transaction - type of transaction`. Possible values:
- :receive
- :send
- :swap
- :bridge
- :buy
- :destroy
- :mint
- :status - transaction status. Possible values:
- :pending
- :confirmed
- :finalised
- :failed
- :counter - amount of transactions shown by instance of the component
- :timestamp - when transaction occured (string)
- :blur?
- :first-tag - props for context tag component that will be first on the first line
- :second-tag - props for context tag component that will be second on the first line
- :third-tag - props for context tag component that will be first on the second line
- :fourth-tag - props for context tag component that will be second on the second line
- :second-tag-prefix - translation keyword to be used with label before second context tag
- :third-tag-prefix - translation keyword to be used with label before third context tag
- :fourth-tag-prefix - translation keyword to be used with label before fourth context tag
"
(quo.theme/with-theme view-internal))
@@ -6,9 +6,9 @@
(h/describe
"Wallet overview test"
(h/test "renders correct balance"
(h/render-with-theme-provider [wallet-overview/view
{:state :default
:time-frame :one-week
:metrics :positive
:balance "€0.01"}])
(h/render [wallet-overview/view
{:state :default
:time-frame :one-week
:metrics :positive
:balance "€0.01"}])
(h/is-truthy (h/get-by-text "€0.01"))))
@@ -1,23 +0,0 @@
(ns quo.components.wallet.wallet-overview.schema)
(def ?schema
[:=>
[:catn
[:props
[:map
[:state {:optional true} [:maybe [:enum :default :loading]]]
[:time-frame {:optional true}
[:maybe [:enum :none :selected :one-week :one-month :three-months :one-year :all-time :custom]]]
[:metrics {:optional true} [:maybe [:enum :none :negative :positive]]]
[:balance {:optional true} [:maybe :string]]
[:date {:optional true} [:maybe :string]]
[:begin-date {:optional true} [:maybe :string]]
[:end-date {:optional true} [:maybe :string]]
[:currency-change {:optional true} [:maybe :string]]
[:percentage-change {:optional true} [:maybe :string]]
[:theme :schema.common/theme]
[:dropdown-on-press {:optional true} [:maybe fn?]]
[:networks {:optional true}
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
[:dropdown-state {:optional true} [:maybe [:enum :default :disabled]]]]]]
:any])
@@ -3,11 +3,9 @@
[quo.components.dropdowns.network-dropdown.view :as network-dropdown]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.wallet.wallet-overview.schema :as component-schema]
[quo.components.wallet.wallet-overview.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]
[utils.i18n :as i18n]))
(def ^:private time-frames
@@ -119,5 +117,4 @@
[view-info-bottom props]])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal component-schema/?schema)))
(quo.theme/with-theme view-internal))
+1 -2
View File
@@ -13,8 +13,7 @@
(def ^:private ?image-source
[:or
:int
:string
[:int]
[:map
[:uri [:maybe [:string]]]]])
@@ -4,6 +4,7 @@
[quo.theme :as theme]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
@@ -57,8 +58,7 @@
(set-animating-true)
(reanimated/animate translate-y height 300)
(reanimated/animate opacity 0 300)
(rf/dispatch [:navigate-back])
true)
(rf/dispatch [:navigate-back]))
reset-open-sheet (fn []
(reanimated/animate translate-y 0 300)
(reanimated/animate opacity 1 300)
@@ -66,11 +66,10 @@
(reset! scroll-enabled? true))]
(rn/use-effect
(fn []
(rn/hw-back-add-listener close)
(reanimated/animate translate-y 0 300)
(reanimated/animate opacity 1 300)
(set-animating-false 300)
#(rn/hw-back-remove-listener close)))
(set-animating-false 300)))
(hooks/use-back-handler close)
[rn/view {:style (style/container insets)}
(when-not skip-background?
[reanimated/view {:style (style/background opacity)}])
@@ -88,7 +87,7 @@
[content
{:insets insets
:close close
:scroll-enabled? scroll-enabled?
:scroll-enabled? @scroll-enabled?
:current-scroll curr-scroll
:on-scroll #(on-scroll % curr-scroll)
:sheet-animating? animating?}]]]]))))
+1 -1
View File
@@ -98,7 +98,7 @@
on-select set-scroll-ref close sheet-animating?]}]
[gesture/flat-list
{:ref set-scroll-ref
:scroll-enabled @scroll-enabled?
:scroll-enabled scroll-enabled?
:data (or filtered-data emoji-picker.data/flatten-data)
:initial-num-to-render 14
:max-to-render-per-batch 10
@@ -7,7 +7,6 @@
[react-native.core :as rn]
[status-im.common.standard-authentication.forgot-password-doc.view :as forgot-password-doc]
[status-im.common.standard-authentication.password-input.style :as style]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
@@ -23,10 +22,9 @@
(defn- on-change-password
[entered-password]
(debounce/debounce-and-dispatch [:profile/on-password-input-changed
{:password (security/mask-data entered-password)
:error ""}]
100))
(rf/dispatch [:set-in [:profile/login :password]
(security/mask-data entered-password)])
(rf/dispatch [:set-in [:profile/login :error] ""]))
(defn- view-internal
[{:keys [default-password theme shell? on-press-biometrics blur?]}]
-1
View File
@@ -19,7 +19,6 @@
(def ^:const content-type-system-message-mutual-event-sent 15)
(def ^:const content-type-system-message-mutual-event-accepted 16)
(def ^:const content-type-system-message-mutual-event-removed 17)
(def ^:const content-type-bridge-message 18)
;; Not implemented in status-go, only used for testing/ui work
(def ^:const content-type-gif 100)
@@ -105,7 +105,7 @@
:render-section-header-fn contact-list/contacts-section-header
:content-container-style {:padding-bottom 70}
:render-fn contact-item-render
:scroll-enabled @scroll-enabled?
:scroll-enabled scroll-enabled?
:on-scroll on-scroll}])
(when contacts-selected?
[quo/button
@@ -182,7 +182,8 @@
(defn open-photo-selector
[{:keys [input-ref]}
{:keys [height]}]
{:keys [height]}
insets]
(permissions/request-permissions
{:permissions [(if platform/is-below-android-13? :read-external-storage :read-media-images)
:write-external-storage]
@@ -191,18 +192,18 @@
(.blur ^js @input-ref))
(rf/dispatch [:chat.ui/set-input-content-height
(reanimated/get-shared-value height)])
(rf/dispatch [:photo-selector/navigate-to-photo-selector]))
(rf/dispatch [:open-modal :photo-selector {:insets insets}]))
:on-denied (fn []
(alert.effects/show-popup (i18n/label :t/error)
(i18n/label
:t/external-storage-denied)))}))
(defn image-button
[props animations edit]
[props animations insets edit]
[quo/composer-button
{:on-press (if edit
#(js/alert "This feature is temporarily unavailable in edit mode.")
#(open-photo-selector props animations))
#(open-photo-selector props animations insets))
:accessibility-label :open-images-button
:container-style {:margin-right 12}
:icon :i/image}])
@@ -227,7 +228,7 @@
:icon :i/format}])
(defn view
[props state animations window-height {:keys [edit images]}]
[props state animations window-height insets {:keys [edit images]}]
(let [send-btn-opacity (reanimated/use-shared-value 0)
audio-btn-opacity (reanimated/interpolate send-btn-opacity [0 1] [1 0])]
[rn/view {:style style/actions-container}
@@ -235,7 +236,7 @@
{:style {:flex-direction :row
:display (if @(:recording? state) :none :flex)}}
[camera-button edit]
[image-button props animations edit]
[image-button props animations insets edit]
[reaction-button]
[format-button]]
[:f> send-button props state animations window-height images edit send-btn-opacity]
@@ -142,7 +142,7 @@
[gradients/view props state animations show-bottom-gradient?]
[link-preview/view]
[images/images-list]]
[:f> actions/view props state animations window-height subscriptions]]]]]))
[:f> actions/view props state animations window-height insets subscriptions]]]]]))
(defn f-composer
[props]
@@ -1,12 +1,10 @@
(ns status-im.contexts.chat.messenger.messages.content.view
(:require
[clojure.string :as string]
[legacy.status-im.ui.screens.chat.message.legacy-view :as old-message]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[reagent.core :as reagent]
@@ -115,34 +113,6 @@
constants/content-type-system-message-mutual-event-sent
[system-message-contact-request message-data :contact-request])))
(defn bridge-message-content
[{:keys [bridge-message timestamp]}]
(let [{:keys [user-avatar user-name
bridge-name content]} bridge-message
user-name (when (string? user-name)
(-> user-name
(string/replace "<b>" "")
(string/replace "</b>" "")))]
[rn/view
{:style {:flex-direction :row
:padding-horizontal 12
:padding-top 4}}
[fast-image/fast-image
{:source {:uri user-avatar}
:style {:width 32
:margin-top 4
:border-radius 16
:height 32}}]
[rn/view {:margin-left 8 :flex 1}
[quo/author
{:primary-name (str user-name)
:short-chat-key (str "Bridged from " bridge-name)
:time-str (datetime/timestamp->time timestamp)}]
[quo/text
{:size :paragraph-1
:style {:line-height 22.75}}
content]]]))
(declare on-long-press)
(defn- user-message-content-internal
@@ -314,9 +284,6 @@
keyboard-shown?))
context]
(= content-type constants/content-type-bridge-message)
[bridge-message-content message-data]
:else
[user-message-content
{:message-data message-data
@@ -87,7 +87,7 @@
:content-container-style {:padding-top 64
:padding-bottom 40}
:key-fn key-fn
:scroll-enabled @scroll-enabled?
:scroll-enabled scroll-enabled?
:on-scroll on-scroll
:style {:height window-height}}]]))
@@ -1,6 +1,5 @@
(ns status-im.contexts.chat.messenger.photo-selector.events
(:require
[re-frame.core :as re-frame]
[status-im.constants :as constants]
status-im.contexts.chat.messenger.photo-selector.effects
[utils.i18n :as i18n]
@@ -75,9 +74,3 @@
(when (and (< (count images) constants/max-album-photos)
(not (some #(= (:uri image) (:uri %)) images)))
{:effects.camera-roll/image-selected [image current-chat-id]})))
(re-frame/reg-event-fx :photo-selector/navigate-to-photo-selector
(fn []
{:fx [[:dispatch [:open-modal :photo-selector]]
[:dispatch [:photo-selector/get-photos-for-selected-album]]
[:dispatch [:photo-selector/camera-roll-get-albums]]]}))
@@ -70,14 +70,13 @@
(let [customization-color (rf/sub [:profile/customization-color])
item-selected? (some #(= (:uri item) (:uri %)) @selected)]
[rn/touchable-opacity
{:on-press (fn []
(if item-selected?
(swap! selected remove-selected item)
(if (>= (count @selected) constants/max-album-photos)
(show-photo-limit-toast)
(swap! selected conj item))))
:allow-multiple-presses? true
:accessibility-label (str "image-" index)}
{:on-press (fn []
(if item-selected?
(swap! selected remove-selected item)
(if (>= (count @selected) constants/max-album-photos)
(show-photo-limit-toast)
(swap! selected conj item))))
:accessibility-label (str "image-" index)}
[rn/image
{:source {:uri (:uri item)}
:style (style/image window-width index)}]
@@ -92,6 +91,8 @@
(defn photo-selector
[{:keys [scroll-enabled? on-scroll current-scroll close] :as sheet}]
(rf/dispatch [:photo-selector/get-photos-for-selected-album])
(rf/dispatch [:photo-selector/camera-roll-get-albums])
(let [album? (reagent/atom false)
customization-color (rf/sub [:profile/customization-color])
sending-image (into [] (vals (rf/sub [:chats/sending-image])))
@@ -133,7 +134,7 @@
:padding-bottom (+ (safe-area/get-bottom) 100)
:padding-top 64}
:on-scroll on-scroll
:scroll-enabled @scroll-enabled?
:scroll-enabled scroll-enabled?
:on-end-reached (fn []
(when (and (not loading?) has-next-page?)
(rf/dispatch [:photo-selector/camera-roll-loading-more true])
@@ -1,3 +1,16 @@
(ns status-im.contexts.communities.actions.addresses-for-permissions.style)
(def container {:flex 1})
(def buttons
{:flex-direction :row
:gap 12
:padding-horizontal 20
:padding-vertical 12})
(def highest-role
{:flex-direction :row
:gap 4
:justify-content :center
:align-items :center
:margin-bottom 8})
@@ -1,24 +1,17 @@
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
(:require [quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[status-im.common.not-implemented :as not-implemented]
[status-im.common.resources :as resources]
[status-im.constants :as constants]
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
[status-im.contexts.communities.utils :as communities.utils]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.re-frame :as rf]))
(defn- role-keyword
[role]
(condp = role
constants/community-token-permission-become-token-owner :token-owner
constants/community-token-permission-become-token-master :token-master
constants/community-token-permission-become-admin :admin
constants/community-token-permission-become-member :member
nil))
(defn- balances->components-props
[balances]
(for [{:keys [amount decimals type name] :as balance} balances]
@@ -61,12 +54,14 @@
(rf/dispatch [:communities/get-permissioned-balances id])
(fn []
(let [{:keys [name color images]} (rf/sub [:communities/community id])
{:keys [checking?
highest-permission-role]} (rf/sub [:community/token-gated-overview id])
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
accounts (rf/sub [:wallet/accounts-without-watched-accounts])
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
share-all-addresses? (rf/sub [:communities/share-all-addresses? id])
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])]
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])
highest-role-text (when highest-permission-role
(i18n/label (communities.utils/role->translation-key
highest-permission-role)))]
[rn/safe-area-view {:style style/container}
[quo/drawer-top
{:type :context-tag
@@ -97,38 +92,47 @@
:share-all-addresses? share-all-addresses?
:community-color color}
:content-container-style {:padding-horizontal 20}
:scroll-enabled @scroll-enabled?
:scroll-enabled scroll-enabled?
:on-scroll on-scroll
:key-fn :address
:data accounts}]
[quo/bottom-actions
{:actions :two-actions
:button-one-label (i18n/label :t/confirm-changes)
:button-one-props {:customization-color color
:disabled? (or checking?
(empty? selected-addresses)
(not highest-permission-role)
(not unsaved-address-changes?))
:on-press (fn []
(rf/dispatch
[:communities/update-previous-permission-addresses
id])
(rf/dispatch [:navigate-back]))}
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press (fn []
(rf/dispatch
[:communities/reset-selected-permission-addresses id])
(rf/dispatch [:navigate-back]))}
:description (if (or (empty? selected-addresses)
(not highest-permission-role))
:top-error
:top)
:role (when-not checking? (role-keyword highest-permission-role))
:error-message (cond
(empty? selected-addresses) (i18n/label :t/no-addresses-selected)
(not highest-permission-role) (i18n/label
:t/addresses-dont-contain-tokens-needed)
:else nil)}]]))))
(if (and highest-permission-role (seq selected-addresses))
[rn/view
{:style style/highest-role}
[quo/text
{:size :paragraph-2
:style {:color colors/neutral-50}}
(i18n/label :t/eligible-to-join-as)]
[quo/context-tag
{:type :icon
:icon :i/members
:size 24
:context highest-role-text}]]
[quo/info-message
{:type :error
:size :default
:icon :i/info
:style {:justify-content :center}}
(if (empty? selected-addresses)
(i18n/label :t/no-addresses-selected)
(i18n/label :t/addresses-dont-contain-tokens-needed))])
[rn/view {:style style/buttons}
[quo/button
{:type :grey
:container-style {:flex 1}
:on-press (fn []
(rf/dispatch [:communities/reset-selected-permission-addresses id])
(rf/dispatch [:navigate-back]))}
(i18n/label :t/cancel)]
[quo/button
{:container-style {:flex 1}
:customization-color color
:disabled? (or (empty? selected-addresses)
(not highest-permission-role)
(not unsaved-address-changes?))
:on-press (fn []
(rf/dispatch [:communities/update-previous-permission-addresses id])
(rf/dispatch [:navigate-back]))}
(i18n/label :t/confirm-changes)]]]))))
@@ -14,7 +14,6 @@
:canManageUsers :can-manage-users?
:categoryID :category-id
:canPost :can-post?
:tokenGated :token-gated?
:isControlNode :is-control-node?
:pinMessageAllMembersEnabled :pin-message-all-members-enabled
:isMember :is-member?
+19 -22
View File
@@ -21,8 +21,7 @@
(defn handle-community
[{:keys [db]} [community-js]]
(when community-js
(let [{:keys [clock
token-permissions
(let [{:keys [token-permissions
token-permissions-check joined id]
:as community} (data-store.communities/<-rpc community-js)
has-channel-perm? (fn [id-perm-tuple]
@@ -31,15 +30,16 @@
(=
type
constants/community-token-permission-can-view-and-post-channel))))]
(when (> clock (get-in db [:communities id :clock]))
{:db (assoc-in db [:communities id] community)
:fx [[:dispatch [:communities/initialize-permission-addresses id]]
(when (not joined)
[:dispatch [:chat.ui/spectate-community id]])
(when (nil? token-permissions-check)
[:dispatch [:communities/check-permissions-to-join-community id]])
(when joined
[:dispatch [:communities/get-revealed-accounts id]])]}))))
{:db (assoc-in db [:communities id] community)
:fx [[:dispatch [:communities/initialize-permission-addresses id]]
(when (not joined)
[:dispatch [:chat.ui/spectate-community id]])
(when (nil? token-permissions-check)
[:dispatch [:communities/check-permissions-to-join-community id]])
(when (some has-channel-perm? token-permissions)
[:dispatch [:communities/check-all-community-channels-permissions id]])
(when joined
[:dispatch [:communities/get-revealed-accounts id]])]})))
(rf/reg-event-fx :communities/handle-community handle-community)
@@ -223,19 +223,16 @@
(defn toggle-share-all-addresses
[{:keys [db]} [community-id]]
(let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?])
next-share-all-addresses? (not share-all-addresses?)
accounts (utils/sorted-non-watch-only-accounts db)
addresses (set (map :address accounts))]
(let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?])
accounts (utils/sorted-non-watch-only-accounts db)
addresses (set (map :address accounts))]
{:db (update-in db
[:communities community-id]
assoc
:share-all-addresses? next-share-all-addresses?
:selected-permission-addresses addresses)
:fx [(when (and community-id next-share-all-addresses?)
[:dispatch
[:communities/check-permissions-to-join-community community-id
addresses :based-on-client-selection]])]}))
(fn [community]
(-> community
(assoc :share-all-addresses? (not share-all-addresses?))
(cond-> (not share-all-addresses?)
(assoc :selected-permission-addresses addresses)))))}))
(rf/reg-event-fx :communities/toggle-share-all-addresses
toggle-share-all-addresses)
@@ -2,6 +2,7 @@
(:require [cljs.test :refer [deftest is testing]]
[legacy.status-im.mailserver.core :as mailserver]
matcher-combinators.test
[status-im.constants :as constants]
[status-im.contexts.chat.messenger.messages.link-preview.events :as link-preview.events]
[status-im.contexts.communities.events :as events]))
@@ -73,8 +74,8 @@
:position 1}}}
:communities {community-id {:share-all-addresses? true
:previous-share-all-addresses? true
:previous-permission-addresses #{"0x1" "0x2"}
:selected-permission-addresses #{"0x1" "0x2"}
:previous-permission-addresses #{"0x1"}
:selected-permission-addresses #{"0x1"}
:airdrop-address "0x1"}}}}
expected-db (update-in initial-db
[:db :communities community-id]
@@ -258,7 +259,7 @@
(-> effects :json-rpc/call first (select-keys [:method :params]))))))))
(deftest handle-community
(let [community {:id community-id :clock 2}]
(let [community {:id community-id}]
(testing "given a unjoined community"
(let [effects (events/handle-community {} [community])]
(is (match? community-id
@@ -283,10 +284,29 @@
[[:dispatch [:communities/initialize-permission-addresses community-id]]
[:dispatch [:chat.ui/spectate-community community-id]]]
(filter some? (:fx effects))))))
(testing "given a community with lower clock"
(let [effects (events/handle-community {:db {:communities {community-id {:clock 3}}}} [community])]
(is (nil? effects))))
(testing "given a community without clock"
(let [community (dissoc community :clock)
(testing "given a community with view channel permission"
(let [community (assoc community
:token-permissions
[["perm-id" {:type constants/community-token-permission-can-view-channel}]])
effects (events/handle-community {} [community])]
(is (nil? effects))))))
(is (match?
[[:dispatch [:communities/initialize-permission-addresses community-id]]
[:dispatch [:chat.ui/spectate-community community-id]]
[:dispatch [:communities/check-permissions-to-join-community community-id]]
[:dispatch
[:communities/check-all-community-channels-permissions community-id]]]
(filter some? (:fx effects))))))
(testing "given a community with post in channel permission"
(let [community (assoc community
:token-permissions
[["perm-id"
{:type constants/community-token-permission-can-view-and-post-channel}]])
effects (events/handle-community {} [community])]
(is (match?
[[:dispatch [:communities/initialize-permission-addresses community-id]]
[:dispatch [:chat.ui/spectate-community community-id]]
[:dispatch [:communities/check-permissions-to-join-community community-id]]
[:dispatch
[:communities/check-all-community-channels-permissions community-id]]]
(filter some? (:fx effects))))))))
@@ -1,10 +1,37 @@
(ns status-im.contexts.communities.overview.events
(:require
[legacy.status-im.data-store.communities :as data-store]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/reg-event-fx :communities/check-all-community-channels-permissions-success
(fn [{:keys [db]} [community-id response]]
{:db (-> db
(assoc-in [:community-channels-permissions community-id]
(data-store/rpc->channel-permissions (:channels response)))
(assoc-in [:communities/channel-permissions-check community-id] false))}))
(rf/reg-event-fx :communities/check-all-community-channels-permissions-failed
(fn [{:keys [db]} [community-id]]
{:db (assoc-in db [:communities/channel-permissions-check community-id] false)}))
(rf/reg-event-fx :communities/check-all-community-channels-permissions
(fn [{:keys [db]} [community-id]]
(when (get-in db [:communities community-id])
{:db (assoc-in db [:communities/channel-permissions-check community-id] true)
:fx [[:json-rpc/call
[{:method "wakuext_checkAllCommunityChannelsPermissions"
:params [{:CommunityID community-id}]
:on-success [:communities/check-all-community-channels-permissions-success community-id]
:on-error (fn [error]
(rf/dispatch [:communities/check-all-community-channels-permissions-failed
community-id])
(log/error "failed to check channels permissions"
{:error error
:community-id community-id
:event
:communities/check-all-community-channels-permissions}))}]]]})))
(rf/reg-event-fx :communities/check-permissions-to-join-community-success
(fn [{:keys [db]} [community-id based-on-client-selection? result]]
@@ -48,16 +48,15 @@
:emoji emoji
:customization-color community-color
:mentions-count mentions-count
;; NOTE: this is a troolean, nil/true/false have different meaning
:locked? locked?
:notification notification}
channel-sheet-data {:selected-item (fn [] [quo/channel channel-options])
:content (fn [] sheet-content)}]
[rn/view {:key id}
[quo/channel
(assoc channel-options
:on-press on-press
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data]))]]))
(merge channel-options
{:on-press on-press
:on-long-press #(rf/dispatch [:show-bottom-sheet channel-sheet-data])})]]))
(defn- channel-list-component
[{:keys [on-category-layout community-id community-color on-first-channel-height-changed]}
@@ -72,7 +71,7 @@
{:key category-id
;; on-layout fires only when the component re-renders, so
;; in case the category hasn't changed, it will not be fired
:on-layout #(on-category-layout name category-id (int (layout-y %)))}
:on-layout #(on-category-layout name (int (layout-y %)))}
(when-not (= constants/empty-category-id category-id)
[quo/divider-label
{:on-press #(collapse-category community-id category-id collapsed?)
@@ -239,22 +238,23 @@
(defn- community-header
[title logo description]
[quo/text-combinations
{:container-style {:margin-top
(if logo
12
(+ scroll-page.style/picture-radius
scroll-page.style/picture-border-width
12))
:margin-bottom 12}
:avatar logo
:title title
:title-number-of-lines 2
:description description
:title-accessibility-label :community-title
{:container-style
{:margin-top
(if logo
12
(+ scroll-page.style/picture-radius
scroll-page.style/picture-border-width
12))
:margin-bottom 12}
:avatar logo
:title title
:description description
:title-accessibility-label :community-title
:description-accessibility-label :community-description}])
(defn- community-content
[_]
[id]
(rf/dispatch [:communities/check-all-community-channels-permissions id])
(fn [id
{:keys [on-category-layout
collapsed?
@@ -328,14 +328,10 @@
(swap! categories-heights select-keys categories)
(reset! first-channel-height height))]
(fn [id joined name images]
(let [cover {:uri (get-in images [:banner :uri])}
logo {:uri (get-in images [:thumbnail :uri])}
collapsed? (and initial-joined? joined)
first-category-height (->> @categories-heights
vals
(apply min)
(+ @first-channel-height))
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))]
(let [cover {:uri (get-in images [:banner :uri])}
logo {:uri (get-in images [:thumbnail :uri])}
collapsed? (and initial-joined? joined)
overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))]
[scroll-page/scroll-page
{:cover-image cover
:collapsed? collapsed?
@@ -351,8 +347,7 @@
:community-name name
:community-logo logo}
:sticky-header [sticky-category-header
{:enabled (> @scroll-height
first-category-height)
{:enabled (> @scroll-height @first-channel-height)
:label (pick-first-category-by-height
@scroll-height
@first-channel-height
@@ -15,15 +15,15 @@
:community-icon (resources/get-mock-image :status-logo)
:customization-color :blue
:tokens [{:id 1 :group [{:id 1 :token-icon (resources/get-mock-image :status-logo)}]}]
:tags [{:id 1
:name (i18n/label :t/music)
:emoji (resources/get-image :music)}
{:id 2
:name (i18n/label :t/lifestyle)
:emoji "🧩"}
{:id 3
:name (i18n/label :t/podcasts)
:emoji "🎶"}]})
:tags [{:id 1
:tag-label (i18n/label :t/music)
:emoji (resources/get-image :music)}
{:id 2
:tag-label (i18n/label :t/lifestyle)
:emoji (resources/get-image :lifestyle)}
{:id 3
:tag-label (i18n/label :t/podcasts)
:emoji (resources/get-image :podcasts)}]})
(def descriptor
[{:key :status
@@ -135,6 +135,8 @@
[]
(let [state (reagent/atom
{:title "Title"
:counter 40
:total-box total-box
:tag-name "Doodle"
:tag-number "120"
:epoch-number-mainnet "181,329"
@@ -247,8 +247,3 @@
#(-> %
(dissoc :processing)
(assoc :error "Invalid password")))}))
(re-frame/reg-event-fx
:profile/on-password-input-changed
(fn [{:keys [db]} [{:keys [password error]}]]
{:db (update db :profile/login assoc :password password :error error)}))
@@ -172,29 +172,13 @@
[props]
[:f> f-profiles-section props])
(defn password-input
[]
(let [password (rf/sub [:profile/login-password])
auth-method (rf/sub [:auth-method])]
[standard-authentication/password-input
{:shell? true
:blur? true
:on-press-biometrics (when (= auth-method constants/auth-method-biometric)
(fn []
(rf/dispatch [:biometric/authenticate
{:on-success #(rf/dispatch
[:profile.login/biometric-success])
:on-fail #(rf/dispatch
[:profile.login/biometric-auth-fail
%])}])))
:default-password password}]))
(defn login-section
[{:keys [set-show-profiles]}]
(let [processing (rf/sub [:profile/login-processing])
(let [{:keys [processing password]} (rf/sub [:profile/login])
{:keys [key-uid name customization-color]} (rf/sub [:profile/login-profile])
sign-in-enabled? (rf/sub [:sign-in-enabled?])
profile-picture (rf/sub [:profile/login-profiles-picture key-uid])
auth-method (rf/sub [:auth-method])
login-multiaccount #(rf/dispatch [:profile.login/login])]
[rn/keyboard-avoiding-view
{:style style/login-container
@@ -229,7 +213,18 @@
:customization-color (or customization-color :primary)
:profile-picture profile-picture
:card-style style/login-profile-card}]
[password-input]]
[standard-authentication/password-input
{:shell? true
:blur? true
:on-press-biometrics (when (= auth-method constants/auth-method-biometric)
(fn []
(rf/dispatch [:biometric/authenticate
{:on-success #(rf/dispatch
[:profile.login/biometric-success])
:on-fail #(rf/dispatch
[:profile.login/biometric-auth-fail
%])}])))
:default-password password}]]
[quo/button
{:size 40
:type :primary
@@ -15,10 +15,12 @@
(defn navigate-back-handler
[]
(when (and (not @navigation.state/curr-modal)
(seq (utils/open-floating-screens)))
(rf/dispatch [:navigate-back])
true))
(if (and (not @navigation.state/curr-modal)
(seq (utils/open-floating-screens)))
(do
(rf/dispatch [:navigate-back])
true)
false))
(defn floating-button
[shared-values]
@@ -3,9 +3,13 @@
[status-im.contexts.wallet.create-account.edit-derivation-path.view :as edit-derivation-path]
[test-helpers.component :as h]))
(defn- render
[component]
(h/render-with-theme-provider component :light))
(h/describe "Edit derivation path page"
(h/test "Default render"
(h/render-with-theme-provider [edit-derivation-path/view {}])
(render [edit-derivation-path/view {}])
(h/is-truthy (h/get-by-translation-text :t/edit-derivation-path))
(h/is-truthy (h/get-by-translation-text :t/path-format))
(h/is-truthy (h/get-by-translation-text :t/derivation-path))
@@ -15,14 +19,14 @@
(h/test "Reveal address pressed"
(let [on-reveal (h/mock-fn)]
(h/render-with-theme-provider [edit-derivation-path/view {:on-reveal on-reveal}])
(render [edit-derivation-path/view {:on-reveal on-reveal}])
(h/fire-event :press (h/get-by-translation-text :t/reveal-address))
(h/was-called on-reveal)
(h/wait-for #(h/is-truthy (h/get-by-translation-text :t/address-activity)))))
(h/test "Reset button pressed"
(let [on-reset (h/mock-fn)]
(h/render-with-theme-provider [edit-derivation-path/view {:on-reset on-reset}])
(render [edit-derivation-path/view {:on-reset on-reset}])
(h/fire-event :press (h/get-by-translation-text :t/reset))
(h/was-called on-reset)
(h/wait-for #(h/is-truthy (h/get-by-translation-text :t/derive-addresses))))))
@@ -133,7 +133,9 @@
:emoji @emoji
:color @account-color
:path @derivation-path
:account-name @account-name}]))
:account-name (if (string/blank? @account-name)
placeholder
@account-name)}]))
:auth-button-label (i18n/label :t/confirm)
;; TODO (@rende11) Add this property when sliding button issue will fixed
;; https://github.com/status-im/status-mobile/pull/18683#issuecomment-1941564785
@@ -60,15 +60,19 @@
:total-balance 100
:market-values-per-currency {:usd {:price 10}}}})
(defn- render
[component]
(h/render-with-theme-provider component :light))
(h/describe "Send > input amount screen"
(h/setup-restorable-re-frame)
(h/test "Default render"
(h/setup-subs sub-mocks)
(h/render-with-theme-provider [input-amount/view
{:crypto-decimals 2
:limit-crypto 250
:initial-crypto-currency? false}])
(render [input-amount/view
{:crypto-decimals 2
:limit-crypto 250
:initial-crypto-currency? false}])
(h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH"))
(h/is-truthy (h/get-by-text "$0.00"))
@@ -78,11 +82,11 @@
(h/test "Fill token input and confirm"
(h/setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render-with-theme-provider [input-amount/view
{:on-confirm on-confirm
:crypto-decimals 10
:limit-crypto 1000
:initial-crypto-currency? false}])
(render [input-amount/view
{:on-confirm on-confirm
:crypto-decimals 10
:limit-crypto 1000
:initial-crypto-currency? false}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
@@ -102,11 +106,11 @@
(h/setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render-with-theme-provider [input-amount/view
{:crypto-decimals 10
:limit-crypto 1000
:on-confirm on-confirm
:initial-crypto-currency? false}])
(render [input-amount/view
{:crypto-decimals 10
:limit-crypto 1000
:on-confirm on-confirm
:initial-crypto-currency? false}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
@@ -124,9 +128,9 @@
(h/test "Try to fill more than limit"
(h/setup-subs sub-mocks)
(h/render-with-theme-provider [input-amount/view
{:crypto-decimals 1
:limit-crypto 1}])
(render [input-amount/view
{:crypto-decimals 1
:limit-crypto 1}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
@@ -136,10 +140,10 @@
(h/test "Switch from crypto to fiat and check limit"
(h/setup-subs sub-mocks)
(h/render-with-theme-provider [input-amount/view
{:crypto-decimals 1
:limit-crypto 1
:on-confirm #()}])
(render [input-amount/view
{:crypto-decimals 1
:limit-crypto 1
:on-confirm #()}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
(h/is-truthy (h/get-by-label-text :container-error))
+4 -5
View File
@@ -181,16 +181,15 @@
(chat.events/public-chat? current-chat)
(assoc :able-to-send-message? true)
(and (chat.events/community-chat? current-chat)
(get-in community [:chats (subs (:chat-id current-chat) 68) :can-post?]))
(assoc :able-to-send-message? true)
(and (chat.events/group-chat? current-chat)
(group-chats.db/member? my-public-key current-chat))
(assoc :able-to-send-message? true
:member? true)
(and (chat.events/community-chat? current-chat)
(get-in community [:chats (subs (:chat-id current-chat) 68) :can-post?]))
(assoc :able-to-send-message? true)
(not group-chat)
(assoc
:contact-request-state (get-in contacts [chat-id :contact-request-state])
+40 -11
View File
@@ -205,13 +205,42 @@
(sort-by :position)
(into []))))
(defn- get-chat-lock-state
"Returns the chat lock state.
- Nil: no lock (there are no permissions for the chat)
- True: locked (there are permissions and can-post? is false)
- False: unlocked (there are permissions and can-post? is true)"
[community-id channels-permissions {chat-id :id}]
(let [composite-key (keyword (str community-id chat-id))
permissions (get channels-permissions composite-key)
{view-only-satisfied? :satisfied?
view-only-permissions :permissions} (:view-only permissions)
{view-and-post-satisfied? :satisfied?
view-and-post-permissions :permissions} (:view-and-post permissions)
can-access? (or (and (seq view-only-permissions)
view-only-satisfied?)
(and (seq view-and-post-permissions)
view-and-post-satisfied?))]
(if (and (empty? view-only-permissions)
(empty? view-and-post-permissions))
nil
(not can-access?))))
(re-frame/reg-sub
:communities/community-channels-permissions
:<- [:communities/channels-permissions]
(fn [channel-permissions [_ community-id]]
(get channel-permissions community-id)))
(defn- reduce-over-categories
[community-id
categories
collapsed-categories
full-chats-data]
full-chats-data
channels-permissions]
(fn [acc
[_ {:keys [name categoryID position id emoji can-post? token-gated?]}]]
[_ {:keys [name categoryID position id emoji] :as chat}]]
(let [category-id (if (seq categoryID) categoryID constants/empty-category-id)
{:keys [unviewed-messages-count
unviewed-mentions-count
@@ -233,11 +262,9 @@
:unread-messages? (pos? unviewed-messages-count)
:position position
:mentions-count (or unviewed-mentions-count 0)
:can-post? can-post?
;; NOTE: this is a troolean nil->no permissions, true->no access, false ->
;; has access
:locked? (when token-gated?
(not can-post?))
:locked? (get-chat-lock-state community-id
channels-permissions
chat)
:id id}]
(update-in acc-with-category [category-id :chats] conj categorized-chat))))
@@ -246,14 +273,17 @@
(fn [[_ community-id]]
[(re-frame/subscribe [:communities/community community-id])
(re-frame/subscribe [:chats/chats])
(re-frame/subscribe [:communities/collapsed-categories-for-community community-id])])
(fn [[{:keys [categories chats]} full-chats-data collapsed-categories]
(re-frame/subscribe [:communities/collapsed-categories-for-community community-id])
(re-frame/subscribe [:communities/community-channels-permissions community-id])])
(fn [[{:keys [categories chats]} full-chats-data collapsed-categories
channels-permissions]
[_ community-id]]
(let [reduce-fn (reduce-over-categories
community-id
categories
collapsed-categories
full-chats-data)
full-chats-data
channels-permissions)
categories-and-chats
(->> chats
(reduce reduce-fn {})
@@ -300,7 +330,6 @@
highest-permission-role (:type highest-role)
can-request-access? (and (boolean highest-permission-role) (not networks-not-supported?))]
{:can-request-access? can-request-access?
:checking? checking?
:highest-permission-role highest-permission-role
:networks-not-supported? networks-not-supported?
:no-member-permission? (and highest-permission-role
+175 -78
View File
@@ -84,29 +84,26 @@
:communities
{"0x1" {:id "0x1"
:chats {"0x1"
{:id "0x1"
:position 1
:name "chat1"
:muted? nil
:categoryID "1"
:token-gated? false
:can-post? true}
{:id "0x1"
:position 1
:name "chat1"
:muted? nil
:categoryID "1"
:can-post? true}
"0x2"
{:id "0x2"
:position 2
:name "chat2"
:muted? nil
:categoryID "1"
:token-gated? true
:can-post? false}
{:id "0x2"
:position 2
:name "chat2"
:muted? nil
:categoryID "1"
:can-post? false}
"0x3"
{:id "0x3"
:position 3
:name "chat3"
:muted? nil
:categoryID "2"
:token-gated? true
:can-post? true}}
{:id "0x3"
:position 3
:name "chat3"
:muted? nil
:categoryID "2"
:can-post? true}}
:categories {"1" {:id "1"
:position 2
:name "category1"}
@@ -115,41 +112,141 @@
:name "category2"}}
:joined true}})
(is
(match? [["2"
{:id "2"
:name "category2"
:collapsed? nil
:position 1
:chats [{:name "chat3"
:position 3
:emoji nil
:muted? nil
:locked? false
:id "0x3"
:unread-messages? false
:mentions-count 0}]}]
["1"
{:id "1"
:name "category1"
:collapsed? nil
:position 2
:chats [{:name "chat1"
:emoji nil
:position 1
:muted? nil
:locked? nil
:id "0x1"
:unread-messages? false
:mentions-count 0}
{:name "chat2"
:emoji nil
:position 2
:muted? nil
:locked? true
:id "0x2"
:unread-messages? false
:mentions-count 0}]}]]
(rf/sub [sub-name "0x1"]))))
(= [["2"
{:id "2"
:name "category2"
:collapsed? nil
:position 1
:chats [{:name "chat3"
:position 3
:emoji nil
:muted? nil
:locked? nil
:id "0x3"
:unread-messages? false
:mentions-count 0}]}]
["1"
{:id "1"
:name "category1"
:collapsed? nil
:position 2
:chats [{:name "chat1"
:emoji nil
:position 1
:muted? nil
:locked? nil
:id "0x1"
:unread-messages? false
:mentions-count 0}
{:name "chat2"
:emoji nil
:position 2
:muted? nil
:locked? nil
:id "0x2"
:unread-messages? false
:mentions-count 0}]}]]
(rf/sub [sub-name "0x1"]))))
(testing "Channels with categories and token permissions"
(swap! rf-db/app-db assoc
:community-channels-permissions
{community-id
{(keyword (str community-id "0x100"))
{:view-only {:satisfied? false
:permissions {:token-permission-id-01 {:criteria [false]}}}
:view-and-post {:satisfied? true :permissions {}}}
(keyword (str community-id "0x200"))
{:view-only {:satisfied? true :permissions {}}
:view-and-post {:satisfied? true :permissions {}}}
(keyword (str community-id "0x300"))
{:view-only {:satisfied? false :permissions {}}
:view-and-post {:satisfied? true
:permissions {:token-permission-id-03 {:criteria [true]}}}}
(keyword (str community-id "0x400"))
{:view-only {:satisfied? true
:permissions {}}
:view-and-post {:satisfied? false
:permissions {:token-permission-id-04 {:criteria [false]}}}}}}
:communities
{community-id {:id community-id
:chats {"0x100" {:id "0x100"
:position 1
:name "chat1"
:muted? nil
:categoryID "1"
:can-post? false}
"0x200" {:id "0x200"
:position 2
:name "chat2"
:muted? nil
:categoryID "1"
:can-post? false}
"0x300" {:id "0x300"
:position 3
:name "chat3"
:muted? nil
:categoryID "2"
:can-post? true}
"0x400" {:id "0x400"
:position 4
:name "chat4"
:muted? nil
:categoryID "2"
:can-post? true}}
:categories {"1" {:id "1"
:position 2
:name "category1"}
"2" {:id "2"
:position 1
:name "category2"}}
:joined true}})
(is
(= [["2"
{:id "2"
:name "category2"
:collapsed? nil
:position 1
:chats [{:name "chat3"
:position 3
:emoji nil
:muted? nil
:locked? false
:id "0x300"
:unread-messages? false
:mentions-count 0}
{:name "chat4"
:position 4
:emoji nil
:muted? nil
:locked? true
:id "0x400"
:unread-messages? false
:mentions-count 0}]}]
["1"
{:id "1"
:name "category1"
:collapsed? nil
:position 2
:chats [{:name "chat1"
:emoji nil
:position 1
:muted? nil
:locked? true
:id "0x100"
:unread-messages? false
:mentions-count 0}
{:name "chat2"
:emoji nil
:position 2
:muted? nil
:locked? nil
:id "0x200"
:unread-messages? false
:mentions-count 0}]}]]
(rf/sub [sub-name "0x1"]))))
(testing "Channels without categories"
(swap! rf-db/app-db assoc
:communities
@@ -177,7 +274,7 @@
:name "category2"}}
:joined true}})
(is
(match?
(=
[[constants/empty-category-id
{:name (i18n/label :t/none)
:collapsed? nil
@@ -226,27 +323,27 @@
{"0x10x1" {:unviewed-messages-count 1 :unviewed-mentions-count 2}
"0x10x2" {:unviewed-messages-count 0 :unviewed-mentions-count 0}})
(is
(match? [["1"
{:name "category1"
:id "1"
:collapsed? nil
:chats [{:name "chat1"
:emoji nil
:position 1
:locked? nil
:id "0x1"
:muted? nil
:unread-messages? true
:mentions-count 2}
{:name "chat2"
:emoji nil
:position 2
:locked? nil
:muted? nil
:id "0x2"
:unread-messages? false
:mentions-count 0}]}]]
(rf/sub [sub-name "0x1"])))))
(= [["1"
{:name "category1"
:id "1"
:collapsed? nil
:chats [{:name "chat1"
:emoji nil
:position 1
:locked? nil
:id "0x1"
:muted? nil
:unread-messages? true
:mentions-count 2}
{:name "chat2"
:emoji nil
:position 2
:locked? nil
:muted? nil
:id "0x2"
:unread-messages? false
:mentions-count 0}]}]]
(rf/sub [sub-name "0x1"])))))
(h/deftest-sub :communities/my-pending-requests-to-join
[sub-name]
-12
View File
@@ -338,18 +338,6 @@
(fn [[{:keys [key-uid]} profiles]]
(get profiles key-uid)))
(re-frame/reg-sub
:profile/login-processing
:<- [:profile/login]
(fn [{:keys [processing]}]
processing))
(re-frame/reg-sub
:profile/login-password
:<- [:profile/login]
(fn [{:keys [password]}]
password))
;; LINK PREVIEW
;; ========================================================================================================
+1
View File
@@ -139,6 +139,7 @@
(reg-root-key-sub :communities :communities)
(reg-root-key-sub :communities/create :communities/create)
(reg-root-key-sub :communities/create-channel :communities/create-channel)
(reg-root-key-sub :communities/channels-permissions :community-channels-permissions)
(reg-root-key-sub :communities/requests-to-join :communities/requests-to-join)
(reg-root-key-sub :communities/community-id-input :communities/community-id-input)
(reg-root-key-sub :communities/fetching-community :communities/fetching-community)
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "release/0.174.x",
"commit-sha1": "469f429af096006c6bbffe6e3a4d58c59315e4f1",
"src-sha256": "1zzcpgh5mrkdr9vzxkzbq3k9njfxph1gv58kq4ybi7bac6gnby0y"
"version": "v0.174.8",
"commit-sha1": "8a3e71378f7208f75bd688c02b0ae5c43ca600f2",
"src-sha256": "10wn93xn6xnkg2d8slyygy9rfrwiargm49738bdjj1g4b81220bq"
}