Compare commits

...
32 Commits
Author SHA1 Message Date
Ibrahem 5715248bfe Initial commit 2023-08-23 17:58:41 +03:00
Volodymyr Kozieiev 821e39a562 Network dropdown component (#16982) 2023-08-23 14:12:15 +01:00
Ibrahem Khalil 4cef868eab [16866] Action Drawer design review (#17033) 2023-08-23 15:58:23 +03:00
Anton Iakimov 34f7a48503 nix: map android arch to status-go builds
Fixes partially #15595
In order to build less targets, when not needed we introduce this
mapping logic.
If only specific ABI is required - status-go will have the same
arhitecuture.
2023-08-23 12:15:05 +03:00
Omar Basem e0f83384a2 Quo2 Wallet: Network Link (#17049)
* Quo2 Wallet: Network Link component
2023-08-23 12:53:45 +04:00
flexsurfer 8fe7fad540 Audio button does not disappear when changed to 'Send' button #17082 (#17083) 2023-08-22 20:39:44 +02:00
Yevheniia Berdnyk 4dd5d88f0f e2e: updated community tests 703086 and 702786 2023-08-22 21:15:14 +03:00
codemaster 27f11fcb2d fix: group-avatar component usage (#17041) 2023-08-22 23:46:10 +10:00
Ibrahem Khalil 8e7c6fe778 Make undread-indicator as last child of view (#17064) 2023-08-22 14:20:52 +03:00
Andrea Maria Piana 79daa4d529 [Fixes: #17027] Fix spacing between own messages 2023-08-22 09:43:34 +01:00
erikseppanen bdedccdda6 wallet overview: design review fixes (#17046) 2023-08-21 19:38:04 -04:00
Parvesh Monu cace2a32a0 Improve the floating shell button and fix its position in the screens (#16981) 2023-08-21 21:30:32 +05:30
Yevheniia Berdnyk 92403f5d30 e2e: fix for navigation issue 2023-08-21 16:37:48 +03:00
Omar Basem 4c9ccf3069 Quo2 Wallet: Keypair component (#17019)
* Quo2 Wallet: Keypair component
2023-08-21 16:25:50 +04:00
Omar Basem 50f3bb005e Quo2: Wallet Button and Wallet CTAs components (#17006)
* Quo2 Wallet: Button and CTAs
2023-08-21 16:01:34 +04:00
Parvesh Monu a45f353356 fix ios blur blue overlay (#17015) 2023-08-21 16:02:17 +05:30
Mohamed Javid e4a2ac9cce Add gradient background support in bottom sheet (#16986)
This commit adds Gradient Background in the bottom sheet which will be used in Wallet Account Actions, and Switcher bottom sheet.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-08-21 15:43:50 +05:30
Ibrahem Khalil bdfdf687a4 [16827] Disable transparent video looping (#17000) 2023-08-21 11:49:41 +03:00
Alexander 95ec35343c Background shown for [Continue] button on iOS when it shouldn't overlap the color picker (#17044)
* Background shown for [Continue] button on iOS when it shouldn't overlap the color picker

* kebab-case
2023-08-18 22:22:48 +02:00
diana e186f513ed Add design review to pipeline process doc 2023-08-18 15:54:42 +02:00
Yevheniia Berdnyk 774687bef6 e2e: updated test_group_chat_mute_chat to unmute by time 2023-08-18 16:00:55 +03:00
John Ngei 66e3b60703 Add members to open community
* add members to open community

* fix: join open community notification
2023-08-18 15:38:35 +03:00
John Ngei 99294fa8ea update empty state image illustrations to reflect the applied theme
* update empty state image illustrations to reflect the applied theme

* refactored the code to use theme provider
2023-08-17 23:46:01 +03:00
Mohamed Javid e11a761fcc Revert "chore: update group-avatar component (#17014)" (#17039)
This reverts commit 673b1afc3a.
2023-08-17 18:49:38 +05:30
yqrashawn 999588e67d fix: timbre log to react-native start console (#17032) 2023-08-17 20:51:20 +08:00
yqrashawn 9cae50dc88 fix: no ident ring in pinned msg (#17011) 2023-08-17 15:19:15 +08:00
Churikova Tetiana aecad2136e e2e: starting to-dos 2023-08-17 05:09:19 +03:00
codemaster 673b1afc3a chore: update group-avatar component (#17014)
We merge it without QA because it only changes the API and doesn't need design review because nothing has been changed 👍
2023-08-17 06:44:30 +10:00
Icaro Motta b0f748cb73 Refactor Quo preview (#16996)
Improvements to quo previews:

- Change quo-preview.preview code to be more aligned with our guidelines.
- Remove duplication when setting up preview screens in quo-preview.main. Now we
  only need to specify the :name and :component keys and fallback to a good
  default for "{:options {:topBar {:visible true}}".
- Auto-generate descriptor labels based on the key.
- Fix form field colors for dark & light, especially for Android.
- Redesigned form fields to look nicer 💄
- Create component that abstracts away the code for rendering the form fields
  and the preview area. This will aid us in creating more consistent looking
  preview screens and keep things DRY.

How do we use the new code?

Just as before, define a state binding and use it to build up the arguments of
the component. Then, use the preview/preview-container to wrap the component.
You can use certain props to control how the preview is styled, etc, but that's
about it.

    (def descriptor
      [{:type :text :key :label}
       {:key     :chevron-position
        :type    :select
        :options [{:key :left}
                  {:key :right}]}])
    
    (defn view
      []
      (let [state (reagent/atom {:chevron-position :left
                                 :label            "Welcome"})]
        (fn []
          [preview/preview-container {:state state :descriptor descriptor}
           [quo/divider-label @state]])))
2023-08-16 11:30:21 +00:00
Andrea Maria Piana d988296ecf Add next in line for communities 2023-08-16 12:16:32 +01:00
Andrea Maria Piana dc8a09ce75 Update wallet team members 2023-08-16 12:16:08 +01:00
Andrea Maria Piana 0dea703ca0 3 lines community description 2023-08-16 12:15:12 +01:00
114 changed files with 2193 additions and 1285 deletions
+3 -5
View File
@@ -16,7 +16,7 @@ The responsibilities of the team are to implement the new wallet UI, with the su
## Decision
Some team members have already expressed interest and some have been asked and accepted to join the wallet team, these team members are:
The team members for the initial wallet team are:
- @rasom
- @OmarBasem
@@ -25,7 +25,5 @@ Some team members have already expressed interest and some have been asked and a
- @briansztamfater
- @smohamedjavid
- @ulisesmac
# Follow-up Actions
- We still need 3/4 team members to join the wallet team
- @erikseppanen
- @mmilad75
+1 -1
View File
@@ -33,7 +33,7 @@ The people identified for each sections are as follow:
- Messaging @flexsurfer, followed by @alwx
- Syncing & Onboarding @siddarthkay
- Communities @ilmotta
- Communities @ilmotta, followed by @ajayesivan
- Activity Center & Shell @J-Son89, followed by @Parveshdhull
- Wallet (once the vertical team is created) @J-Son89, followed by @briansztamfater
+27 -16
View File
@@ -30,7 +30,7 @@ Ready for testing PR should meet the following criteria:
3. Wait for the review.
4. Make sure that after review and before requesting manual QA your PR is rebased to current develop.
5. Once the PR has been approved by reviewer(s) - label `request-manual-qa` should be applied to the PR
6. Move PR to the E2E column when it is ready for testing. That will also trigger e2e tests run. QAs are monitoring PRs from E2E column and take it into test.
6. Move PR to the E2E column when it is ready for testing (**mandatory for all PRs**). That will also trigger e2e tests run. QAs are monitoring PRs from E2E column and take it into test.
After that - PR will be taken into manual testing by the QA team.
@@ -41,27 +41,37 @@ After that - PR will be taken into manual testing by the QA team.
- QA engineer picks up one of PRs with the ```request-manual-qa``` label, drags the item to the ```IN TESTING``` column and assigns it to themselves.
- During testing, QA will add comments describing the issues found, and also review automation tests results.
Usually found issues are numbered as "Issue 1, Issue 2", etc.
When the first round of testing is completed and all issues for this stage are found, tester can add the ```Tested - Issues``` label and drag the card to the ```CONTRIBUTOR``` column. These two actions are optional.
- When manual testing of PR is fully completed and all issues are fixed, QA adds the ```Tested - OK``` label and drags the card to the ```MERGE``` column, after which developer merges PR into develop.
If manual testing was not carried out, developer drags PR to the ```MERGE``` column themselves.
When the first round of testing is completed and all issues for this stage are found, the QA can add the ```Tested - Issues``` label and drag the card to the ```CONTRIBUTOR``` column. These two actions are optional.
- When manual testing of the PR is fully completed and all the issues are fixed, the QA adds the ```Tested - OK``` label and drags the card to the ```Design review``` column (the cases when design review is necessary are described below).
- If design review is not required, the QA drags the PR to the ```MERGE``` column. After that the developer merges PR into develop.
- If design review has been done, the designer (```@Francesca-G```) drags the PR to the ```MERGE``` column.
After that the developer merges PR into develop.
- If manual testing/design review was not carried out, the developer drags PR to the ```MERGE``` column themselves.
### Design review
_**How do I know if a design review is needed?**_
There are three cases here depending on the changes in the PR:
1. **Functional PRs with UI changes:** after the ```Tested - OK``` label is added, the QA moves the PR to the ```Design review``` column + mentions ```@Francesca-G``` in comments.
2. **Component PRs:** can be moved directly to the ```Design review``` column by the developer when get a review from devs (manual testing step can be skipped) + the developer mentions ```@Francesca-G``` in comments.
3. **Functional PRs changes in which are not related to UI (e.g. a crash fix):** skip the ```Design review``` step (the PR should only be manually tested by QA).
There are three possible scenarios when the design review is completed:
1. **Approved by design** > the PR is moved to the ```MERGE``` column by Francesca
2. **Some changes requested, but can be fixed as followups** > need to be negotiated with Francesca > Francesca moves PR to the ```MERGE``` column and adds the ```Follow-up required``` label > follow-ups should be added **by the dev** right after the PR is merged
3. **Some changes requested, they should be fixed before merge** > Francesca reviews the PR again after the fixes and moves PR to the ```MERGE``` column from ```Design review```
---
**Notes:**
- If your PR has a long story and started from `develop` branch several days ago, please rebase it to current develop before adding label
- if PR can be tested by developer (in case of small changes) and/or developer is sure that the changes made cannot introduce a regression, then PR can be merged without manual testing. Also, currently, PRs are not manually tested if the changes relate only the design (creation of components, etc.) and do not affect the functionality.
---
**Notes:**
- If your PR has a long story and started from `develop` branch several days ago, please rebase it to current develop before adding label
- if PR can be tested by developer (in case of small changes) and/or developer is sure that the changes made cannot introduce a regression, then PR can be merged without manual testing. Also, currently, PRs are not manually tested if the changes relate only the design (creation of components, etc.) and do not affect the functionality.
#### Why my PR is in `Contributor` column?
PR can be moved to this column by the ```status-github-bot``` or by QA engineer with label `Tested-issues`.
In the first case most often this happens due to conflicting files in PR.
In the second case - after fixing of all found issues, the developer should ping the QA in the PR comments for retesting.
#### Why is my PR in `To Rebase` column?
PR is moved to the "To Rebase" column in two cases:
- automatically by github bot if PR branch has conflicts that should be resolved
- manually (by QAs) if PR branch is out-of-date with the base branch and requires rebasing to the latest develop
If PR appeared in the "To Rebase" column dev who is working on the PR should resolve conflicts/rebase branch to the latest develop. After resolving conflicts/rebasing PR should be moved by developer to the right column depending on PR work progress.
## Merging a PR
**Merge conditions:**
1. Required number of reviews received
@@ -73,6 +83,7 @@ If PR appeared in the "To Rebase" column dev who is working on the PR should res
6. In case of manual testing - the label ```Tested - OK``` from QA
7. In case of design review - the approval from the designer
You can merge your PR into develop - some useful clues you can find [here](https://notes.status.im/setup-e2e#3-Merging-PR)
+1 -9
View File
@@ -15,19 +15,11 @@ rec {
];
inputsFrom = [
release
(release {})
androidShell
];
shellHook = ''
export ANDROID_SDK_ROOT="${androidPkgs.sdk}"
export ANDROID_NDK_ROOT="${androidPkgs.ndk}"
export STATUS_NIX_MAVEN_REPO="${deps.gradle}"
# required by some makefile targets
export STATUS_GO_ANDROID_LIBDIR=${status-go}
# check if node modules changed and if so install them
$STATUS_MOBILE_HOME/nix/scripts/node_modules.sh ${deps.nodejs-patched}
'';
+16 -8
View File
@@ -30,6 +30,9 @@ let
# Pass secretsFile for POKT_TOKEN to jsbundle build
builtJsBundle = jsbundle { inherit secretsFile; };
# Map ANDROID_ABI_INCLUDE to status-go targets
androidAbiIncludeSplit = lib.splitString ";" androidAbiInclude;
envFileName =
if androidAbiInclude == "x86" then ".env.e2e"
@@ -77,20 +80,25 @@ in stdenv.mkDerivation rec {
ANDROID_ABI_SPLIT = androidAbiSplit;
ANDROID_ABI_INCLUDE = androidAbiInclude;
# Android SDK/NDK for use by Gradle
ANDROID_SDK_ROOT = "${androidPkgs.sdk}";
ANDROID_NDK_ROOT = "${androidPkgs.ndk}";
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
NODE_OPTIONS = "--openssl-legacy-provider";
# Used by the Android Gradle build script in android/build.gradle
STATUS_GO_ANDROID_LIBDIR = status-go;
phases = [
"unpackPhase" "secretsPhase" "buildPhase" "checkPhase" "installPhase"
"shellHook" "unpackPhase" "secretsPhase" "buildPhase" "checkPhase" "installPhase"
];
# We use shellHook as a single place to setup env vars for both build derivation and shell
shellHook = ''
# Used by the Android Gradle build script in android/build.gradle
export STATUS_GO_ANDROID_LIBDIR=${ status-go { abis = androidAbiIncludeSplit; } }
# Android SDK/NDK for use by Gradle
export ANDROID_SDK_ROOT="${androidPkgs.sdk}"
export ANDROID_NDK_ROOT="${androidPkgs.ndk}"
export STATUS_NIX_MAVEN_REPO="${deps.gradle}"
'';
unpackPhase = ''
cp -ar $src/. ./
chmod u+w -R ./
+1 -1
View File
@@ -66,7 +66,7 @@ let
# helpers for use with target argument
ios = targets.mobile.ios.shell;
android = targets.mobile.android.shell;
status-go = targets.status-go.mobile.android;
status-go = targets.status-go.mobile.android {};
};
# for merging the default shell with others
+10 -2
View File
@@ -1,10 +1,18 @@
{ callPackage, meta, source, goBuildLdFlags }:
{
android = callPackage ./build.nix {
android = {abis ? [ "armeabi-v7a" "arm64-v8a" "x86" ]}: callPackage ./build.nix {
platform = "android";
platformVersion = "23";
targets = [ "android/arm" "android/arm64" "android/386" ];
# Hide different arch naming in gomobile from Android builds.
targets = let
abiMap = {
"armeabi-v7a" = "android/arm";
"arm64-v8a" = "android/arm64";
"x86" = "android/386";
"x86_64" = "android/amd64";
};
in map (arch: abiMap."${arch}") abis;
outputFileName = "status-go-${source.shortRev}.aar";
inherit meta source goBuildLdFlags;
};
+2 -2
View File
@@ -66,13 +66,13 @@
"react-native-randombytes": "^3.6.1",
"react-native-reanimated": "2.11.0",
"react-native-redash": "^16.0.11",
"react-native-svg": "13.10.0",
"react-native-shake": "^3.3.1",
"react-native-share": "^8.2.2",
"react-native-static-safe-area-insets": "^2.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#refs/tags/v2.5.39",
"react-native-svg": "13.10.0",
"react-native-touch-id": "^4.4.1",
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.0.9",
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.1.1",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#refs/tags/v11.16.0-status",
"react-syntax-highlighter": "^15.5.0",
"rn-emoji-keyboard": "0.7.0",
Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

+19 -17
View File
@@ -10,14 +10,14 @@
;; (-> reanimated/slide-out-up-animation (.damping 20) .springify (.stiffness 300))
(js/eval
"
var globalThis
if (typeof window === \"undefined\") {
globalThis = global
} else {
globalThis = window
}
globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return () => globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__}})
")
var globalThis
if (typeof window === \"undefined\") {
globalThis = global
} else {
globalThis = window
}
globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return () => globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__}})
")
(def action-button #js {:default #js {:Item #js {}}})
(def config #js {:default #js {}})
@@ -139,15 +139,17 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(def react-native-share #js {:default {}})
(def react-native-svg
#js
{:ClipPath #js {:render identity}
:Circle #js {:render identity}
:Defs #js {:render identity}
:G #js {:render identity}
:Path #js {:render identity}
:Rect #js {:render identity}
:SvgUri #js {:render identity}
:SvgXml #js {:render identity}
:default #js {:render identity}})
{:ClipPath #js {:render identity}
:Circle #js {:render identity}
:Defs #js {:render identity}
:G #js {:render identity}
:Path #js {:render identity}
:Rect #js {:render identity}
:SvgUri #js {:render identity}
:SvgXml #js {:render identity}
:LinearGradient #js {:render identity}
:Stop #js {:render identity}
:default #js {:render identity}})
(def react-native-webview #js {:default {}})
(def react-native-audio-toolkit
#js
@@ -3,12 +3,12 @@
(defn container
[{:keys [container-size customization-color theme]}]
{:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:background-color
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)})
{:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:overflow :hidden
:background-color (colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)})
@@ -7,25 +7,24 @@
[quo2.components.avatars.group-avatar.style :as style]))
(def sizes
{:icon {:x-small 12
:small 16
:medium 16
:large 20
:x-large 32}
:container {:x-small 20
:small 28
:medium 32
:large 48
:x-large 80}})
{:size/s-20 {:icon 12
:container 20}
:size/s-28 {:icon 16
:container 28}
:size/s-32 {:icon 16
:container 32}
:size/s-48 {:icon 20
:container 48}
:size/s-80 {:icon 32
:container 80}})
(defn- view-internal
[_]
(fn [{:keys [size theme customization-color picture]
:or {size :x-small
customization-color :blue
picture nil}}]
(let [container-size (get-in sizes [:container size])
icon-size (get-in sizes [:icon size])]
:or {size :size/s-20
customization-color :blue}}]
(let [container-size (get-in sizes [size :container])
icon-size (get-in sizes [size :icon])]
[rn/view
{:style (style/container {:container-size container-size
:customization-color customization-color
+7 -2
View File
@@ -1,6 +1,7 @@
(ns quo2.components.avatars.icon-avatar
(:require [quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]))
(def sizes
@@ -8,8 +9,8 @@
:medium 32
:small 20})
(defn icon-avatar
[{:keys [size icon color opacity]
(defn icon-avatar-internal
[{:keys [size icon color opacity border? theme]
:or {opacity 20}}]
(let [component-size (size sizes)
circle-color (colors/custom-color color 50 opacity)
@@ -22,9 +23,13 @@
{:style {:width component-size
:height component-size
:border-radius component-size
:border-width (when border? 1)
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color circle-color
:justify-content :center
:align-items :center}}
[icons/icon icon
{:size icon-size
:color icon-color}]]))
(def icon-avatar (quo.theme/with-theme icon-avatar-internal))
@@ -61,6 +61,7 @@
:active-opacity 1
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
:pointer-events :auto
:style {:height 24}
:accessibility-label type}
[rn/view
{:style (merge
@@ -0,0 +1,39 @@
(ns quo2.components.buttons.wallet-button.component-spec
(:require [quo2.components.buttons.wallet-button.view :as wallet-button]
[test-helpers.component :as h]))
(h/describe "button tests"
(h/test "default render of wallet button component"
(h/render [wallet-button/view
{:icon :i/placeholder
:accessibility-label "test-button"}])
(h/is-truthy (h/get-by-label-text "test-button")))
(h/test "button on-press works"
(let [event (h/mock-fn)]
(h/render [wallet-button/view
{:icon :i/placeholder
:on-press event
:accessibility-label "test-button"}])
(h/fire-event :press (h/get-by-label-text "test-button"))
(h/was-called event)))
(h/test "button on-press disabled when disabled"
(let [event (h/mock-fn)]
(h/render [wallet-button/view
{:icon :i/placeholder
:on-press event
:accessibility-label "test-button"
:disabled? true}])
(h/fire-event :press (h/get-by-label-text "test-button"))
(h/was-not-called event)))
(h/test "button on-long-press works"
(let [event (h/mock-fn)]
(h/render [wallet-button/view
{:icon :i/placeholder
:on-long-press event
:accessibility-label "test-button"}])
(h/fire-event :long-press (h/get-by-label-text "test-button"))
(h/was-called event))))
@@ -0,0 +1,20 @@
(ns quo2.components.buttons.wallet-button.style
(:require [quo2.foundations.colors :as colors]))
(defn get-border-color
[{:keys [pressed? theme]}]
(if (= pressed? true)
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme)))
(defn main
[{:keys [pressed? theme disabled?]}]
{:border-color (get-border-color {:pressed? pressed?
:theme theme})
:border-width 1
:border-radius 10
:width 32
:height 32
:justify-content :center
:align-items :center
:opacity (when disabled? 0.3)})
@@ -0,0 +1,29 @@
(ns quo2.components.buttons.wallet-button.view
(:require
[quo2.components.buttons.wallet-button.style :as style]
[quo2.components.icon :as quo2.icons]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn- view-internal
[]
(let [pressed? (reagent/atom false)]
(fn
[{:keys [on-press on-long-press disabled? icon accessibility-label container-style theme]}]
[rn/pressable
{:accessibility-label (or accessibility-label :wallet-button)
:on-press on-press
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? nil)
:on-long-press on-long-press
:disabled disabled?
:style (merge (style/main {:pressed? @pressed?
:theme theme
:disabled? disabled?})
container-style)}
[quo2.icons/icon icon
{:color (colors/theme-colors colors/neutral-100 colors/white theme)}]])))
(def view (theme/with-theme view-internal))
@@ -0,0 +1,11 @@
(ns quo2.components.buttons.wallet-ctas.component-spec
(:require [test-helpers.component :as h]
[quo2.components.buttons.wallet-ctas.view :as wallet-ctas]))
(h/describe "Wallet CTAs test"
(h/test "Buttons render"
(h/render [wallet-ctas/view])
(h/is-truthy (h/get-by-label-text :buy))
(h/is-truthy (h/get-by-label-text :send))
(h/is-truthy (h/get-by-label-text :receive))
(h/is-truthy (h/get-by-label-text :bridge))))
@@ -0,0 +1,13 @@
(ns quo2.components.buttons.wallet-ctas.style)
(def container
{:padding-top 24
:padding-bottom 12
:padding-horizontal 20
:flex-direction :row})
(def button-container
{:padding-vertical 8
:width 77.75
:justify-content :center
:align-items :center})
@@ -0,0 +1,55 @@
(ns quo2.components.buttons.wallet-ctas.view
(:require
[quo2.components.buttons.wallet-button.view :as wallet-button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]
[quo2.components.buttons.wallet-ctas.style :as style]))
(defn action-button
[{:keys [icon text on-press theme accessibility-label]}]
[rn/view
{:style style/button-container
:accessibility-label accessibility-label}
[wallet-button/view
{:icon icon
:on-press on-press
:on-long-press #(js/alert "long pressed")}]
[text/text
{:weight :medium
:size :paragraph-2
:style {:margin-top 4
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} text]])
(defn view-internal
[{:keys [theme buy-action send-action receive-action bridge-action]}]
[rn/view {:style style/container}
[action-button
{:icon :i/add
:text (i18n/label :t/buy)
:on-press buy-action
:theme theme
:accessibility-label :buy}]
[action-button
{:icon :i/send
:text (i18n/label :t/send)
:on-press send-action
:theme theme
:accessibility-label :send}]
[action-button
{:icon :i/receive
:text (i18n/label :t/receive)
:on-press receive-action
:theme theme
:accessibility-label :receive}]
[action-button
{:icon :i/bridge
:text (i18n/label :t/bridge)
:on-press bridge-action
:theme theme
:accessibility-label :bridge}]])
(def view (quo.theme/with-theme view-internal))
@@ -23,10 +23,11 @@
:margin-horizontal 12
:flex-direction :row})
(def left-icon
(defn left-icon
[sub-label?]
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-top (if sub-label? 10 :auto)
:margin-bottom (when-not sub-label? :auto)
:margin-right 12
:width 20})
@@ -51,7 +51,7 @@
[rn/view
{:accessibility-label :left-icon-for-action
:accessible true
:style style/left-icon}
:style (style/left-icon sub-label)}
[icon/icon icon
{:color (or icon-color (get-icon-color danger? theme))
:size 20}]]
@@ -0,0 +1,35 @@
(ns quo2.components.dropdowns.network-dropdown.component-spec
(:require [quo2.components.dropdowns.network-dropdown.view :as network-dropdown]
[quo2.foundations.resources :as quo.resources]
[test-helpers.component :as h]))
(def ^:private networks-list
[{:source (quo.resources/get-network :ethereum)}
{:source (quo.resources/get-network :optimism)}
{:source (quo.resources/get-network :arbitrum)}])
(h/describe "Network dropdown"
(h/test "default render"
(h/render [network-dropdown/view {:state :default}
networks-list])
(h/is-truthy (h/query-by-label-text :network-dropdown)))
(h/test "Should call :on-press in enabled state"
(let [on-press (h/mock-fn)]
(h/render [network-dropdown/view
{:state :default
:on-press on-press}
networks-list])
(h/is-truthy (h/query-by-label-text :network-dropdown))
(h/fire-event :press (h/query-by-label-text :network-dropdown))
(h/was-called on-press)))
(h/test "Should not call :on-press in disabled state"
(let [on-press (h/mock-fn)]
(h/render [network-dropdown/view
{:state :disabled
:on-press on-press}
networks-list])
(h/is-truthy (h/query-by-label-text :network-dropdown))
(h/fire-event :press (h/query-by-label-text :network-dropdown))
(h/was-not-called on-press))))
@@ -0,0 +1,24 @@
(ns quo2.components.dropdowns.network-dropdown.style
(:require [quo2.foundations.colors :as colors]))
(defn container-border-color
[{:keys [state blur? theme pressed?]}]
(let [default-color (if blur?
colors/neutral-80-opa-5
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))
active-color (if blur?
colors/neutral-80-opa-10
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme))]
(condp = state
:disabled default-color
:default (if pressed? active-color default-color))))
(defn dropdown-container
[{:keys [state] :as props}]
{:border-width 1
:border-radius 10
:padding-horizontal 8
:padding-vertical 6
:opacity (if (= state :disabled) 0.3 1)
:border-color (container-border-color props)
:align-items :center})
@@ -0,0 +1,26 @@
(ns quo2.components.dropdowns.network-dropdown.view
(:require [quo2.theme :as quo.theme]
[quo2.components.dropdowns.network-dropdown.style :as style]
[react-native.core :as rn]
[quo2.components.list-items.preview-list :as preview-list]
[reagent.core :as reagent]))
(defn- internal-view
[_ _]
(let [pressed? (reagent/atom false)]
(fn
[{:keys [on-press state] :as props} networks]
[rn/pressable
{:style (style/dropdown-container (merge props {:pressed? @pressed?}))
:accessibility-label :network-dropdown
:disabled (= state :disabled)
:on-press on-press
:on-press-in (fn [] (reset! pressed? true))
:on-press-out (fn [] (reset! pressed? false))}
[preview-list/preview-list
{:type :network
:list-size (count networks)
:size 20}
networks]])))
(def view (quo.theme/with-theme internal-view))
@@ -21,6 +21,12 @@
:hole-size 26
:hole-x 19
:hole-y -1}
20 {:border-radius {:circular 10 :rounded 8}
:hole-radius {:circular 11 :rounded 9}
:margin-left -4
:hole-size 22
:hole-x 15
:hole-y -1}
16 {:border-radius {:circular 8 :rounded 8}
:hole-radius {:circular 9 :rounded 9}
:margin-left -4
@@ -32,19 +38,19 @@
(defn avatar
[item type size border-radius]
(case type
:user [user-avatar/user-avatar
(merge {:ring? false
:status-indicator? false
:size (case size
32 :small
24 :xs
16 :xxxs)}
item)]
(:photo :collectible) [fast-image/fast-image
{:source (:source item)
:style {:width size
:height size
:border-radius border-radius}}]))
:user [user-avatar/user-avatar
(merge {:ring? false
:status-indicator? false
:size (case size
32 :small
24 :xs
16 :xxxs)}
item)]
(:photo :collectible :network) [fast-image/fast-image
{:source (:source item)
:style {:width size
:height size
:border-radius border-radius}}]))
(defn list-item
[index type size item list-size margin-left
@@ -115,7 +121,7 @@
(defn- preview-list-internal
"[preview-list opts items]
opts
{:type :user/:community/:account/:token/:collectible/:dapp
{:type :user/:community/:account/:token/:collectible/:dapp/:network
:size 32/24/16
:list-size override items count in overflow label (optional)
:transparent? overflow-label transparent?}
@@ -1,59 +0,0 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo2.components.buttons.dynamic-button.view :as dynamic-button]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]))
(defn dynamic-button-view
[type dynamic-buttons style]
(when-let [{:keys [on-press customization-color label] :as props} (get dynamic-buttons type)]
[dynamic-button/view
{:type type
:label label
:on-press on-press
:count (:count props)
:style style
:customization-color customization-color}]))
(defn- section
[children]
[rn/view {:style {:flex 1} :pointer-events :box-none} children])
(defn- f-floating-shell-button
[dynamic-buttons style opacity-anim]
(let [original-style (merge {:flex-direction :row
:margin-horizontal 12
:pointer-events :box-none}
style)
animated-style (reanimated/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
original-style)]
[reanimated/view {:style animated-style}
;; Left Section
[section
[dynamic-button-view :search dynamic-buttons
{:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[section
[rn/view
{:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}]]]]))
(defn floating-shell-button
"[floating-shell-button dynamic-buttons style opacity-anim pointer-anim]
dynamic-buttons {:button-type {:on-press on-press :count count}}
style override style
opacity-anim reanimated value (optional)"
([dynamic-buttons style]
[:f> f-floating-shell-button dynamic-buttons style nil])
([dynamic-buttons style opacity-anim]
[:f> f-floating-shell-button dynamic-buttons style opacity-anim]))
@@ -0,0 +1,22 @@
(ns quo2.components.navigation.floating-shell-button.style
(:require [react-native.reanimated :as reanimated]))
(defn floating-shell-button
[style opacity-anim]
(reanimated/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
(merge
{:flex-direction :row
:height 44
:align-self :center
:padding-top 8
:padding-horizontal 12
:pointer-events :box-none}
style)))
(def right-section
{:position :absolute
:flex-direction :row
:right 0})
@@ -0,0 +1,49 @@
(ns quo2.components.navigation.floating-shell-button.view
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.dynamic-button.view :as dynamic-button]
[quo2.components.navigation.floating-shell-button.style :as style]))
(defn dynamic-button-view
[type dynamic-buttons style]
(when-let [{:keys [on-press customization-color label] :as props} (get dynamic-buttons type)]
[dynamic-button/view
{:type type
:label label
:on-press on-press
:count (:count props)
:style style
:customization-color customization-color}]))
(defn- section
[children]
[rn/view {:style {:flex 1} :pointer-events :box-none} children])
(defn- f-floating-shell-button
[dynamic-buttons style opacity-anim]
[reanimated/view {:style (style/floating-shell-button style opacity-anim)}
;; Left Section
[section
[dynamic-button-view :search dynamic-buttons
{:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[section
[rn/view
{:style style/right-section}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}]]]])
(defn view
"[floating-shell-button dynamic-buttons style opacity-anim pointer-anim]
dynamic-buttons {:button-type {:on-press on-press :count count}}
style override style
opacity-anim reanimated value (optional)"
([dynamic-buttons style]
[:f> f-floating-shell-button dynamic-buttons style nil])
([dynamic-buttons style opacity-anim]
[:f> f-floating-shell-button dynamic-buttons style opacity-anim]))
@@ -0,0 +1,61 @@
(ns quo2.components.wallet.keypair.component-spec
(:require [test-helpers.component :as h]
[quo2.components.wallet.keypair.view :as keypair]))
(def accounts
[{:account-props {:customization-color :turquoise
:size 32
:emoji "\uD83C\uDFB2"
:type :default
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [:ethereum :optimism]
:state :default
:action :none}])
(def default-details
{:full-name "John Doe"
:address "zQ3...6fBd2"})
(def other-details {:full-name "Metamask"})
(h/describe "Wallet: Keypair"
(h/test "Default keypair title renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :default-keypair
:stored :on-device
:action :selector
:details default-details}])
(h/is-truthy (h/get-by-label-text :title)))
(h/test "On device renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-device
:action :selector
:details other-details}])
(h/is-truthy (h/get-by-label-text :details)))
(h/test "Selector action renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-keycard
:action :selector
:details other-details}])
(h/is-truthy (h/get-by-label-text :radio-on)))
(h/test "Options action renders"
(h/render [keypair/view
{:accounts accounts
:customization-color :blue
:type :other
:stored :on-keycard
:action :options
:details other-details}])
(h/is-truthy (h/get-by-label-text :options-button))))
@@ -0,0 +1,26 @@
(ns quo2.components.wallet.keypair.style
(:require [quo2.foundations.colors :as colors]))
(defn container
[selected? customization-color theme]
{:border-radius 20
:border-width 1
:border-color (if selected?
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
:padding-bottom 8})
(def header-container
{:padding-horizontal 12
:padding-top 8
:padding-bottom 12
:flex-direction :row
:align-items :center})
(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:flex 1})
@@ -0,0 +1,93 @@
(ns quo2.components.wallet.keypair.view
(:require
[quo2.components.avatars.icon-avatar :as icon-avatar]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.icon :as icon]
[quo2.components.list-items.account-list-card.view :as account-list-card]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.selectors.selectors.view :as selectors]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[quo2.components.wallet.keypair.style :as style]
[clojure.string :as string]))
(defn keypair-string
[full-name]
(let [first-name (first (string/split full-name #" "))]
(i18n/label :t/keypair-title {:name first-name})))
(defn details-string
[address stored]
(str (when address (str address " ∙ "))
(if (= stored :on-device) (i18n/label :t/on-device) (i18n/label :t/on-keycard))))
(defn avatar
[type full-name customization-color]
(if (= type :default-keypair)
[user-avatar/user-avatar
{:full-name full-name
:ring? true
:size :small
:customization-color customization-color}]
[icon-avatar/icon-avatar
{:size :medium
:icon :i/placeholder
:border? true}]))
(defn title-view
[full-name action selected? type customization-color on-options-press theme]
[rn/view
{:style style/title-container
:accessibility-label :title}
[text/text {:weight :semi-bold}
(if (= type :default-keypair) (keypair-string full-name) full-name)]
(if (= action :selector)
[selectors/radio
{:checked? selected?
:customization-color customization-color}]
[rn/pressable {:on-press on-options-press}
[icon/icon :i/options
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:accessibility-label :options-button}]])])
(defn details-view
[address stored theme]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[text/text
{:size :paragraph-2
:accessibility-label :details
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(details-string address stored)]
(when (= stored :on-keycard)
[rn/view {:style {:margin-left 4}}
[icon/icon :i/keycard-card
{:size 16
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]])])
(defn- view-internal
[]
(let [selected? (reagent/atom true)]
(fn [{:keys [theme accounts customization-color type details stored action on-options-press]}]
(let [{:keys [address full-name]} details]
[rn/pressable
{:style (style/container @selected? customization-color theme)
:on-press #(when (= action :selector) (reset! selected? (not @selected?)))}
[rn/view {:style style/header-container}
[avatar type full-name customization-color]
[rn/view
{:style {:margin-left 8
:flex 1}}
[title-view full-name action @selected? type customization-color on-options-press theme]
[details-view address stored theme]]]
[rn/flat-list
{:data accounts
:render-fn account-list-card/view
:separator [rn/view {:style {:height 8}}]
:style {:padding-horizontal 8}}]]))))
(def view (quo.theme/with-theme view-internal))
@@ -0,0 +1,85 @@
(ns quo2.components.wallet.network-link.view
(:require
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.svg :as svg]))
(defn link-linear
[{:keys [source theme]}]
[svg/svg {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "10" :fill :none}
[svg/path {:stroke (get colors/networks source) :d "M68 5H5"}]
[svg/circle
{:cx "68"
:cy "5"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks source)}]
[svg/circle
{:cx "5"
:cy "5"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks source)}]])
(defn link-1x
[{:keys [source destination theme]}]
[svg/svg {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "66" :fill :none}
[svg/path
{:stroke "url(#gradient)" :d "M68 5h-9.364c-11.046 0-20 8.954-20 20v16c0 11.046-8.955 20-20 20H5"}]
[svg/circle
{:cx "68"
:cy "5"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks destination)}]
[svg/circle
{:cx "5"
:cy "61"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks source)}]
[svg/defs
[svg/linear-gradient
{:id "gradient" :x1 "72.271" :x2 "82.385" :y1 "5" :y2 "34.155" :gradientUnits "userSpaceOnUse"}
[svg/stop {:stopColor (get colors/networks destination)}]
[svg/stop {:offset "1" :stopColor (get colors/networks source)}]]]])
(defn link-2x
[{:keys [source destination theme]}]
[svg/svg
{:width "73" :height "122" :viewBox "0 0 73 122" :fill "none" :xmlns "http://www.w3.org/2000/svg"}
[svg/path
{:d
"M67.9999 5L58.6356 5C47.5899 5 38.6356 13.9543 38.6356 25L38.6356 97C38.6356 108.046 29.6813 117 18.6356 117L5.00006 117"
:stroke "url(#gradient)"}]
[svg/circle
{:cx "68"
:cy "5"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks destination)}]
[svg/circle
{:cx "5"
:cy "117"
:r "4"
:fill (colors/theme-colors colors/white colors/neutral-90 theme)
:stroke (get colors/networks source)}]
[svg/defs
[svg/linear-gradient
{:id "gradient"
:x1 "72.2711"
:y1 "5.00001"
:x2 "102.867"
:y2 "49.0993"
:gradientUnits "userSpaceOnUse"}
[svg/stop {:stop-color (get colors/networks destination)}]
[svg/stop {:offset "1" :stop-color (get colors/networks source)}]]]])
(defn- view-internal
[{:keys [shape] :as props}]
(case shape
:linear [link-linear props]
:1x [link-1x props]
:2x [link-2x props]))
(def view (quo.theme/with-theme view-internal))
@@ -12,6 +12,10 @@
{:flex-direction :row
:justify-content :space-between})
(def container-info-bottom
{:flex-direction :row
:padding-top 4})
(def network-dropdown
{:border-color colors/neutral-50
:border-width 1
@@ -20,8 +24,10 @@
:height 32})
(defn color-metrics
[metrics]
(if (= metrics :positive) colors/success-50 colors/danger-50))
[metrics theme]
(if (= metrics :positive)
(colors/theme-colors colors/success-50 colors/success-60 theme)
(colors/theme-colors colors/danger-50 colors/danger-60 theme)))
(defn color-text-heading
[theme]
@@ -40,8 +46,8 @@
{:color (color-text-paragraph theme)})
(defn dot-separator
[metrics]
{:background-color (color-metrics metrics)
[metrics theme]
{:background-color (color-metrics metrics theme)
:margin-horizontal 4
:width 2
:height 2})
@@ -42,38 +42,38 @@
[network-dropdown-temporary]])
(defn- view-metrics
[metrics currency-change percentage-change]
[{:keys [metrics currency-change percentage-change theme]}]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[text/text
{:weight :medium
:size :paragraph-2
:style {:color (style/color-metrics metrics)}}
:style {:color (style/color-metrics metrics theme)}}
percentage-change]
[rn/view
{:style (style/dot-separator metrics)}]
{:style (style/dot-separator metrics theme)}]
[text/text
{:weight :medium
:size :paragraph-2
:style {:color (style/color-metrics metrics)
:style {:color (style/color-metrics metrics theme)
:margin-right 4}}
currency-change]
[icons/icon
(if (= metrics :positive) :i/positive :i/negative)
{:color (style/color-metrics metrics)
{:color (style/color-metrics metrics theme)
:size 16}]])
(defn- view-info-bottom
[{:keys [state time-frame metrics date begin-date end-date
currency-change percentage-change theme]}]
[rn/view {:flex-direction :row}
[rn/view {:style style/container-info-bottom}
(when (= state :loading)
[rn/view
{:style {:flex-direction :row
:align-items :center}}
(loading-bars [{:width 32 :height 10 :margin 8}
{:width 32 :height 10 :margin 4}
{:width 32 :height 10 :margin 2}
{:width 62 :height 10 :margin 4}
{:width 10 :height 10 :margin 0}]
theme)])
@@ -107,7 +107,11 @@
:margin-right 8}}
(time-frame time-frames)]
(when (and (= state :default) (not= metrics :none))
[view-metrics metrics currency-change percentage-change])])])
[view-metrics
{:metrics metrics
:currency-change currency-change
:percentage-change percentage-change
:theme theme}])])])
(defn- view-internal
[props]
+12 -2
View File
@@ -13,6 +13,8 @@
quo2.components.buttons.dynamic-button.view
quo2.components.buttons.predictive-keyboard.view
quo2.components.buttons.slide-button.view
quo2.components.buttons.wallet-button.view
quo2.components.buttons.wallet-ctas.view
quo2.components.browser.browser-input.view
quo2.components.calendar.calendar.view
quo2.components.calendar.calendar-day.view
@@ -39,6 +41,7 @@
quo2.components.drawers.drawer-buttons.view
quo2.components.drawers.permission-context.view
quo2.components.dropdowns.dropdown
quo2.components.dropdowns.network-dropdown.view
quo2.components.empty-state.empty-state.view
quo2.components.gradient.gradient-cover.view
quo2.components.graph.wallet-graph.view
@@ -70,7 +73,7 @@
quo2.components.messages.author.view
quo2.components.messages.gap
quo2.components.messages.system-message
quo2.components.navigation.floating-shell-button
quo2.components.navigation.floating-shell-button.view
quo2.components.navigation.page-nav
quo2.components.notifications.activity-log.view
quo2.components.notifications.activity-logs-photos.view
@@ -109,8 +112,10 @@
quo2.components.text-combinations.title.view
quo2.components.wallet.account-overview.view
quo2.components.wallet.account-card.view
quo2.components.wallet.keypair.view
quo2.components.wallet.network-amount.view
quo2.components.wallet.network-bridge.view
quo2.components.wallet.network-link.view
quo2.components.wallet.progress-bar.view
quo2.components.wallet.summary-info.view
quo2.components.wallet.token-input.view
@@ -135,6 +140,8 @@
(def dynamic-button quo2.components.buttons.dynamic-button.view/view)
(def predictive-keyboard quo2.components.buttons.predictive-keyboard.view/view)
(def slide-button quo2.components.buttons.slide-button.view/view)
(def wallet-button quo2.components.buttons.wallet-button.view/view)
(def wallet-ctas quo2.components.buttons.wallet-ctas.view/view)
;;;; Browser
(def browser-input quo2.components.browser.browser-input.view/view)
@@ -187,6 +194,7 @@
;;;; Dropdowns
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
(def network-dropdown quo2.components.dropdowns.network-dropdown.view/view)
;;;; Empty State
(def empty-state quo2.components.empty-state.empty-state.view/empty-state)
@@ -238,7 +246,7 @@
(def static-skeleton quo2.components.loaders.skeleton.view/view)
;;;; Navigation
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
(def floating-shell-button quo2.components.navigation.floating-shell-button.view/view)
(def page-nav quo2.components.navigation.page-nav/page-nav)
;;;; Markdown
@@ -313,9 +321,11 @@
;;;; Wallet
(def account-card quo2.components.wallet.account-card.view/view)
(def account-overview quo2.components.wallet.account-overview.view/view)
(def keypair quo2.components.wallet.keypair.view/view)
(def network-amount quo2.components.wallet.network-amount.view/view)
(def network-bridge quo2.components.wallet.network-bridge.view/view)
(def progress-bar quo2.components.wallet.progress-bar.view/view)
(def summary-info quo2.components.wallet.summary-info.view/view)
(def network-link quo2.components.wallet.network-link.view/view)
(def token-input quo2.components.wallet.token-input.view/view)
(def wallet-overview quo2.components.wallet.wallet-overview.view/view)
+4
View File
@@ -8,6 +8,8 @@
[quo2.components.buttons.composer-button.component-spec]
[quo2.components.buttons.predictive-keyboard.component-spec]
[quo2.components.buttons.slide-button.component-spec]
[quo2.components.buttons.wallet-button.component-spec]
[quo2.components.buttons.wallet-ctas.component-spec]
[quo2.components.calendar.calendar.component-spec]
[quo2.components.calendar.calendar-day.component-spec]
[quo2.components.calendar.calendar.month-picker.component-spec]
@@ -21,6 +23,7 @@
[quo2.components.drawers.documentation-drawers.component-spec]
[quo2.components.drawers.drawer-buttons.component-spec]
[quo2.components.drawers.permission-context.component-spec]
[quo2.components.dropdowns.network-dropdown.component-spec]
[quo2.components.gradient.gradient-cover.component-spec]
[quo2.components.graph.wallet-graph.component-spec]
[quo2.components.inputs.input.component-spec]
@@ -54,6 +57,7 @@
[quo2.components.tags.status-tags-component-spec]
[quo2.components.wallet.account-overview.component-spec]
[quo2.components.wallet.account-card.component-spec]
[quo2.components.wallet.keypair.component-spec]
[quo2.components.wallet.network-amount.component-spec]
[quo2.components.wallet.network-bridge.component-spec]
[quo2.components.wallet.progress-bar.component-spec]
+4 -2
View File
@@ -1,5 +1,6 @@
(ns quo2.foundations.colors
(:require [clojure.string :as string]
[react-native.platform :as platform]
[quo2.theme :as theme]))
(defn alpha
@@ -126,12 +127,13 @@
(def neutral-5-opa-70-blur (alpha neutral-5 0.7))
(def neutral-10-opa-10-blur (alpha neutral-10 0.1))
(def neutral-10-opa-40-blur (alpha neutral-10 0.4))
(def neutral-80-opa-80-blur (alpha "#192438" 0.8))
;; https://github.com/status-im/status-mobile/issues/14903
(def neutral-80-opa-80-blur (if platform/android? (alpha "#192438" 0.8) "#1E2430CC"))
(def neutral-90-opa-10-blur (alpha neutral-90 0.1))
(def neutral-90-opa-40-blur (alpha neutral-90 0.4))
(def neutral-90-opa-70-blur (alpha neutral-90 0.7))
(def neutral-95-opa-70-blur neutral-95-opa-70)
(def neutral-100-opa-70-blur neutral-100-opa-70)
(def neutral-100-opa-70-blur (if platform/android? neutral-100-opa-70 "#0D1014B3"))
;;;;Black
+4
View File
@@ -28,3 +28,7 @@
{:ethereum (js/require "../resources/images/tokens/mainnet/ETH-network.png")
:optimism (js/require "../resources/images/tokens/mainnet/OP.png")
:arbitrum (js/require "../resources/images/tokens/mainnet/ARB.png")})
(defn get-network
[n]
(get networks n))
+2
View File
@@ -10,3 +10,5 @@
(def circle (reagent/adapt-react-class Svg/Circle))
(def svgxml (reagent/adapt-react-class Svg/SvgXml))
(def g (reagent/adapt-react-class Svg/G))
(def linear-gradient (reagent/adapt-react-class Svg/LinearGradient))
(def stop (reagent/adapt-react-class Svg/Stop))
+10 -6
View File
@@ -243,15 +243,19 @@
(rf/merge
cofx
{:json-rpc/call [{:method "wakuext_editMessage"
:params [{:id message-id
:text text
:content-type (if (message-content/emoji-only-content?
{:text text :response-to quoted-message})
constants/content-type-emoji
constants/content-type-text)}]
:params [{:id message-id
:text text
:content-type (if (message-content/emoji-only-content?
{:text text
:response-to quoted-message})
constants/content-type-emoji
constants/content-type-text)
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
(get-in db [:chat/link-previews :unfurled]))}]
:js-response true
:on-error #(log/error "failed to edit message " %)
:on-success (fn [result]
(prn result "awpdkoawpodkawd")
(re-frame/dispatch [:sanitize-messages-and-process-response
result]))}]}
(link-preview/reset-unfurled)
-9
View File
@@ -220,15 +220,6 @@
(log/error "failed to import community" %)
(re-frame/dispatch [::failed-to-import %]))}]})
(rf/defn join
{:events [:communities/join]}
[_ community-id]
{:json-rpc/call [{:method "wakuext_joinCommunity"
:params [community-id]
:js-response true
:on-success #(re-frame/dispatch [::joined %])
:on-error #(log/error "failed to join community" community-id %)}]})
(rf/defn request-to-join
{:events [:communities/request-to-join]}
[_ community-id]
@@ -14,7 +14,7 @@
:margin-vertical 8})
(defn sheet
[{:keys [top bottom]} window-height theme padding-bottom-override shell?]
[{:keys [top bottom]} window-height theme padding-bottom-override selected-item shell?]
{:position :absolute
:max-height (- window-height top)
:z-index 1
@@ -23,13 +23,19 @@
:right 0
:border-top-left-radius 20
:border-top-right-radius 20
:overflow (when shell? :hidden)
:overflow (when-not selected-item :hidden)
:flex 1
:padding-bottom (or padding-bottom-override (+ bottom 8))
:background-color (if shell?
:transparent
(colors/theme-colors colors/white colors/neutral-95 theme))})
(def gradient-bg
{:position :absolute
:top 0
:left 0
:right 0})
(def shell-bg
{:position :absolute
:background-color (if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90)
+9 -3
View File
@@ -1,7 +1,8 @@
(ns status-im2.common.bottom-sheet.view
(:require [oops.core :as oops]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.gesture :as gesture]
@@ -57,7 +58,8 @@
[_ _]
(let [sheet-height (reagent/atom 0)]
(fn [{:keys [hide? insets theme]}
{:keys [content selected-item padding-bottom-override on-close shell?]}]
{:keys [content selected-item padding-bottom-override on-close shell?
gradient-cover? customization-color]}]
(let [{window-height :height} (rn/get-window)
bg-opacity (reanimated/use-shared-value 0)
translate-y (reanimated/use-shared-value window-height)
@@ -88,8 +90,12 @@
window-height
theme
padding-bottom-override
selected-item
shell?))
:on-layout #(reset! sheet-height (oops/oget % "nativeEvent" "layout" "height"))}
(when gradient-cover?
[rn/view {:style style/gradient-bg}
[quo/gradient-cover {:customization-color customization-color}]])
(when shell?
[blur/ios-view {:style style/shell-bg}])
(when selected-item
@@ -106,4 +112,4 @@
[args sheet]
[:f> f-view args sheet])
(def view (theme/with-theme internal-view))
(def view (quo.theme/with-theme internal-view))
@@ -11,7 +11,7 @@
(if group-chat
[quo/group-avatar
{:customization-color color
:size :x-small}]
:size :size/s-20}]
[quo/user-avatar
{:full-name display-name
:profile-picture photo-path
+1 -1
View File
@@ -189,7 +189,7 @@
(defn view-profile-entry
[chat-id]
(entry {:icon :i/friend
(entry {:icon :i/profile
:label (i18n/label :t/view-profile)
:on-press #(show-profile-action chat-id)
:danger? false
+2 -2
View File
@@ -102,12 +102,12 @@
:on-press #(dispatch-and-chill [:open-modal :share-shell] 1000)})
:i/qr-code]
[rn/view
[unread-indicator]
[quo/button
(merge button-common-props
{:accessibility-label :open-activity-center-button
:on-press #(rf/dispatch [:activity-center/open])})
:i/activity-center]]]))
:i/activity-center]
[unread-indicator]]]))
;; TODO: should be moved to quo2 https://github.com/status-im/status-mobile/issues/16964
(defn top-nav
+4 -3
View File
@@ -1,11 +1,11 @@
(ns status-im2.common.log
(:require [clojure.string :as string]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.utils.types :as types]
[status-im2.config :as config]
[taoensso.timbre :as log]
[utils.re-frame :as rf]
[native-module.core :as native-module]
[status-im.utils.types :as types]))
[utils.re-frame :as rf]))
(def logs-queue (atom #queue []))
(def max-log-entries 1000)
@@ -28,6 +28,7 @@
:mobile-system? false
:log-level level
:callback handle-error}]
(log/merge-config! {:ns-whitelist ["*"]})
(if (string/blank? level)
(native-module/init-status-go-logging (merge logging-params {:log-level "WARN"}))
(do
+6 -4
View File
@@ -6,7 +6,7 @@
[status-im2.common.parallax.style :as style]))
(defn f-sensor-animated-video
[{:keys [offset stretch order source disable-parallax?]}]
[{:keys [offset stretch order source disable-parallax? enable-looping?]}]
(let [double-stretch (* 2 stretch)
{window-width :width
window-height :height} (rn/get-window)
@@ -25,14 +25,15 @@
image-style]}
[transparent-video/view
{:source source
:style style/video}]])))
:style style/video
:loop enable-looping?}]])))
(defn sensor-animated-video
[props]
[:f> f-sensor-animated-video props])
(defn f-video
[{:keys [layers disable-parallax? offset stretch container-style]
[{:keys [layers disable-parallax? offset stretch container-style enable-looping?]
:or {offset 50
stretch 0}}]
[rn/view
@@ -44,7 +45,8 @@
:offset offset
:stretch stretch
:order (inc idx)
:disable-parallax? disable-parallax?}])
:disable-parallax? disable-parallax?
:enable-looping? enable-looping?}])
layers)])
(defn video
@@ -65,16 +65,16 @@
:i/arrow-up]])
(defn send-button
[props {:keys [text-value] :as state} animations window-height images? edit]
(let [btn-opacity (reanimated/use-shared-value 0)
z-index (reagent/atom (if (and (empty? @text-value) (not images?)) 0 1))]
[props {:keys [text-value] :as state} animations window-height images? edit btn-opacity]
(let [z-index (reagent/atom (if (and (empty? @text-value) (not images?)) 0 1))]
[:f> f-send-button props state animations window-height images? btn-opacity z-index edit]))
(defn disabled-audio-button
[]
[quo/composer-button
{:on-press #(js/alert "to be implemented")
:icon :i/audio}])
[opacity]
[reanimated/view {:style (reanimated/apply-animations-to-style {:opacity opacity} {})}
[quo/composer-button
{:on-press #(js/alert "to be implemented")
:icon :i/audio}]])
(defn audio-button
[{:keys [record-reset-fn input-ref]}
@@ -169,8 +169,8 @@
[quo/composer-button
{:on-press #(go-to-camera images-count)
:icon :i/camera
:container-style {:margin-right 12}}
]))
:container-style {:margin-right 12}}]))
(defn open-photo-selector
[{:keys [input-ref]}
@@ -212,16 +212,18 @@
(defn view
[props state animations window-height insets {:keys [edit images]}]
[rn/view {:style style/actions-container}
[rn/view
{:style {:flex-direction :row
:display (if @(:recording? state) :none :flex)}}
[camera-button]
[image-button props animations insets]
[reaction-button]
[format-button]]
[:f> send-button props state animations window-height images edit]
(when (and (not edit) (not images))
;; TODO(alwx): needs to be replaced with an `audio-button` later.
;; See https://github.com/status-im/status-mobile/issues/16084 for more details.
[disabled-audio-button])])
(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}
[rn/view
{:style {:flex-direction :row
:display (if @(:recording? state) :none :flex)}}
[camera-button]
[image-button props animations insets]
[reaction-button]
[format-button]]
[:f> send-button props state animations window-height images edit send-btn-opacity]
(when (and (not edit) (not images))
;; TODO(alwx): needs to be replaced with an `audio-button` later.
;; See https://github.com/status-im/status-mobile/issues/16084 for more details.
[:f> disabled-audio-button audio-btn-opacity])]))
@@ -69,7 +69,8 @@
{:full-name display-name
:profile-picture photo-path
:status-indicator? false
:size :xxxs}]
:size :xxxs
:ring? false}]
[quo/text
{:weight :semi-bold
:size :paragraph-2
@@ -14,6 +14,12 @@
:shadow-offset {:width 0 :height (colors/theme-colors -4 -8)}}
{:elevation (if @focused? 10 0)}))
(def composer-sheet-and-jump-to-container
{:position :absolute
:bottom 0
:left 0
:right 0})
(defn sheet-container
[insets {:keys [focused?]} {:keys [container-opacity]}]
(reanimated/apply-animations-to-style
@@ -22,10 +28,6 @@
{:border-top-left-radius 20
:border-top-right-radius 20
:padding-horizontal 20
:position :absolute
:bottom 0
:left 0
:right 0
:background-color (colors/theme-colors colors/white colors/neutral-95)
:z-index 3
:padding-bottom (:bottom insets)}
@@ -87,8 +89,7 @@
:right 0
:bottom 0
:height window-height
:background-color colors/neutral-95-opa-70
:z-index 1}))
:background-color colors/neutral-95-opa-70}))
(defn blur-container
[height focused?]
@@ -110,18 +111,11 @@
:blur-type (colors/theme-colors :light :dark)
:blur-amount 20})
(defn shell-container
[bottom translate-y]
(reanimated/apply-animations-to-style
{:bottom bottom ; we use height of the input directly as bottom position
:transform [{:translate-y translate-y}]}
{:position :absolute
:left 0
:right 0}))
(defn shell-button
[translate-y opacity]
(reanimated/apply-animations-to-style
{:transform [{:translate-y translate-y}]
:opacity opacity}
{}))
{:position :absolute
:top 0
:align-self :center}))
@@ -5,9 +5,7 @@
[react-native.core :as rn]
[status-im2.config :as config]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im2.contexts.chat.composer.style :as style]
[status-im2.contexts.chat.composer.utils :as utils]
[status-im2.contexts.chat.messages.list.view :as messages.list]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -27,12 +25,8 @@
[:f> f-blur-view layout-height focused?])
(defn- f-shell-button
[{:keys [maximized? focused?]} {:keys [height]} {:keys [reply edit]}]
[{:keys [focused?]}]
(let [customization-color (rf/sub [:profile/customization-color])
insets (safe-area/get-insets)
extra-height (utils/calc-top-content-height reply edit)
neg-y (utils/calc-shell-neg-y insets maximized? extra-height)
y-container (reanimated/use-shared-value neg-y)
hide-shell? (or @focused? @messages.list/show-floating-scroll-down-button)
y-shell (reanimated/use-shared-value (if hide-shell? 35 0))
opacity (reanimated/use-shared-value (if hide-shell? 0 1))]
@@ -41,8 +35,7 @@
(reanimated/animate opacity (if hide-shell? 0 1))
(reanimated/animate y-shell (if hide-shell? 35 0)))
[@focused? @messages.list/show-floating-scroll-down-button])
[reanimated/view
{:style (style/shell-container height y-container)}
[:<>
[reanimated/view
{:style (style/shell-button y-shell opacity)}
[quo/floating-shell-button
@@ -53,11 +46,12 @@
(rf/dispatch [:shell/navigate-to-jump-to]))
:customization-color customization-color
:label (i18n/label :t/jump-to)
:style {:align-self :center}}} {}]]
:style {:align-self :center}}}
{}]]
[quo/floating-shell-button
(when @messages.list/show-floating-scroll-down-button
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}})
{:bottom 24}]]))
{}]]))
(defn shell-button
[state animations subs]
+50 -48
View File
@@ -66,62 +66,64 @@
(effects/link-previews props state animations subs)
(effects/images props state animations subs)
[:<>
[sub-view/shell-button state animations subs]
(when chat-screen-loaded?
[mentions/view props state animations max-height cursor-pos
(:images subs)
(:link-previews? subs)
(:reply subs)
(:edit subs)])
[gesture/gesture-detector
{:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)}
[reanimated/view
{:style (style/sheet-container insets state animations)
:on-layout #(handler/layout % state blur-height)}
[sub-view/bar]
(when chat-screen-loaded?
[:<>
[reply/view state]
[edit/view state]])
[reanimated/touchable-opacity
{:active-opacity 1
:on-press (when @(:input-ref props) #(.focus ^js @(:input-ref props)))
:style (style/input-container (:height animations) max-height)
:accessibility-label :message-input-container}
[rn/selectable-text-input
{:ref #(reset! (:selectable-input-ref props) %)
:menu-items @(:menu-items state)
:style (style/input-view state)}
[rn/text-input
{:ref #(reset! (:input-ref props) %)
:default-value @(:text-value state)
:on-focus #(handler/focus props state animations dimensions)
:on-blur #(handler/blur state animations dimensions subs)
:on-content-size-change #(handler/content-size-change %
state
animations
subs
dimensions
(or keyboard-shown (:edit subs)))
:on-scroll #(handler/scroll % props state animations dimensions)
:on-change-text #(handler/change-text % props state)
:on-selection-change #(handler/selection-change % props state)
:on-selection #(selection/on-selection % props state)
:keyboard-appearance (theme/theme-value :light :dark)
:max-height max-height
:max-font-size-multiplier 1
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50)
:style (style/input-text props state subs max-height)
:max-length constants/max-text-size
:accessibility-label :chat-message-input}]]
[rn/view
{:style style/composer-sheet-and-jump-to-container}
[sub-view/shell-button state]
[gesture/gesture-detector
{:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)}
[reanimated/view
{:style (style/sheet-container insets state animations)
:on-layout #(handler/layout % state blur-height)}
[sub-view/bar]
(when chat-screen-loaded?
[:<>
[gradients/view props state animations show-bottom-gradient?]
[link-preview/view]
[images/images-list]])]
[actions/view props state animations window-height insets subs]]]]))
[reply/view state]
[edit/view state]])
[reanimated/touchable-opacity
{:active-opacity 1
:on-press (when @(:input-ref props) #(.focus ^js @(:input-ref props)))
:style (style/input-container (:height animations) max-height)
:accessibility-label :message-input-container}
[rn/selectable-text-input
{:ref #(reset! (:selectable-input-ref props) %)
:menu-items @(:menu-items state)
:style (style/input-view state)}
[rn/text-input
{:ref #(reset! (:input-ref props) %)
:default-value @(:text-value state)
:on-focus #(handler/focus props state animations dimensions)
:on-blur #(handler/blur state animations dimensions subs)
:on-content-size-change #(handler/content-size-change %
state
animations
subs
dimensions
(or keyboard-shown (:edit subs)))
:on-scroll #(handler/scroll % props state animations dimensions)
:on-change-text #(handler/change-text % props state)
:on-selection-change #(handler/selection-change % props state)
:on-selection #(selection/on-selection % props state)
:keyboard-appearance (theme/theme-value :light :dark)
:max-height max-height
:max-font-size-multiplier 1
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50)
:style (style/input-text props state subs max-height)
:max-length constants/max-text-size
:accessibility-label :chat-message-input}]]
(when chat-screen-loaded?
[:<>
[gradients/view props state animations show-bottom-gradient?]
[link-preview/view]
[images/images-list]])]
[:f> actions/view props state animations window-height insets subs]]]]]))
(defn composer
[insets]
@@ -169,7 +169,7 @@
:padding-horizontal 20}}
[quo/group-avatar
{:customization-color color
:size :small}]
:size :size/s-32}]
[quo/text
{:weight :semi-bold
:size :heading-1
@@ -211,7 +211,7 @@
(assoc :ring? false))])
[quo/group-avatar
{:customization-color color
:size :small}]))
:size :size/s-32}]))
(defn notification
[{:keys [muted group-chat unviewed-messages-count unviewed-mentions-count]}]
+22 -13
View File
@@ -1,6 +1,6 @@
(ns status-im2.contexts.chat.home.view
(:require [oops.core :as oops]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[re-frame.core :as re-frame]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
@@ -27,31 +27,32 @@
(filter k)
(sort-by :timestamp >))))
(def empty-state-content
(defn empty-state-content
[theme]
#:tab{:contacts
{:title (i18n/label :t/no-contacts)
:description (i18n/label :t/no-contacts-description)
:image (resources/get-image
(theme/theme-value :no-contacts-light :no-contacts-dark))}
(quo.theme/theme-value :no-contacts-light :no-contacts-dark theme))}
:groups
{:title (i18n/label :t/no-group-chats)
:description (i18n/label :t/no-group-chats-description)
:image (resources/get-image
(theme/theme-value :no-group-chats-light :no-group-chats-dark))}
(quo.theme/theme-value :no-group-chats-light :no-group-chats-dark theme))}
:recent
{:title (i18n/label :t/no-messages)
:description (i18n/label :t/no-messages-description)
:image (resources/get-image
(theme/theme-value :no-messages-light :no-messages-dark))}})
(quo.theme/theme-value :no-messages-light :no-messages-dark theme))}})
(defn chats
[{:keys [selected-tab set-scroll-ref scroll-shared-value]}]
[{:keys [theme selected-tab set-scroll-ref scroll-shared-value]}]
(let [unfiltered-items (rf/sub [:chats-stack-items])
items (filter-and-sort-items-by-tab selected-tab unfiltered-items)]
(if (empty? items)
[common.home/empty-state-image
{:selected-tab selected-tab
:tab->content empty-state-content}]
:tab->content (empty-state-content theme)}]
[reanimated/flat-list
{:ref set-scroll-ref
:key-fn #(or (:chat-id %) (:public-key %) (:id %))
@@ -81,12 +82,12 @@
item]))
(defn contacts
[{:keys [pending-contact-requests set-scroll-ref scroll-shared-value]}]
[{:keys [theme pending-contact-requests set-scroll-ref scroll-shared-value]}]
(let [items (rf/sub [:contacts/active-sections])]
(if (and (empty? items) (empty? pending-contact-requests))
[common.home/empty-state-image
{:selected-tab :tab/contacts
:tab->content empty-state-content}]
:tab->content (empty-state-content theme)}]
[rn/section-list
{:ref set-scroll-ref
:key-fn :public-key
@@ -117,8 +118,8 @@
:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}})
(defn home
[]
(defn- f-view-internal
[{:keys [theme]}]
(let [scroll-ref (atom nil)
set-scroll-ref #(reset! scroll-ref %)]
(fn []
@@ -131,11 +132,13 @@
[contacts
{:pending-contact-requests pending-contact-requests
:set-scroll-ref set-scroll-ref
:scroll-shared-value scroll-shared-value}]
:scroll-shared-value scroll-shared-value
:theme theme}]
[chats
{:selected-tab selected-tab
:set-scroll-ref set-scroll-ref
:scroll-shared-value scroll-shared-value}])
:scroll-shared-value scroll-shared-value
:theme theme}])
[:f> common.home.banner/animated-banner
{:content banner-data
:customization-color customization-color
@@ -153,3 +156,9 @@
:selected-tab selected-tab
:on-tab-change (fn [tab] (rf/dispatch [:messages-home/select-tab tab]))
:scroll-shared-value scroll-shared-value}]]))))
(defn- internal-chats-home-view
[params]
[:f> f-view-internal params])
(def view (quo.theme/with-theme internal-chats-home-view))
@@ -3,6 +3,7 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[quo2.core :as quo]
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]
[quo2.components.drawers.permission-context.view :as permission-context]
[status-im2.constants :as constants]
[react-native.core :as rn]
@@ -37,13 +38,13 @@
(= contact-request-state
constants/contact-request-state-sent)
(i18n/label :t/contact-request-chat-pending))]]
[rn/view {:position :absolute :top -36 :align-self :center}
[quo/floating-shell-button
{:jump-to
{:on-press (fn []
(when config/shell-navigation-disabled?
(rf/dispatch [:chat/close true]))
(rf/dispatch [:shell/navigate-to-jump-to]))
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
{}]]]))
[quo/floating-shell-button
{:jump-to
{:on-press (fn []
(when config/shell-navigation-disabled?
(rf/dispatch [:chat/close true]))
(rf/dispatch [:shell/navigate-to-jump-to]))
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
{:position :absolute
:top (- jump-to.constants/floating-shell-button-height)}]]))
@@ -13,3 +13,14 @@
(and (not in-pinned-view?) (or mentioned pinned-by last-in-group?))
(assoc :margin-top 8))))
(defn user-message-content
[{:keys [first-in-group? outgoing outgoing-status]}]
{:border-radius 16
:padding-horizontal 8
:padding-vertical (if first-in-group?
8
4)
:opacity (if (and outgoing (= outgoing-status :sending))
0.5
1)})
@@ -134,9 +134,10 @@
:message-sending
:message-sent)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
:style {:border-radius 16
:padding 8
:opacity (if (and outgoing (= outgoing-status :sending)) 0.5 1)}
:style (style/user-message-content
{:first-in-group? (:first-in-group? message-data)
:outgoing outgoing
:outgoing-status outgoing-status})
:on-press (fn []
(if (and platform/ios? keyboard-shown?)
(rn/dismiss-keyboard!)
@@ -12,10 +12,11 @@
[status-im.ui.screens.chat.group :as chat.group]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.content.view :as message]
[status-im2.contexts.chat.messages.list.state :as state]
[status-im2.contexts.chat.messages.list.style :as style]
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.navigation.style :as navigation.style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -24,7 +25,6 @@
(defonce ^:const loading-indicator-extra-spacing 250)
(defonce ^:const loading-indicator-page-loading-height 100)
(defonce ^:const scroll-animation-input-range [50 125])
(defonce ^:const spacing-between-composer-and-content 64)
(defonce ^:const min-message-height 32)
(defonce messages-list-ref (atom nil))
@@ -129,15 +129,14 @@
[insets able-to-send-message?]
[rn/view
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:margin-bottom (- 0
(:top insets)
(when platform/ios? style/overscroll-cover-height))
:margin-bottom (when platform/ios? (- style/overscroll-cover-height))
:height (+ (if able-to-send-message?
(+ composer.constants/composer-default-height
spacing-between-composer-and-content
jump-to.constants/floating-shell-button-height
(:bottom insets))
(- 70 (:bottom insets)))
(when platform/ios? style/overscroll-cover-height))}])
(when platform/ios?
(- style/overscroll-cover-height (:top insets))))}])
(defn f-list-footer-avatar
[{:keys [scroll-y display-name online? profile-picture]}]
@@ -67,7 +67,7 @@
:on-press (fn []
(if can-join?
(do
(rf/dispatch [:communities/join id])
(rf/dispatch [:communities/request-to-join id])
(rf/dispatch [:navigate-back]))
(do (and can-request-access?
(not pending?)
@@ -1,7 +1,7 @@
(ns status-im2.contexts.communities.home.view
(:require [oops.core :as oops]
[quo2.core :as quo]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im2.common.home.banner.view :as common.home.banner]
@@ -37,7 +37,9 @@
{:id :pending :label (i18n/label :t/pending) :accessibility-label :pending-tab}
{:id :opened :label (i18n/label :t/opened) :accessibility-label :opened-tab}])
(def empty-state-content
(defn empty-state-content
[theme]
{:joined
{:title (i18n/label :t/no-communities)
:description [:<>
@@ -45,18 +47,21 @@
(i18n/label :t/no-communities-description-strikethrough)]
" "
(i18n/label :t/no-communities-description)]
:image (resources/get-image (theme/theme-value :no-communities-light
:no-communities-dark))}
:image (resources/get-image (quo.theme/theme-value :no-communities-light
:no-communities-dark
theme))}
:pending
{:title (i18n/label :t/no-pending-communities)
:description (i18n/label :t/no-pending-communities-description)
:image (resources/get-image (theme/theme-value :no-pending-communities-light
:no-pending-communities-dark))}
:image (resources/get-image (quo.theme/theme-value :no-pending-communities-light
:no-pending-communities-dark
theme))}
:opened
{:title (i18n/label :t/no-opened-communities)
:description (i18n/label :t/no-opened-communities-description)
:image (resources/get-image (theme/theme-value :no-opened-communities-light
:no-opened-communities-dark))}})
:image (resources/get-image (quo.theme/theme-value :no-opened-communities-light
:no-opened-communities-dark
theme))}})
(def ^:private banner-data
{:title-props
@@ -70,8 +75,8 @@
:banner (resources/get-image :discover)
:accessibility-label :communities-home-discover-card}})
(defn home
[]
(defn- f-view-internal
[{:keys [theme]}]
(let [flat-list-ref (atom nil)
set-flat-list-ref #(reset! flat-list-ref %)]
(fn []
@@ -87,7 +92,7 @@
(if (empty? selected-items)
[common.home/empty-state-image
{:selected-tab selected-tab
:tab->content empty-state-content}]
:tab->content (empty-state-content theme)}]
[reanimated/flat-list
{:ref set-flat-list-ref
:key-fn :id
@@ -109,3 +114,9 @@
:selected-tab selected-tab
:on-tab-change (fn [tab] (rf/dispatch [:communities/select-tab tab]))
:scroll-shared-value scroll-shared-value}]]))))
(defn- internal-communities-home-view
[params]
[:f> f-view-internal params])
(def view (quo.theme/with-theme internal-communities-home-view))
@@ -256,7 +256,7 @@
[description]
[quo/text
{:accessibility-label :community-description-text
:number-of-lines 2
:number-of-lines 4
:ellipsize-mode :tail
:weight :regular
:size :paragraph-1
@@ -367,4 +367,4 @@
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
{:position :absolute
:bottom 41}]]))
:bottom 34}]]))
@@ -4,6 +4,7 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[oops.core :refer [oget]]
[react-native.platform :as platform]
[status-im2.common.resources :as resources]
[status-im.async-storage.core :as async-storage]
[status-im2.contexts.shell.jump-to.state :as shell.state]
@@ -88,10 +89,9 @@
(when dark-overlay?
[blur/view
{:style style/background-blur-overlay
:blur-amount 30
:blur-radius 25
:blur-amount (if platform/android? 30 20)
:blur-radius (if platform/android? 25 10)
:blur-type :transparent
:overlay-color :transparent}])]))
(defn view [dark-overlay?] [:f> f-view dark-overlay?])
@@ -3,6 +3,7 @@
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[react-native.platform :as platform]
[status-im2.contexts.onboarding.common.overlay.style :as style]
[status-im2.constants :as constants]))
@@ -61,7 +62,7 @@
:style (style/blur-container opacity)}
[blur/view
{:blur-amount @blur-amount
:blur-radius 25
:blur-radius (if platform/android? 25 10)
:blur-type :transparent
:overlay-color :transparent
:style style/blur-style}]]))
@@ -51,7 +51,7 @@
(defn show-button-background
[keyboard-height keyboard-shown]
[keyboard-height keyboard-shown content-scroll-y]
(let [button-container-height 64
keyboard-view-height (+ keyboard-height button-container-height)]
(when keyboard-shown
@@ -60,7 +60,7 @@
(< (- @scroll-view-height button-container-height) @content-container-height)
platform/ios?
(< (- @scroll-view-height keyboard-view-height) @content-container-height)
(< (- @scroll-view-height keyboard-view-height) (- @content-container-height content-scroll-y))
:else
false))))
@@ -93,6 +93,7 @@
(defn- f-page
[{:keys [onboarding-profile-data navigation-bar-top]}]
(reagent/with-let [show-keyboard? (reagent/atom false)
content-scroll-y (reagent/atom 0)
show-listener (oops/ocall rn/keyboard
"addListener"
(if platform/android?
@@ -129,7 +130,8 @@
:else :success)
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
show-background? (show-button-background keyboard-height
keyboard-shown)]
keyboard-shown
@content-scroll-y)]
[rn/view {:style style/page-container}
[navigation-bar/navigation-bar
{:stack-id :new-to-status
@@ -137,7 +139,12 @@
[rn/scroll-view
{:on-layout (fn [event]
(let [height (oops/oget event "nativeEvent.layout.height")]
(reset! scroll-view-height height)))
(reset! scroll-view-height height)
(reset! content-scroll-y 0)))
:on-scroll (fn [event]
(let [y (oops/oget event "nativeEvent.contentOffset.y")]
(reset! content-scroll-y y)))
:scroll-event-throttle 64
:content-container-style {:flexGrow 1}}
[rn/view
{:on-layout (fn [event]
@@ -125,7 +125,8 @@
:container-style {:top 40
:left 20}
:layers (:generate-keys resources/parallax-video)
:disable-parallax? true}]
:disable-parallax? true
:enable-looping? false}]
[:f> f-page-title insets]])
(defn f-simple-page
@@ -10,28 +10,28 @@
[{:label "Size"
:key :size
:type :select
:options [{:key :x-small
:value "x-small"}
{:key :small
:value "Small"}
{:key :medium
:value "Medium"}
{:key :large
:value "Large"}
{:key :x-large
:value "x-Large"}]}
:options [{:key :size/s-20
:value "20"}
{:key :size/s-28
:value "28"}
{:key :size/s-32
:value "32"}
{:key :size/s-48
:value "48"}
{:key :size/s-80
:value "80"}]}
{:label "Avatar"
:key :picture?
:type :boolean}
(preview/customization-color-option)])
(def avatar (resources/get-mock-image :user-picture-male4))
(def avatar (resources/get-mock-image :photo1))
(defn cool-preview
[]
(let [state (reagent/atom {:theme :light
:customization-color :blue
:size :small
:size :size/s-20
:picture? false})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
@@ -0,0 +1,35 @@
(ns status-im2.contexts.quo-preview.buttons.wallet-button
(:require
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Disabled?:"
:key :disabled?
:type :boolean}])
(defn cool-preview
[]
(let [state (reagent/atom {:icon :i/placeholder
:on-press #(js/alert "pressed")
:on-long-press #(js/alert "long pressed")})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:flex 1 :padding-bottom 20}
[rn/view {:height 200}
[preview/customizer state descriptor]]
[rn/view
{:flex 1
:align-items :center
:justify-content :center}
[quo/wallet-button @state]]]])))
(defn preview
[]
[rn/view
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}
[cool-preview]])
@@ -0,0 +1,30 @@
(ns status-im2.contexts.quo-preview.buttons.wallet-ctas
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn cool-preview
[]
(let [state (reagent/atom {:buy-action #(js/alert "Buy button pressed")
:send-action #(js/alert "Send button pressed")
:receive-action #(js/alert "Receive button pressed")
:bridge-action #(js/alert "Bridge button pressed")})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:style {:padding-bottom 150}}
[rn/view
{:style {:padding-vertical 60
:flex-direction :row
:justify-content :center}}
[quo/wallet-ctas @state]]]])))
(defn preview
[]
[rn/view
{:style {:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
@@ -1,48 +1,26 @@
(ns status-im2.contexts.quo-preview.colors.color-picker
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Color:"
:key :color
[{:key :selected
:type :select
:options (map (fn [color]
(let [k (get color :name)]
{:key k :value k}))
(quo/picker-colors))}
{:label "Blur?"
:key :blur
:type :boolean}])
{:key :blur?
:type :boolean}])
(defn cool-preview
(defn view
[]
(let [state (reagent/atom {:color "orange" :blur false})
blur (reagent/cursor state [:blur])
color (reagent/cursor state [:color])]
(let [state (reagent/atom {:selected :orange
:blur? false})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[(if @blur blur/view :<>)
[rn/view {:padding-vertical 60 :align-items :center}
[quo/color-picker
{:blur? @blur
:selected @color
:on-change #(reset! color %)}]]]]])))
(defn preview-color-picker
[]
[rn/view
{:background-color (colors/theme-colors
colors/white
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true}
[quo/color-picker (assoc @state :on-change #(swap! state assoc :selected %))]])))
@@ -1,54 +1,29 @@
(ns status-im2.contexts.quo-preview.dividers.divider-label
(:require [quo2.components.dividers.divider-label :as divider-label]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
(:require [quo2.core :as quo]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Label:"
:key :label
:type :text}
{:label "Chevron position:"
:key :chevron-position
[{:type :text :key :label}
{:type :text :key :counter-value}
{:type :boolean :key :increase-padding-top?}
{:type :boolean :key :blur?}
{:key :chevron-position
:type :select
:options [{:key :left
:value "Left"}
{:key :right
:value "Right"}]}
{:label "Counter value:"
:key :counter-value
:type :text}
{:label "Increase padding top:"
:key :increase-padding-top?
:type :boolean}
{:label "Blur:"
:key :blur?
:type :boolean}])
:options [{:key :left}
{:key :right}]}])
(defn cool-preview
(defn view
[]
(let [state (reagent/atom {:label "Welcome"
(let [state (reagent/atom {:blur? false
:chevron-position :left
:counter-value 0
:counter-value "0"
:increase-padding-top? true
:blur? false})]
:label "Welcome"})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60}
[divider-label/divider-label @state]]]])))
(defn preview-divider-label
[]
[rn/view
{:background-color (colors/theme-colors
colors/white
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:blur? @state)
:show-blur-background? true}
[quo/divider-label @state]])))
@@ -0,0 +1,49 @@
(ns status-im2.contexts.quo-preview.dropdowns.network-dropdown
(:require [quo2.foundations.resources :as quo.resources]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]
[quo2.core :as quo]))
(def descriptor
[{:key :state
:type :select
:options [{:key :default
:value "Default"}
{:key :disabled
:value "Disabled"}]}
{:key :blur?
:type :select
:options [{:key true
:value "True"}
{:key false
:value "False"}]}
{:key :amount
:type :select
:options [{:key 1
:value 1}
{:key 2
:value 2}
{:key 3
:value 3}]}])
(def ^:private networks-list
[{:source (quo.resources/get-network :ethereum)}
{:source (quo.resources/get-network :optimism)}
{:source (quo.resources/get-network :arbitrum)}])
(defn preview-dropdown
[]
(let [component-state (reagent/atom {:state :default :blur? false :amount 3})]
(fn []
[preview/preview-container
{:state component-state
:descriptor descriptor
:blur? (:blur? @component-state)
:show-blur-background? true}
[rn/view {:style {:align-self :center}}
[quo/network-dropdown
(merge {:on-press #(js/alert "Dropdown pressed")}
@component-state)
(take (:amount @component-state) networks-list)]]])))
@@ -1,21 +1,44 @@
(ns status-im2.contexts.quo-preview.gradient.gradient-cover
(:require [quo2.components.colors.color-picker.view :as color-picker]
[quo2.components.gradient.gradient-cover.view :as gradient-cover]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]))
[status-im2.contexts.quo-preview.preview :as preview]
[utils.re-frame :as rf]))
(defn render-action-sheet
[]
[:<>
[rn/view {:style {:align-items :center}}
[quo/summary-info
{:type :status-account
:networks? false
:account-props {:customization-color :purple
:size 32
:emoji "🍑"
:type :default
:name "Collectibles vault"
:address "0x0ah...78b"}}]]
[quo/action-drawer
[[{:icon :i/edit
:label "Edit account"
:on-press #(js/alert "Edit account")}
{:icon :i/copy
:label "Copy address"
:on-press #(js/alert "Copy address")}
{:icon :i/share
:label "Share account"
:on-press #(js/alert "Share account")}
{:icon :i/delete
:label "Remove account"
:danger? true
:on-press #(js/alert "Remove account")}]]]])
(def descriptor
[{:label "Customization color:"
:key :customization-color
:type :select
:options (mapv (fn [color]
{:key color :value color})
color-picker/color-list)}
[(preview/customization-color-option)
{:label "Blur (dark only)?"
:key :blur?
:type :boolean}])
@@ -51,14 +74,21 @@
:bottom 0
:padding-vertical 40}
:blur-type :dark}
[gradient-cover/view @state]]]
[quo/gradient-cover @state]]]
[rn/view
{:style {:padding-vertical 20
:padding-horizontal 16}}
[color-picker/view
[quo/color-picker
{:blur? @blur?
:selected @customization-color
:on-change #(reset! customization-color %)}]]])]))
:on-change #(reset! customization-color %)}]]
[quo/button
{:container-style {:margin-horizontal 40}
:on-press #(rf/dispatch [:show-bottom-sheet
{:content (fn [] [render-action-sheet])
:gradient-cover? true
:customization-color @customization-color}])}
"See in bottom sheet"]])]))
(defn preview-gradient-cover
[]
@@ -1,100 +1,56 @@
(ns status-im2.contexts.quo-preview.links.link-preview
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
(:require [quo2.core :as quo]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]
utils.number))
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Title"
:key :title
:type :text}
{:label "Description"
:key :description
:type :text}
{:label "Link"
:key :link
:type :text}
{:label "Container width"
:key :width
:type :text}
{:label "With logo?"
:key :with-logo?
:type :boolean}
{:label "With description?"
:key :with-description?
:type :boolean}
{:label "With thumbnail?"
:key :with-thumbnail?
:type :boolean}
{:label "Disabled text"
:key :disabled-text
:type :text}
{:label "Enabled?"
:key :enabled?
:type :boolean}
{:label "Thumbnail"
:key :thumbnail
[{:type :text :key :title}
{:type :text :key :description}
{:type :text :key :link}
{:type :number :key :width}
{:type :boolean :key :with-logo?}
{:type :boolean :key :with-description?}
{:type :boolean :key :with-thumbnail?}
{:type :text :key :disabled-text}
{:type :boolean :key :enabled?}
{:key :thumbnail
:type :select
:options (mapv (fn [k]
{:key k
:value (string/capitalize (name k))})
:options (mapv (fn [k] {:key k})
(keys resources/mock-images))}
{:label "Thumbnail size"
:key :thumbnail-size
{:key :thumbnail-size
:type :select
:options [{:key :normal
:value :normal}
{:key :large
:value :large}]}])
:options [{:key :normal}
{:key :large}]}])
(defn cool-preview
(defn view
[]
(let [state (reagent/atom
{:title "Rarible - NFT Marketplace"
:description "Turn your products or services into publicly tradeable items"
{:description "Turn your products or services into publicly tradeable items"
:disabled-text "Enable Preview"
:enabled? true
:link "rarible.com"
:thumbnail :collectible
:width "295"
:with-logo? true
:with-thumbnail? true
:with-description? true
:enabled? true
:thumbnail-size :normal
:disabled-text "Enable Preview"})]
:title "Rarible - NFT Marketplace"
:width 295
:with-description? true
:with-logo? true
:with-thumbnail? true})]
(fn []
(let [width (utils.number/parse-int (:width @state) 295)
thumbnail (get resources/mock-images (:thumbnail @state))]
[rn/view {:style {:margin-bottom 20}}
[preview/customizer state descriptor]
[rn/view
{:style {:align-items :center
:margin-top 20}}
[quo/link-preview
{:logo (when (:with-logo? @state)
(resources/get-mock-image :status-logo))
:title (:title @state)
:description (when (:with-description? @state)
(:description @state))
:enabled? (:enabled? @state)
:on-enable #(js/alert "Button pressed")
:disabled-text (:disabled-text @state)
:link (:link @state)
:thumbnail (when (:with-thumbnail? @state)
thumbnail)
:thumbnail-size (:thumbnail-size @state)
:container-style {:width width}}]]]))))
(defn preview
[]
[rn/view
{:style {:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)
:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
(let [thumbnail (get resources/mock-images (:thumbnail @state))]
[preview/preview-container {:state state :descriptor descriptor}
[quo/link-preview
{:logo (when (:with-logo? @state)
(resources/get-mock-image :status-logo))
:title (:title @state)
:description (when (:with-description? @state)
(:description @state))
:enabled? (:enabled? @state)
:on-enable #(js/alert "Button pressed")
:disabled-text (:disabled-text @state)
:link (:link @state)
:thumbnail (when (:with-thumbnail? @state)
thumbnail)
:thumbnail-size (:thumbnail-size @state)
:container-style {:width (:width @state)}}]]))))
@@ -1,30 +1,18 @@
(ns status-im2.contexts.quo-preview.links.url-preview
(:require
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Title"
:key :title
:type :text}
{:label "Body"
:key :body
:type :text}
{:label "With logo?"
:key :with-logo?
:type :boolean}
{:label "Loading?"
:key :loading?
:type :boolean}
{:label "Loading message"
:key :loading-message
:type :text}])
[{:type :text :key :title}
{:type :text :key :body}
{:type :boolean :key :with-logo?}
{:type :boolean :key :loading?}
{:type :text :key :loading-message}])
(defn cool-preview
(defn view
[]
(let [state (reagent/atom
{:title "Status - Private, Secure Communication"
@@ -33,29 +21,12 @@
:loading? false
:loading-message "Generating preview"})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:style {:padding-bottom 150}}
[preview/customizer state descriptor]
[rn/view
{:style {:align-items :center
:padding-horizontal 16
:margin-top 50}}
[quo/url-preview
{:title (:title @state)
:body (:body @state)
:logo (when (:with-logo? @state)
(resources/get-mock-image :status-logo))
:loading? (:loading? @state)
:loading-message (:loading-message @state)
:on-clear #(js/alert "Clear button pressed")}]]]])))
(defn preview
[]
[rn/view
{:style {:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
[preview/preview-container {:state state :descriptor descriptor}
[quo/url-preview
{:title (:title @state)
:body (:body @state)
:logo (when (:with-logo? @state)
(resources/get-mock-image :status-logo))
:loading? (:loading? @state)
:loading-message (:loading-message @state)
:on-clear #(js/alert "Clear button pressed")}]])))
@@ -1,50 +1,34 @@
(ns status-im2.contexts.quo-preview.links.url-preview-list
(:require
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]
utils.number))
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:label "Number of previews"
:key :previews-length
:type :text}])
[{:type :number :key :previews-length}])
(defn cool-preview
(defn view
[]
(let [state (reagent/atom {:previews-length "3"})]
(let [state (reagent/atom {:previews-length 3})
padding 20]
(fn []
(let [previews-length (min 6 (utils.number/parse-int (:previews-length @state)))
padding 20]
[rn/view {:style {:padding-bottom 150}}
[preview/customizer state descriptor]
[rn/view
{:style {:align-items :center
:margin-top 50}}
[quo/url-preview-list
{:horizontal-spacing padding
:preview-width (- (:width (rn/get-window))
(* 2 padding))
:on-clear #(js/alert "Clear button pressed")
:key-fn :url
:data (for [index (range previews-length)
:let [index (inc index)]]
{:title (str "Title " index)
:body (str "status.im." index)
:logo (resources/get-mock-image :status-logo)
:loading? false
:url (str "status.im." index)})}]]]))))
(defn preview
[]
[rn/view
{:style {:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
[preview/preview-container
{:state state
:descriptor descriptor
:component-container-style {:padding-horizontal 0}}
[quo/url-preview-list
{:horizontal-spacing padding
:preview-width (- (:width (rn/get-window))
(* 2 padding))
:on-clear #(js/alert "Clear button pressed")
:key-fn :url
:data (for [index (range (:previews-length @state))
:let [index (inc index)]]
{:title (str "Title " index)
:body (str "status.im." index)
:logo (resources/get-mock-image
:status-logo)
:loading? false
:url (str "status.im." index)})}]])))
@@ -2,39 +2,33 @@
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.community.data :as data]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor-type
{:label "Type:"
{:type :select
:key :type
:type :select
:options [{:key :discover :value "Discover"}
{:key :engage :value "Engage"}
{:key :share :value "Share"}]})
:options [{:key :discover}
{:key :engage}
{:key :share}]})
(def descriptor-locked
{:label "Locked?" :key :locked? :type :boolean})
{:type :boolean :key :locked?})
(def descriptor-unread-count
{:label "Unread count:" :key :unread-count :type :number})
{:type :number :key :unread-count})
(def descriptor-title
{:label "Title:" :key :title :type :text})
{:type :text :key :title})
(def descriptor-blur
{:label "Blur?" :key :blur? :type :boolean})
{:type :boolean :key :blur?})
(def descriptor-member-stats
[{:label "Total member count:"
:key :members-count
:type :number}
{:label "Active member count:"
:key :active-count
:type :number}])
[{:type :number :key :members-count}
{:type :number :key :active-count}])
(def descriptors-base
[descriptor-type
@@ -43,29 +37,27 @@
(def descriptors-type-discover
(conj descriptors-base
{:label "Info:"
{:type :select
:key :info
:type :select
:options [{:key :token-gated :value "Token gated"}
{:key :default :value "Default"}]}
:options [{:key :token-gated}
{:key :default}]}
{:label "Member stats?"
:key :members?
:type :boolean}))
:type :boolean
:key :members?}))
(def descriptors-type-engage
(conj descriptors-base
{:label "Info:"
{:type :select
:key :info
:type :select
:options [{:key :notification :value "Notification"}
{:key :mention :value "Mention"}
{:key :muted :value "Muted"}
{:key :token-gated :value "Token gated"}
{:key :navigation :value "Navigation"}
{:key :default :value "Default"}]}))
:options [{:key :notification}
{:key :mention}
{:key :muted}
{:key :token-gated}
{:key :navigation}
{:key :default}]}))
(def descriptors-type-share
(conj descriptors-base {:label "Subtitle:" :key :subtitle :type :text}))
(conj descriptors-base {:type :text :key :subtitle}))
(defn descriptors
[{:keys [members? info] :as state}]
@@ -88,7 +80,7 @@
(into [descriptor-blur] descs)
descs)))
(defn cool-preview
(defn view
[]
(let [state (reagent/atom {:blur? false
:customization-color :blue
@@ -103,30 +95,16 @@
:unread-count 5})]
(fn []
(let [customization-color (colors/custom-color-by-theme (:customization-color @state) 50 60)]
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:style {:margin-bottom 20}}
[preview/customizer state (descriptors @state)]
[rn/view {:style {:margin-vertical 30 :align-items :center}}
[quo/community-list-item
(merge @state
{:container-style {:width 335}
:logo (resources/get-mock-image :status-logo)
:tokens (:tokens data/community)
:customization-color customization-color
:on-press #(js/alert "List item pressed")
:on-long-press #(js/alert "Long pressed item")
:on-press-info #(js/alert "Info pressed")
:members (when (:members? @state)
{:members-count (:members-count @state)
:active-count (:active-count @state)})})]]]]))))
(defn preview
[]
[rn/view
{:style {:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)
:flex 1}}
[rn/flat-list
{:style {:flex 1}
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
[preview/preview-container {:state state :descriptor (descriptors @state)}
[quo/community-list-item
(merge @state
{:container-style {:width 335}
:logo (resources/get-mock-image :status-logo)
:tokens (:tokens data/community)
:customization-color customization-color
:on-press #(js/alert "List item pressed")
:on-long-press #(js/alert "Long pressed item")
:on-press-info #(js/alert "Info pressed")
:members (when (:members? @state)
{:members-count (:members-count @state)
:active-count (:active-count @state)})})]]))))
@@ -1,6 +1,7 @@
(ns status-im2.contexts.quo-preview.list-items.preview-lists
(:require [quo2.components.list-items.preview-list :as quo2]
[quo2.foundations.colors :as colors]
[quo2.foundations.resources :as quo.resources]
[react-native.core :as rn]
[reagent.core :as reagent]
[utils.i18n :as i18n]
@@ -23,7 +24,9 @@
:options [{:key :user
:value "User"}
{:key :photo
:value "Photo"}]}
:value "Photo"}
{:key :network
:value "Network"}]}
{:label "List Size"
:key :list-size
:default 10
@@ -44,6 +47,11 @@
{:source (resources/get-mock-image :photo2)}
{:source (resources/get-mock-image :photo3)}])
(def networks-list
[{:source (quo.resources/get-network :ethereum)}
{:source (quo.resources/get-network :optimism)}
{:source (quo.resources/get-network :arbitrum)}])
(defn cool-preview
[]
(let [state (reagent/atom {:type :user
@@ -60,8 +68,9 @@
:align-items :center}
[quo2/preview-list @state
(case @type
:user user-list
:photo photos-list)]]]])))
:user user-list
:photo photos-list
:network networks-list)]]]])))
(defn preview-preview-lists
[]
+66 -158
View File
@@ -2,9 +2,9 @@
(:refer-clojure :exclude [filter])
(:require
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[react-native.core :as rn]
[status-im2.contexts.quo-preview.style :as style]
[status-im2.common.theme.core :as theme]
[status-im2.contexts.quo-preview.animated-header-list.animated-header-list :as animated-header-list]
[status-im2.contexts.quo-preview.avatars.account-avatar :as account-avatar]
@@ -20,6 +20,8 @@
[status-im2.contexts.quo-preview.buttons.slide-button :as slide-button]
[status-im2.contexts.quo-preview.buttons.dynamic-button :as dynamic-button]
[status-im2.contexts.quo-preview.buttons.predictive-keyboard :as predictive-keyboard]
[status-im2.contexts.quo-preview.buttons.wallet-button :as wallet-button]
[status-im2.contexts.quo-preview.buttons.wallet-ctas :as wallet-ctas]
[status-im2.contexts.quo-preview.calendar.calendar :as calendar]
[status-im2.contexts.quo-preview.calendar.calendar-day :as calendar-day]
[status-im2.contexts.quo-preview.calendar.calendar-year :as calendar-year]
@@ -43,6 +45,7 @@
[status-im2.contexts.quo-preview.drawers.drawer-buttons :as drawer-buttons]
[status-im2.contexts.quo-preview.drawers.permission-drawers :as permission-drawers]
[status-im2.contexts.quo-preview.dropdowns.dropdown :as dropdown]
[status-im2.contexts.quo-preview.dropdowns.network-dropdown :as network-dropdown]
[status-im2.contexts.quo-preview.foundations.shadows :as shadows]
[status-im2.contexts.quo-preview.info.info-message :as info-message]
[status-im2.contexts.quo-preview.info.information-box :as information-box]
@@ -110,8 +113,10 @@
[status-im2.contexts.quo-preview.gradient.gradient-cover :as gradient-cover]
[status-im2.contexts.quo-preview.wallet.account-overview :as account-overview]
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]
[status-im2.contexts.quo-preview.wallet.keypair :as keypair]
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
[status-im2.contexts.quo-preview.wallet.network-bridge :as network-bridge]
[status-im2.contexts.quo-preview.wallet.network-link :as network-link]
[status-im2.contexts.quo-preview.wallet.progress-bar :as progress-bar]
[status-im2.contexts.quo-preview.wallet.summary-info :as summary-info]
[status-im2.contexts.quo-preview.wallet.token-input :as token-input]
@@ -120,344 +125,244 @@
(def screens-categories
{:foundations [{:name :shadows
:options {:topBar {:visible true}}
:component shadows/preview-shadows}]
:animated-list [{:name :animated-header-list
:options {:topBar {:visible false}}
:component animated-header-list/mock-screen}]
:avatar [{:name :group-avatar
:options {:topBar {:visible true}}
:component group-avatar/preview-group-avatar}
{:name :icon-avatar
:options {:topBar {:visible true}}
:component icon-avatar/preview-icon-avatar}
{:name :user-avatar
:options {:topBar {:visible true}}
:component user-avatar/preview-user-avatar}
{:name :wallet-user-avatar
:options {:topBar {:visible true}}
:component wallet-user-avatar/preview-wallet-user-avatar}
{:name :channel-avatar
:options {:topBar {:visible true}}
:component channel-avatar/preview-channel-avatar}
{:name :account-avatar
:options {:topBar {:visible true}}
:component account-avatar/preview-account-avatar}]
:banner [{:name :banner
:options {:topBar {:visible true}}
:component banner/preview-banner}]
:buttons [{:name :button
:options {:topBar {:visible true}}
:component button/preview-button}
{:name :composer-button
:options {:topBar {:visible true}}
:component composer-button/preview-composer-button}
{:name :dynamic-button
:options {:topBar {:visible true}}
:component dynamic-button/preview-dynamic-button}
{:name :slide-button
:options {:topBar {:visible true}}
:component slide-button/preview-slide-button}
{:name :predictive-keyboard
:options {:topBar {:visible true}}
:component predictive-keyboard/preview-predictive-keyboard}]
:component predictive-keyboard/preview-predictive-keyboard}
{:name :wallet-button
:component wallet-button/preview}
{:name :wallet-ctas
:component wallet-ctas/preview}]
:browser [{:name :browser-input
:options {:topBar {:visible false}}
:component browser-input/preview-browser-input}]
:calendar [{:name :calendar
:options {:topBar {:visible true}}
:component calendar/preview-calendar}
{:name :calendar-day
:options {:topBar {:visible true}}
:component calendar-day/preview-calendar-day}
{:name :calendar-year
:options {:topBar {:visible true}}
:component calendar-year/preview-calendar-year}]
:code [{:name :snippet
:options {:topBar {:visible true}}
:component code-snippet/preview-code-snippet}]
:colors [{:name :color-picker
:options {:topBar {:visible true}}
:component color-picker/preview-color-picker}]
:component color-picker/view}]
:community [{:name :community-card-view
:options {:topBar {:visible true}}
:component community-card/preview-community-card}
{:name :community-membership-list-view
:options {:topBar {:visible true}}
:component community-membership-list-view/preview-community-list-view}
{:name :discover-card
:options {:topBar {:visible true}}
:component discover-card/preview-discoverd-card}
{:name :token-gating
:options {:insets {:bottom? true}
:topBar {:visible true}}
:options {:insets {:bottom? true}}
:component token-gating/preview-token-gating}
{:name :channel-actions
:options {:insets {:bottom? true}
:topBar {:visible true}}
:options {:insets {:bottom? true}}
:component channel-actions/preview-channel-actions}]
:counter [{:name :counter
:options {:topBar {:visible true}}
:component counter/preview-counter}
{:name :step
:options {:topBar {:visible true}}
:component step/preview-step}]
:dividers [{:name :divider-label
:options {:topBar {:visible true}}
:component divider-label/preview-divider-label}
:component divider-label/view}
{:name :new-messages
:options {:topBar {:visible true}}
:component new-messages/preview-new-messages}
{:name :divider-date
:options {:topBar {:visible true}}
:component divider-date/preview-divider-date}
{:name :strength-divider
:options {:topBar {:visible true}}
:component strength-divider/preview-strength-divider}]
:drawers [{:name :action-drawers
:options {:topBar {:visible true}}
:component action-drawers/preview-action-drawers}
{:name :documentation-drawer
:options {:topBar {:visible true}}
:component documenation-drawers/preview-documenation-drawers}
{:name :drawer-buttons
:options {:topBar {:visible true}}
:component drawer-buttons/preview-drawer-buttons}
{:name :permission-drawers
:options {:topBar {:visible true}}
:component permission-drawers/preview-permission-drawers}]
:dropdowns [{:name :dropdown
:options {:topBar {:visible true}}
:component dropdown/preview-dropdown}]
:component dropdown/preview-dropdown}
{:name :network-dropdown
:component network-dropdown/preview-dropdown}]
:empty-state [{:name :empty-state
:options {:topBar {:visible true}}
:component empty-state/preview-empty-state}]
:gradient [{:name :gradient-cover
:options {:topBar {:visible true}}
:component gradient-cover/preview-gradient-cover}]
:graph [{:name :wallet-graph
:options {:topBar {:visible true}}
:component wallet-graph/preview-wallet-graph}]
:info [{:name :info-message
:options {:topBar {:visible true}}
:component info-message/preview-info-message}
{:name :information-box
:options {:topBar {:visible true}}
:component information-box/preview-information-box}]
:inputs [{:name :input
:options {:topBar {:visible true}}
:component input/preview-input}
{:name :locked-input
:options {:topBar {:visible true}}
:component locked-input/preview-locked-input}
{:name :profile-input
:options {:topBar {:visible true}}
:component profile-input/preview-profile-input}
{:name :recovery-phrase-input
:options {:topBar {:visible true}}
:component recovery-phrase-input/preview-recovery-phrase-input}
{:name :search-input
:options {:topBar {:visible true}}
:component search-input/preview-search-input}
{:name :title-input
:options {:topBar {:visible true}}
:component title-input/preview-title-input}]
:numbered-keyboard [{:name :keyboard-key
:options {:insets {:top? true}
:topBar {:visible true}}
:options {:insets {:top? true}}
:component keyboard-key/preview-keyboard-key}
{:name :numbered-keyboard
:options {:insets {:top? true}
:topBar {:visible true}}
:options {:insets {:top? true}}
:component numbered-keyboard/preview-numbered-keyboard}]
:links [{:name :url-preview
:options {:insets {:top? true}
:topBar {:visible true}}
:component url-preview/preview}
:options {:insets {:top? true}}
:component url-preview/view}
{:name :url-preview-list
:options {:insets {:top? true}
:topBar {:visible true}}
:component url-preview-list/preview}
:options {:insets {:top? true}}
:component url-preview-list/view}
{:name :link-preview
:options {:insets {:top? true}
:topBar {:visible true}}
:component link-preview/preview}]
:options {:insets {:top? true}}
:component link-preview/view}]
:list-items [{:name :account-list-card
:options {:topBar {:visible true}}
:component account-list-card/preview}
{:name :channel
:options {:topBar {:visible true}}
:component channel/preview-channel}
{:name :community-list
:options {:insets {:top? true}
:topBar {:visible true}}
:component community-list/preview}
:options {:insets {:top? true}}
:component community-list/view}
{:name :preview-lists
:options {:topBar {:visible true}}
:component preview-lists/preview-preview-lists}
{:name :user-list
:options {:topBar {:visible true}}
:component user-list/preview-user-list}
{:name :token-value
:options {:topBar {:visible true}}
:component token-value/preview}]
:loaders [{:name :skeleton
:options {:topBar {:visible true}}
:component skeleton/preview-skeleton}]
:markdown [{:name :texts
:options {:topBar {:visible true}}
:component text/preview-text}
{:name :markdown-list
:options {:topBar {:visible true}}
:component markdown-list/preview-markdown-list}]
:messages [{:name :gap
:options {:topBar {:visible true}}
:component messages-gap/preview-messages-gap}
{:name :system-messages
:options {:topBar {:visible true}}
:component system-message/preview-system-message}
{:name :author
:options {:topBar {:visible true}}
:component messages-author/preview-author}]
:navigation [{:name :bottom-nav-tab
:options {:topBar {:visible true}}
:component bottom-nav-tab/preview-bottom-nav-tab}
{:name :top-nav
:options {:topBar {:visible true}}
:component top-nav/preview-top-nav}
{:name :page-nav
:options {:topBar {:visible true}}
:component page-nav/preview-page-nav}
{:name :floating-shell-button
:options {:topBar {:visible true}}
:component floating-shell-button/preview-floating-shell-button}]
:notifications [{:name :activity-logs
:options {:topBar {:visible true}}
:component activity-logs/preview-activity-logs}
{:name :activity-logs-photos
:options {:topBar {:visible true}}
:component activity-logs-photos/preview-activity-logs-photos}
{:name :toast
:options {:topBar {:visible true}}
:component toast/preview-toasts}
{:name :notification
:options {:topBar {:visible true}}
:component notification/preview-notification}]
:onboarding [{:name :small-option-card
:options {:topBar {:visible true}}
:component small-option-card/preview-small-option-card}]
:password [{:name :tips
:options {:topBar {:visible true}}
:component tips/preview-tips}]
:profile [{:name :profile-card
:options {:topBar {:visible true}}
:component profile-card/preview-profile-card}
{:name :collectible
:options {:topBar {:visible true}}
:component collectible/preview-collectible}
{:name :select-profile
:options {:topBar {:visible true}}
:component select-profile/preview-select-profile}]
:reactions [{:name :react
:options {:topBar {:visible true}}
:component react/preview-react}]
:record-audio [{:name :record-audio
:options {:topBar {:visible true}}
:component record-audio/preview-record-audio}]
:switcher [{:name :switcher-cards
:options {:topBar {:visible true}}
:component switcher-cards/preview-switcher-cards}]
:selectors [{:name :disclaimer
:options {:topBar {:visible true}}
:component disclaimer/preview-disclaimer}
{:name :filter
:options {:topBar {:visible true}}
:component filter/preview}
{:name :selectors
:options {:topBar {:visible true}}
:component selectors/preview-selectors}
{:name :select-reactions
:options {:topBar {:visible true}}
:component selector-reactions/preview}]
:settings [{:name :privacy-option
:options {:topBar {:visible true}}
:component privacy-option/preview-options}
{:name :accounts
:options {:topBar {:visible true}}
:component accounts/preview-accounts}
{:name :settings-list
:options {:topBar {:visible true}}
:component settings-list/preview-settings-list}
{:name :reorder-item
:options {:topBar {:visible true}}
:component reorder-item/preview-reorder-item}
{:name :category
:options {:topBar {:visible true}}
:component category/preview}]
:share [{:name :qr-code
:options {:topBar {:visible true}}
:component qr-code/preview-qr-code}
{:name :share-qr-code
:options {:topBar {:visible true}}
:component share-qr-code/preview-share-qr-code}]
:tabs [{:name :segmented
:options {:topBar {:visible true}}
:component segmented/preview-segmented}
{:name :tabs
:options {:topBar {:visible true}}
:component tabs/preview-tabs}
{:name :account-selector
:options {:topBar {:visible true}}
:component account-selector/preview-this}]
:tags [{:name :context-tags
:options {:topBar {:visible true}}
:component context-tags/preview-context-tags}
{:name :tags
:options {:topBar {:visible true}}
:component tags/preview-tags}
{:name :permission-tag
:options {:topBar {:visible true}}
:component permission-tag/preview-permission-tag}
{:name :status-tags
:options {:topBar {:visible true}}
:component status-tags/preview-status-tags}
{:name :token-tag
:options {:topBar {:visible true}}
:component token-tag/preview-token-tag}]
:text-combinations [{:name :title
:options {:topBar {:visible true}}
:component title/preview-title}]
:wallet [{:name :account-card
:options {:topBar {:visible true}}
:component account-card/preview-account-card}
{:name :account-overview
:options {:topBar {:visible true}}
:component account-overview/preview-account-overview}
{:name :network-amount
{:name :keypair
:options {:topBar {:visible true}}
:component keypair/preview}
{:name :network-amount
:component network-amount/preview}
{:name :network-bridge
:options {:topBar {:visible true}}
:component network-bridge/preview}
{:name :network-link
:component network-link/preview}
{:name :progress-bar
:options {:topBar {:visible true}}
:component progress-bar/preview}
{:name :summary-info
:options {:topBar {:visible true}}
:component summary-info/preview}
{:name :token-input
:options {:topBar {:visible true}}
:component token-input/preview}
{:name :wallet-overview
:options {:topBar {:visible true}}
:component wallet-overview/preview-wallet-overview}]
:keycard [{:name :keycard-component
:options {:topBar {:visible true}}
:component keycard/preview-keycard}]})
(def screens (flatten (map val screens-categories)))
(defn navigation-bar
(defn- navigation-bar
[]
(let [logged-in? (rf/sub [:multiaccount/logged-in?])
has-profiles? (boolean (rf/sub [:profile/profiles-overview]))
@@ -477,48 +382,51 @@
(theme/set-theme :dark)
(rf/dispatch [:init-root root]))))}}]))
(defn theme-switcher
(defn- theme-switcher
[]
[rn/view
{:style {:flex-direction :row
:justify-content :space-between
:padding-horizontal 24
:padding-vertical 12}}
[rn/view {:style style/theme-switcher}
[quo/button {:on-press #(theme/set-theme :light)} "Set light theme"]
[quo/button {:on-press #(theme/set-theme :dark)} "Set dark theme"]])
(defn category-view
(defn- category-view
[]
(let [open? (reagent/atom false)]
(let [open? (reagent/atom false)
on-change #(swap! open? not)]
(fn [category]
[rn/view {:style {:margin-vertical 8}}
[quo/dropdown {:selected @open? :on-change #(swap! open? not) :type :grey}
(clojure.core/name (key category))]
[quo/dropdown
{:selected @open?
:on-change on-change
:type :grey}
(name (key category))]
(when @open?
(for [{:keys [name]} (val category)]
^{:key name}
(for [{category-name :name} (val category)]
^{:key category-name}
[quo/button
{:type :outline
:container-style {:margin-vertical 8}
:on-press #(rf/dispatch [:navigate-to name])}
(clojure.core/name name)]))])))
:on-press #(rf/dispatch [:navigate-to category-name])}
(name category-name)]))])))
(defn main-screen
(defn- main-screen
[]
(fn []
[:<>
[navigation-bar]
[theme-switcher]
[rn/scroll-view
{:flex 1
:padding-bottom 8
:padding-horizontal 16
:background-color (colors/theme-colors colors/white colors/neutral-90)}
[rn/view
(map (fn [category]
^{:key (get category 0)}
[category-view category])
(sort screens-categories))]]]))
[:<>
[navigation-bar]
[theme-switcher]
[rn/scroll-view {:style (style/main)}
(for [category (sort screens-categories)]
^{:key (first category)}
[category-view category])]])
(def screens
(->> screens-categories
(map val)
flatten
(map (fn [subcategory]
(update-in subcategory
[:options :topBar]
merge
{:visible true})))))
(def main-screens
[{:name :quo2-preview
@@ -1,8 +1,7 @@
(ns status-im2.contexts.quo-preview.navigation.floating-shell-button
(:require [quo2.components.navigation.floating-shell-button :as quo2]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -43,11 +42,6 @@
(= scroll-type :scroll-to-bottom)
(assoc :scroll-to-bottom {:on-press #()})))
(defn- f-shell-button
[state]
[quo2/floating-shell-button (mock-data state)
nil (reanimated/use-shared-value 1)])
(defn cool-preview
[]
(let [state (reagent/atom {:show-jump-to? true
@@ -59,7 +53,7 @@
[rn/view
{:padding-vertical 60
:align-items :center}
[:f> f-shell-button @state]]]])))
[quo/floating-shell-button (mock-data @state) nil]]]])))
(defn preview-floating-shell-button
[]
+163 -187
View File
@@ -1,216 +1,178 @@
(ns status-im2.contexts.quo-preview.preview
(:require [clojure.string :as string]
(:require [camel-snake-kebab.core :as camel-snake-kebab]
[clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.style :as style]
utils.number)
(:require-macros status-im2.contexts.quo-preview.preview))
(def container
{:flex-direction :row
:padding-vertical 8
:flex 1
:align-items :center})
(defn touchable-style
[]
{:flex 1
:align-items :center
:justify-content :center
:padding-horizontal 16
:height 44})
(defn select-style
[]
{:flex 1
:flex-direction :row
:align-items :center
:padding-horizontal 16
:height 44
:border-radius 4
:background-color colors/neutral-20
:border-width 1
:border-color colors/neutral-100})
(defn select-option-style
[selected]
(merge (select-style)
{:margin-vertical 8
:justify-content :center}
(if selected
{:background-color colors/primary-50-opa-30}
{:background-color (colors/theme-colors colors/neutral-20 colors/white)})))
(def label-style
{:flex 0.4
:padding-right 8})
(defn label-view
(defn- label-view
[_ label]
[rn/view {:style label-style}
[rn/text
(when-let [label-color (colors/theme-colors colors/neutral-100 colors/white)]
{:style {:color label-color}})
[rn/view {:style style/label-container}
[rn/text {:style (style/label)}
label]])
(defn modal-container
[]
{:flex 1
:justify-content :center
:padding-horizontal 24
:background-color "rgba(0,0,0,0.4)"})
(defn- humanize
[k]
;; We explicitly convert `k` to string because sometimes it's a number and
;; Clojure would throw an exception.
(-> (if (keyword? k) k (str k))
camel-snake-kebab/->kebab-case-keyword
name
(string/replace "-" " ")
string/capitalize))
(defn modal-view
[]
{:padding-horizontal 16
:padding-vertical 8
:border-radius 8
:flex-direction :column
:margin-vertical 100
:background-color (colors/theme-colors colors/neutral-20 colors/white)})
(defn- key->boolean-label
[k]
(let [label (humanize k)]
(if (string/ends-with? label "?")
label
(str label "?"))))
(defn customizer-boolean
(defn- key->text-label
[k]
(str (humanize k) ":"))
(defn- customizer-boolean
[{:keys [label state] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
(let [label (or label (key->boolean-label (:key args)))
field-value (reagent/cursor state [(:key args)])
active? @field-value]
[rn/view {:style style/field-row}
[label-view state label]
[rn/view
{:style {:flex-direction :row
:flex 0.6
:border-radius 4
:background-color (colors/theme-colors colors/neutral-20 colors/white)
:border-width 1
:border-color (colors/theme-colors colors/neutral-100 colors/white)}}
[rn/touchable-opacity
{:style (merge (touchable-style) {:background-color (when @state* colors/primary-50-opa-30)})
:on-press #(reset! state* true)}
[rn/text
[rn/view {:style (style/boolean-container)}
[rn/pressable
{:style (style/boolean-button {:active? active? :left? true})
:on-press #(reset! field-value true)}
[rn/text {:style (style/field-text active?)}
"True"]]
[rn/view
{:width 1
:margin-vertical 4
:background-color (colors/theme-colors colors/neutral-20 colors/white)}]
[rn/touchable-opacity
{:style (merge (touchable-style)
{:background-color (when (not @state*) colors/primary-50-opa-30)})
:on-press #(reset! state* false)}
[rn/text {}
[rn/pressable
{:style (style/boolean-button {:active? (not active?) :left? false})
:on-press #(reset! field-value false)}
[rn/text {:style (style/field-text (not active?))}
"False"]]]]))
(defn customizer-text
(defn- customizer-text
[{:keys [label state limit suffix] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[rn/view {:style style/field-row}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[rn/view {:style style/field-column}
[rn/text-input
(merge
{:value @state*
{:value @field-value
:show-cancel false
:style {:border-radius 4
:border-width 1
:color (colors/theme-colors colors/neutral-100 colors/white)
:border-color (colors/theme-colors colors/neutral-100 colors/white)}
:keyboard-appearance (theme/theme-value :light :dark)
:on-change-text #(do
(reset! state* (if (and suffix (> (count %) (count @state*)))
(str (string/replace % suffix "") suffix)
%))
(reagent/flush))}
:style (style/field-container false)
:keyboard-appearance (quo.theme/theme-value :light :dark)
:on-change-text (fn [text]
(reset! field-value (if (and suffix
(> (count text) (count @field-value)))
(str (string/replace text suffix "") suffix)
text))
(reagent/flush))}
(when limit
{:max-length limit}))]]]))
(defn customizer-number
(defn- customizer-number
[{:keys [label state default] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[rn/view {:style style/field-row}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[rn/view {:style style/field-column}
[rn/text-input
(merge
{:value (str @state*)
{:value (str @field-value)
:show-cancel false
:style {:border-radius 4
:border-width 1
:color (colors/theme-colors colors/neutral-100 colors/white)
:border-color (colors/theme-colors colors/neutral-100 colors/white)}
:keyboard-appearance (theme/theme-value :light :dark)
:on-change-text (fn [v]
(reset! state* (utils.number/parse-int v default))
:style (style/field-container false)
:keyboard-appearance (quo.theme/theme-value :light :dark)
:on-change-text (fn [text]
(reset! field-value (utils.number/parse-int text default))
(reagent/flush))})]]]))
(defn value-for-key
(defn- find-selected-option
[id v]
(:value (first (filter #(= (:key %) id) v))))
(first (filter #(= (:key %) id) v)))
(defn customizer-select
(defn- customizer-select-modal
[{:keys [open options field-value]}]
[rn/modal
{:visible @open
:on-request-close #(reset! open false)
:status-bar-translucent true
:transparent true
:animation :slide}
[rn/view {:style (style/modal-overlay)}
[rn/view {:style (style/modal-container)}
[rn/scroll-view {:shows-vertical-scroll-indicator false}
(doall
(for [{k :key v :value} options
:let [v (or v (humanize k))]]
^{:key k}
[rn/pressable
{:style (style/select-option (= @field-value k))
:on-press (fn []
(reset! open false)
(reset! field-value k))}
[rn/text {:style (style/field-text (= @field-value k))}
v]]))]
[rn/view {:style (style/footer)}
[rn/pressable
{:style (style/select-button)
:on-press (fn []
(reset! field-value nil)
(reset! open false))}
[rn/text {:style (style/field-text false)}
"Clear"]]
[rn/view {:style {:width 16}}]
[rn/touchable-opacity
{:style (style/select-button)
:on-press #(reset! open false)}
[rn/text {:style (style/field-text false)}
"Close"]]]]]])
(defn- customizer-select-button
[{:keys [open selected-key]}]
[rn/pressable
{:style (style/select-container)
:on-press #(reset! open true)}
[rn/text
{:style (style/field-select)
:number-of-lines 1}
(if selected-key
(humanize selected-key)
"Select option")]
[rn/view
[quo/icon :i/chevron-right]]])
(defn- customizer-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state options] :as args}]
(let [state* (reagent/cursor state [(:key args)])
selected (value-for-key @state* options)]
[rn/view {:style container}
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])
selected-key (:key (find-selected-option @field-value options))]
[rn/view {:style style/field-row}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[rn/modal
{:visible @open
:on-request-close #(reset! open false)
:statusBarTranslucent true
:transparent true
:animation :slide}
[rn/view {:style (modal-container)}
[rn/view {:style (modal-view)}
[rn/scroll-view
(doall
(for [{k :key v :value} options]
^{:key k}
[rn/touchable-opacity
{:style (select-option-style (= @state* k))
:on-press #(do
(reset! open false)
(reset! state* k))}
[rn/text {:color (if (= @state* k) :link :secondary)}
v]]))]
[rn/view
{:flex-direction :row
:padding-top 20
:margin-top 10
:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-100 colors/white)}
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(do
(reset! state* nil)
(reset! open false))}
[rn/text "Clear"]]
[rn/view {:width 16}]
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(reset! open false)}
[rn/text "Close"]]]]]]
[rn/touchable-opacity
{:style (select-style)
:on-press #(reset! open true)}
(if selected
[rn/text {:color :link} selected]
[rn/text "Select option"])
[rn/view
{:position :absolute
:right 16
:top 0
:bottom 0
:justify-content :center}
[rn/text "↓"]]]]]))))
[rn/view {:style style/field-column}
[customizer-select-modal
{:open open
:options options
:field-value field-value}]
[customizer-select-button {:open open :selected-key selected-key}]]]))))
(defn customizer
[state descriptors]
[rn/view
{:style {:flex 1}
:padding-horizontal 16}
{:style {:flex-shrink 1
:padding-horizontal 20}}
(doall
(for [desc descriptors
:let [descriptor (merge desc {:state state})]]
@@ -237,19 +199,6 @@
{:key k :value (string/capitalize (name k))})))}
opts)))
(comment
[{:label "Show error:"
:key :error
:type :boolean}
{:label "Label:"
:key :label
:type :text}
{:label "Type:"
:key :type
:type :select
:options [{:key :primary :value "Primary"}
{:key :secondary :value "Secondary"}]}])
(defn blur-view
[{:keys [show-blur-background? image height blur-view-props style]} children]
[rn/view
@@ -262,8 +211,7 @@
:overflow :hidden}}
[rn/image
{:source (or image (resources/get-mock-image :community-cover))
:style {:height "100%"
:width "100%"}}]
:style {:height "100%" :width "100%"}}]
[blur/view
(merge {:style {:position :absolute
:top 0
@@ -271,9 +219,7 @@
:left 0
:right 0}
:blur-amount 10
:overlay-color (colors/theme-colors
colors/white-opa-70
colors/neutral-80-opa-80)}
:overlay-color (colors/theme-colors colors/white-opa-70 colors/neutral-80-opa-80)}
blur-view-props)]])
[rn/view
{:style (merge {:position :absolute
@@ -281,3 +227,33 @@
:padding-horizontal 16}
style)}
children]])
(defn preview-container
[{:keys [state descriptor blur?
component-container-style
blur-container-style blur-view-props blur-height show-blur-background?]
:or {blur-height 200}}
component]
[rn/scroll-view
{:style (style/panel-basic)
:shows-vertical-scroll-indicator false}
[rn/pressable {:on-press rn/dismiss-keyboard!}
[rn/view {:style style/customizer-container}
[customizer state descriptor]]
[rn/view
(merge {:style style/component-container}
component-container-style)
(if blur?
[blur-view
{:show-blur-background? show-blur-background?
:height blur-height
:style (merge {:width "100%"
:flex-grow 1}
(when-not show-blur-background?
{:padding-horizontal 0
:top 0})
blur-container-style)
:blur-view-props (merge {:blur-type (quo.theme/get-theme)}
blur-view-props)}
component]
component)]]])
@@ -0,0 +1,179 @@
(ns status-im2.contexts.quo-preview.style
(:require [quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]))
;;;; Form fields
(def field-border-radius 12)
(def field-flex-percentage 0.6)
(def text-default typography/paragraph-1)
(defn field-active-bg-color
[]
(colors/theme-colors colors/primary-50 colors/primary-60))
(defn field-default-color
[]
(colors/theme-colors colors/neutral-100 colors/white))
(defn field-default-bg-color
[]
(colors/theme-colors colors/neutral-20 colors/neutral-80))
(defn field-default-border-color
[]
(colors/theme-colors colors/neutral-30 colors/neutral-70))
(def field-row
{:flex-direction :row
:padding-vertical 6
:align-items :center})
(def field-column
{:flex field-flex-percentage})
(defn field-container
[active?]
(merge text-default
{:color (if active?
(colors/theme-colors colors/white colors/white-opa-95)
(colors/theme-colors colors/neutral-100 colors/white))
:border-width 1
:border-color (field-default-border-color)
:border-radius field-border-radius
:padding-vertical 9
:padding-horizontal 12}))
(defn field-text
[active?]
(merge text-default
{:color (if active?
(colors/theme-colors colors/white colors/white-opa-95)
(field-default-color))}))
(def customizer-container
{:flex-shrink 1
:padding-top 12})
(defn select-container
[]
(merge (field-container false)
{:flex-direction :row
:align-items :center
:border-radius field-border-radius
:background-color (field-default-bg-color)
:border-width 1
:border-color (field-default-border-color)}))
(defn field-select
[]
(merge text-default
{:flex-grow 1
:color (field-default-color)}))
(defn select-option
[selected?]
(merge (field-container selected?)
{:justify-content :center
:flex 1
:margin-vertical 4}
(if selected?
{:border-color (field-active-bg-color)
:background-color (field-active-bg-color)}
{:background-color (field-default-bg-color)})))
(defn select-button
[]
(merge (select-option false) {:align-items :center}))
(def label-container
{:flex (- 1 field-flex-percentage)
:padding-right 8})
(defn label
[]
(merge text-default
typography/font-medium
{:color (field-default-color)}))
(defn boolean-container
[]
{:flex-direction :row
:flex field-flex-percentage
:border-radius field-border-radius})
(defn boolean-button
[{:keys [active? left?]}]
(cond-> {:flex 1
:align-items :center
:justify-content :center
:padding-vertical 9
:padding-horizontal 12
:border-color (if active?
(field-active-bg-color)
(field-default-border-color))
:border-top-width 1
:border-bottom-width 1
:background-color (if active?
(field-active-bg-color)
(field-default-bg-color))}
left?
(assoc :border-top-left-radius field-border-radius
:border-bottom-left-radius field-border-radius
:border-left-width 1)
(not left?)
(assoc :border-top-right-radius field-border-radius
:border-bottom-right-radius field-border-radius
:border-right-width 1)))
;;;; Modal
(defn modal-overlay
[]
{:flex 1
:justify-content :center
:padding-horizontal 24
:background-color (colors/theme-colors colors/neutral-80-opa-60 colors/neutral-80-opa-80)})
(defn modal-container
[]
{:padding-horizontal 16
:padding-vertical 8
:border-radius 12
:margin-vertical 100
:background-color (colors/theme-colors colors/white colors/neutral-95)})
(defn footer
[]
{:flex-direction :row
:padding-top 10
:margin-top 10
:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-80)})
;;;; Misc
(defn panel-basic
[]
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1})
(def component-container
{:flex-grow 1
:min-height 200
:padding-vertical 20
:padding-horizontal 20})
(defn main
[]
{:flex 1
:padding-bottom 8
:padding-horizontal 16
:background-color (colors/theme-colors colors/white colors/neutral-90)})
(def theme-switcher
{:flex-direction :row
:justify-content :space-between
:padding-horizontal 24
:padding-vertical 12})
@@ -141,7 +141,7 @@
:group-avatar [quo2/group-avatar-tag (:label @state)
{:blur? (:blur? @state)
:size :x-small
:size :size/s-20
:customization-color :purple}]
:public-key [quo2/public-key-tag
@@ -0,0 +1,115 @@
(ns status-im2.contexts.quo-preview.wallet.keypair
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def accounts
[{:account-props {:customization-color :turquoise
:size 32
:emoji "\uD83C\uDFB2"
:type :default
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :purple
:size 32
:emoji "\uD83C\uDF7F"
:type :default
:name "My savings"
:address "0x0ah...72b"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :army
:size 32
:emoji "\uD83D\uDCC8"
:type :default
:name "Coin vault"
:address "0x0ah...73c"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :orange
:size 32
:emoji "\uD83C\uDFF0"
:type :default
:name "Crypto fortress"
:address "0x0ah...74e"}
:networks [:ethereum :optimism]
:state :default
:action :none}
{:account-props {:customization-color :yellow
:size 32
:emoji "\uD83C\uDFDD"
:type :default
:name "Block treasure"
:address "0x0ah...75f"}
:networks [:ethereum :optimism]
:state :default
:action :none}])
(def descriptor
[{:label "Stored:"
:key :stored
:type :select
:options [{:key :on-device
:value "On device"}
{:key :on-keycard
:value "On Keycard"}]}
{:label "Action:"
:key :action
:type :select
:options [{:key :selector
:value "Selector"}
{:key :options
:value "Options"}]}
{:label "Type:"
:key :type
:type :select
:options [{:key :default-keypair
:value "Default keypair"}
{:key :other
:value "Other"}]}
(preview/customization-color-option)])
(def default-details
{:full-name "John Doe"
:address "zQ3...6fBd2"})
(def other-details {:full-name "Metamask"})
(defn cool-preview
[]
(let [state (reagent/atom {:accounts accounts
:customization-color :blue
:type :default-keypair
:stored :on-device
:on-options-press #(js/alert "Options pressed")
:action :selector})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:style {:padding-bottom 150}}
[rn/view {:style {:flex 1}}
[preview/customizer state descriptor]]
[rn/view
{:style {:padding-vertical 30
:flex-direction :row
:justify-content :center}}
[quo/keypair
(merge
@state
{:details (if (= (:type @state) :default-keypair) default-details other-details)})]]]])))
(defn preview
[]
[rn/view
{:style {:flex 1}}
[rn/flat-list
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])
@@ -0,0 +1,50 @@
(ns status-im2.contexts.quo-preview.wallet.network-link
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def networks
[{:key :ethereum
:value "Ethereum"}
{:key :optimism
:value "Optimism"}
{:key :arbitrum
:vault "Arbitrum"}])
(def descriptor
[{:label "Shape:"
:key :shape
:type :select
:options [{:key :linear
:value "Linear"}
{:key :1x
:value "1x"}
{:key :2x
:value "2x"}]}
{:label "Source:"
:key :source
:type :select
:options networks}
{:label "Destination:"
:key :destination
:type :select
:options networks}])
(defn preview
[]
(let [state (reagent/atom {:shape :linear
:source :ethereum
:destination :optimism})]
(fn []
[rn/view
{:style {:flex 1
:padding-horizontal 20}}
[rn/view {:style {:min-height 150}}
[preview/customizer state descriptor]]
[rn/view
{:style {:flex 1
:padding-top 40
:align-items :center}}
[quo/network-link @state]]])))
@@ -9,7 +9,7 @@
[utils.re-frame :as rf]))
(def tag-params
{:size :small
{:size :size/s-20
:customization-color :blue
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text
@@ -21,9 +21,11 @@
(defn- get-header-text-and-context
[community membership-status]
(let [community-name (:name community)
permissions (:permissions community)
community-image (get-in community [:images :thumbnail :uri])
community-context-tag [quo/context-tag common/tag-params community-image
community-name]]
community-name]
open? (not= 3 (:access permissions))]
(cond
(= membership-status constants/activity-center-membership-status-idle)
{:header-text (i18n/label :t/community-request-not-accepted)
@@ -40,9 +42,14 @@
community-context-tag]}
(= membership-status constants/activity-center-membership-status-accepted)
{:header-text (i18n/label :t/community-request-accepted)
{:header-text (i18n/label (if open?
:t/join-open-community
:t/community-request-accepted))
:context [[quo/text {:style common-style/user-avatar-tag-text}
(i18n/label :t/community-request-accepted-body-text)]
(i18n/label (if open?
:t/joined-community
:t/community-request-accepted-body-text)
(when open? {:community community-name}))]
community-context-tag]}
:else nil)))
@@ -67,7 +67,7 @@
:context [[common/user-avatar-tag author]
(i18n/label :t/added-you-to)
[quo/group-avatar-tag chat-name
{:size :x-small
{:size :size/s-20
:customization-color :purple}]]
:items (when-not (or accepted dismissed)
[{:type :button
@@ -27,10 +27,13 @@
:flex 1
:accessibility-label :bottom-tabs})
(def bottom-tabs-blur-overlay
{:position :absolute
:left 0
:right 0
:bottom 0
:height (utils/bottom-tabs-extended-container-height)
:background-color colors/neutral-100-opa-70})
(defn bottom-tabs-blur-overlay
[height]
(reanimated/apply-animations-to-style
{:height height}
{:position :absolute
:left 0
:right 0
:bottom 0
:height (utils/bottom-tabs-container-height)
:background-color colors/neutral-100-opa-70-blur}))
@@ -1,8 +1,8 @@
(ns status-im2.contexts.shell.jump-to.components.bottom-tabs.view
(:require [utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.blur :as blur]
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im2.contexts.shell.jump-to.utils :as utils]
[status-im2.contexts.shell.jump-to.state :as state]
@@ -14,8 +14,8 @@
(defn blur-overlay-params
[style]
{:style style
:blur-amount 30
:blur-radius 25
:blur-amount (if platform/android? 30 20)
:blur-radius (if platform/android? 25 10)
:blur-type :transparent
:overlay-color :transparent})
@@ -53,13 +53,15 @@
(gesture/number-of-taps 2)
(gesture/on-start
(fn [_event]
(rf/dispatch [:messages-home/select-tab :tab/recent]))))]
(rf/dispatch [:messages-home/select-tab :tab/recent]))))
bottom-tabs-blur-overlay-style (style/bottom-tabs-blur-overlay (:bottom-tabs-height
shared-values))]
(utils/load-stack @state/selected-stack-id)
(reanimated/set-shared-value (:pass-through? shared-values) pass-through?)
[reanimated/view
{:style (style/bottom-tabs-container pass-through? (:bottom-tabs-height shared-values))}
(when pass-through?
[blur/view (blur-overlay-params style/bottom-tabs-blur-overlay)])
[reanimated/blur-view (blur-overlay-params bottom-tabs-blur-overlay-style)])
[rn/view {:style (style/bottom-tabs)}
[gesture/gesture-detector {:gesture communities-double-tab-gesture}
[bottom-tab :i/communities :communities-stack shared-values notifications-data]]
@@ -28,8 +28,8 @@
:z-index (get shared-values
(get shell.constants/stacks-z-index-keywords stack-id))})}
(case stack-id
:communities-stack [:f> communities/home]
:chats-stack [:f> chat/home]
:communities-stack [:f> communities/view]
:chats-stack [:f> chat/view]
;NOTE temporary while we support old wallet
:wallet-stack (if @state/load-new-wallet?
[wallet-new/view]
@@ -61,4 +61,4 @@
:left 0
:right 0
:top 0
:background-color colors/neutral-100-opa-70})
:background-color colors/neutral-100-opa-70-blur})
@@ -125,7 +125,7 @@
shell.constants/private-group-chat-card
[quo/group-avatar
{:customization-color customization-color
:size :large
:size :size/s-48
:override-theme :dark}]
(shell.constants/community-card
@@ -2,6 +2,7 @@
(def ^:const shell-animation-time 200)
(def ^:const switcher-card-size 160)
(def ^:const floating-shell-button-height 44)
;; Bottom tabs
(def ^:const bottom-tabs-container-height-android 57)
@@ -37,7 +37,7 @@
:label (i18n/label :t/jump-to)
:customization-color (rf/sub [:profile/customization-color])}}
{:position :absolute
:bottom (+ (utils/bottom-tabs-container-height) 12)}
:bottom (utils/bottom-tabs-container-height)}
(:home-stack-opacity shared-values)])
(defn f-shell-stack
@@ -845,7 +845,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.profile_1.just_fyi("Sending contact request via Profile > Contacts")
for home in (self.home_1, self.home_2):
home.click_system_back_button_until_element_is_shown()
home.navigate_back_to_home_view()
home.chats_tab.click()
self.home_1.send_contact_request_via_bottom_sheet(self.public_key_2)
@@ -855,7 +855,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.profile_1.just_fyi("Sending message to contact via Messages > Recent")
self.chat_1 = self.home_1.get_chat(self.username_2).click()
self.chat_1.send_message('hey')
self.home_2.click_system_back_button_until_element_is_shown()
self.home_2.navigate_back_to_home_view()
self.chat_2 = self.home_2.get_chat(self.username_1).click()
self.message_1, self.message_2, self.message_3, self.message_4 = \
"Message 1", "Message 2", "Message 3", "Message 4"
@@ -919,9 +919,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@marks.testrail_id(702782)
def test_1_1_chat_emoji_send_reply_and_open_link(self):
for chat in self.chat_1, self.chat_2:
element = chat.chat_message_input
if not element.is_element_displayed():
chat.click_system_back_button_until_element_is_shown(element)
chat.navigate_back_to_chat_view()
self.home_1.just_fyi("Check that can send emoji in 1-1 chat")
emoji_name = random.choice(list(emoji.EMOJI_UNICODE))
emoji_unicode = emoji.EMOJI_UNICODE[emoji_name]
@@ -1086,14 +1084,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.home_1.jump_to_messages_home()
self.home_1.profile_button.click()
self.profile_1.edit_profile_picture('sauce_logo.png')
self.profile_1.click_system_back_button_until_element_is_shown()
self.profile_1.navigate_back_to_home_view()
self.profile_1.chats_tab.click()
self.chat_2.just_fyi("Send messages with non-latin symbols")
self.home_1.jump_to_card_by_text(self.username_2)
self.chat_1.send_message("just a text") # Sending a message here so the next ones will be in a separate line
self.home_2.click_system_back_button_until_element_is_shown()
self.home_2.navigate_back_to_home_view()
self.home_2.jump_to_card_by_text(self.username_1)
messages = ['hello', '¿Cómo estás tu año?', 'ё, доброго вечерочка', '® æ ç ♥']
[self.chat_2.send_message(message) for message in messages]
@@ -1132,7 +1130,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
def test_1_1_chat_push_emoji(self):
message_no_pn, message = 'No PN', 'Text push notification'
[home.click_system_back_button_until_element_is_shown() for home in self.homes]
[home.navigate_back_to_home_view() for home in self.homes]
self.home_2.profile_button.click()
self.home_1.chats_tab.click()
@@ -1144,7 +1142,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.send_message(message)
self.device_1.just_fyi("Device 1 puts app on background to receive emoji push notification")
self.device_1.click_system_back_button_until_element_is_shown()
self.device_1.navigate_back_to_home_view()
self.device_1.profile_button.click()
self.device_2.just_fyi("Check text push notification and tap it")
@@ -1182,7 +1180,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@marks.testrail_id(702855)
def test_1_1_chat_edit_message(self):
[home.click_system_back_button_until_element_is_shown() for home in self.homes]
[home.navigate_back_to_home_view() for home in self.homes]
self.chat_2.jump_to_card_by_text(self.username_1)
self.chat_1.jump_to_card_by_text(self.username_2)
@@ -1237,7 +1235,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
except TimeoutException:
self.errors.append(
"%s can't share an image via Gmail." % ("Sender" if chat is self.chat_1 else "Receiver"))
chat.click_system_back_button_until_element_is_shown(element="chat")
chat.navigate_back_to_chat_view()
for chat in self.chat_1, self.chat_2:
chat.just_fyi("Open the image and save it")
@@ -1254,7 +1252,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
toast_element_text, chat.get_translation_by_key("photo-saved"), device_name))
else:
self.errors.append("Message about saving a photo is not shown for %s." % device_name)
chat.click_system_back_button_until_element_is_shown(element="chat")
chat.navigate_back_to_chat_view()
for chat in self.chat_1, self.chat_2:
chat.just_fyi("Check that image is saved in gallery")
@@ -1307,7 +1305,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
for chat in (self.chat_2, self.chat_1):
if chat.chat_element_by_text(message_after_edit_1_1).is_element_displayed(30):
self.errors.append("Deleted message is shown in chat view for 1-1 chat")
self.chat_1.click_system_back_button_until_element_is_shown()
self.chat_1.navigate_back_to_home_view()
if self.home_1.element_by_text(message_after_edit_1_1).is_element_displayed(30):
self.errors.append("Deleted message is shown on chat element on home screen")
@@ -1325,7 +1323,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
if pn_to_disappear:
if not pn_to_disappear.is_element_disappeared(90):
self.errors.append("Push notification was not removed after initial message deletion")
[device.click_system_back_button_until_element_is_shown() for device in (self.device_1, self.device_2)]
[device.navigate_back_to_home_view() for device in (self.device_1, self.device_2)]
self.errors.verify_no_errors()
@marks.testrail_id(702783)
@@ -1380,7 +1378,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@marks.testrail_id(703496)
def test_1_1_chat_mute_chat(self):
self.home_1.click_system_back_button_until_element_is_shown()
self.home_1.navigate_back_to_home_view()
self.home_1.chats_tab.click()
self.home_1.just_fyi("Mute chat")
self.home_1.mute_chat_long_press(self.username_2)
@@ -1397,13 +1395,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.errors.append("Message '%s' is not shown in chat for receiver after mute" % muted_message)
self.chat_1.just_fyi("Unmute chat")
self.chat_1.click_system_back_button_until_element_is_shown()
self.chat_1.navigate_back_to_home_view()
chat.long_press_element()
if self.home_1.mute_chat_button.text != transl["unmute-chat"]:
self.errors.append("Chat is not muted")
expected_text = "Muted until you turn it back on"
if not self.home_1.element_by_text(expected_text).is_element_displayed():
self.errors.append("Text '%s' is not shown for muted chat" %expected_text)
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
self.home_1.mute_chat_button.click()
unmuted_message = "after unmute"
@@ -1421,7 +1419,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@marks.testrail_id(702784)
def test_1_1_chat_delete_via_long_press_relogin(self):
self.home_2.click_system_back_button_until_element_is_shown()
self.home_2.navigate_back_to_home_view()
self.home_2.chats_tab.click()
self.home_2.just_fyi("Deleting chat via delete button and check it will not reappear after relaunching app")
@@ -1,3 +1,5 @@
import datetime
import pytest
from _pytest.outcomes import Failed
from selenium.common.exceptions import NoSuchElementException, TimeoutException
@@ -176,7 +178,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.homes[0].just_fyi('Admin adds future members to contacts')
for i in range(3):
self.homes[i].click_system_back_button_until_element_is_shown()
self.homes[i].navigate_back_to_home_view()
self.homes[i].chats_tab.click()
for i in range(1, 3):
@@ -192,7 +194,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
)
)
for i in range(1, 3):
self.homes[i].click_system_back_button_until_element_is_shown()
self.homes[i].navigate_back_to_home_view()
self.homes[0].just_fyi('Admin creates group chat')
self.chat_name = self.homes[0].get_random_chat_name()
@@ -207,7 +209,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
@marks.testrail_id(702807)
def test_group_chat_join_send_text_messages_push(self):
message_to_admin = self.message_to_admin
[self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)]
[self.homes[i].navigate_back_to_home_view() for i in range(3)]
self.homes[1].get_chat(self.chat_name).click()
self.chats[1].send_message(message_to_admin)
@@ -230,7 +232,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
@marks.testrail_id(703202)
def test_group_chat_reactions(self):
[self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)]
[self.homes[i].navigate_back_to_home_view() for i in range(3)]
[self.homes[i].get_chat(self.chat_name).click() for i in range(3)]
message = "This is a test message to check some reactions."
self.chats[0].just_fyi("Admin sends a message")
@@ -282,7 +284,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
)
except NoSuchElementException:
self.errors.append("User profile was not opened from the list of reactions")
self.chats[0].click_system_back_button_until_element_is_shown(element="chat")
self.chats[0].navigate_back_to_chat_view()
self.chats[1].just_fyi("Member_1 removes 'thumbs-up' reaction and adds 'sad' one")
self.chats[1].add_remove_same_reaction(message=message, emoji="thumbs-up")
@@ -317,7 +319,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
for chat in self.chats[1], self.chats[2]:
chat.just_fyi("Just making the session not to quit")
chat.click_system_back_button_until_element_is_shown()
chat.navigate_back_to_home_view()
self.chats[0].just_fyi("Admin checks info about voted users after relogin")
message_element.emojis_below_message(
@@ -343,7 +345,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
@marks.testrail_id(703297)
def test_group_chat_send_image_save_and_share(self):
[self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)]
[self.homes[i].navigate_back_to_home_view() for i in range(3)]
for i in range(3):
self.homes[i].get_chat(self.chat_name).click()
@@ -371,9 +373,9 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[0].wait_for_current_package_to_be('com.google.android.gm')
except TimeoutException:
self.errors.append("Admin can't share an image via Gmail.")
self.chats[0].click_system_back_button_until_element_is_shown(element="chat")
self.chats[0].navigate_back_to_chat_view()
self.chats[1].click_system_back_button_until_element_is_shown()
self.chats[1].navigate_back_to_home_view()
self.chats[2].just_fyi("Member_2 opens the image and saves it")
self.chats[2].chat_element_by_text(image_description).image_in_message.click()
@@ -388,22 +390,22 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
toast_element_text, self.chats[2].get_translation_by_key("photo-saved")))
else:
self.errors.append("Message about saving a photo is not shown for member_2.")
self.chats[2].click_system_back_button_until_element_is_shown(element="chat")
self.chats[2].navigate_back_to_chat_view()
self.chats[2].just_fyi("Member_2 checks that image was saved in gallery")
self.chats[2].show_images_button.click()
self.chats[2].allow_button.click_if_shown()
if not self.chats[2].get_image_by_index(0).is_element_image_similar_to_template("saucelabs_sauce_gallery.png"):
self.errors.append("Image is not saved to gallery for member_2.")
self.chats[2].click_system_back_button_until_element_is_shown(element="chat")
self.chats[2].navigate_back_to_chat_view()
self.errors.verify_no_errors()
@marks.testrail_id(702808)
def test_group_chat_offline_pn(self):
self.homes[0].click_system_back_button_until_element_is_shown()
[self.homes[i].jump_to_messages_home() for i in range(3)]
for i in range(1, 3):
self.homes[i].navigate_back_to_home_view()
self.homes[i].chats_tab.click()
self.homes[i].groups_tab.click()
self.homes[i].get_chat(self.chat_name).click()
@@ -441,7 +443,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
@marks.xfail(reason="Pin feature is in development", run=False)
@marks.testrail_id(702732)
def test_group_chat_pin_messages(self):
[self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)]
[self.homes[i].navigate_back_to_home_view() for i in range(3)]
[self.homes[i].get_chat(self.chat_name).click() for i in range(3)]
self.message_1, self.message_2, self.message_3, self.message_4 = \
@@ -520,27 +522,35 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
@marks.testrail_id(703495)
def test_group_chat_mute_chat(self):
[self.homes[i].click_system_back_button_until_element_is_shown() for i in range(3)]
[self.homes[i].navigate_back_to_home_view() for i in range(3)]
self.homes[1].just_fyi("Member 1 mutes the chat")
self.homes[1].mute_chat_long_press(self.chat_name)
# ToDo: should be redone to some exact period mute after issue with adb commands execution is solved with
# SauceLabs or an option for 1 minute mute is added for e2e apk
# self.homes[1].mute_chat_long_press(self.chat_name, "mute-for-1-hour")
# device_time = self.homes[1].driver.device_time
self.homes[0].just_fyi("Admin sends a message")
muted_message = "Text message in the muted chat"
self.homes[0].get_chat(self.chat_name).click()
self.homes[1].just_fyi("Member 1 mutes the chat for 1 hour")
self.homes[1].mute_chat_long_press(self.chat_name, "mute-for-1-hour")
device_time = self.homes[1].driver.device_time
current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z")
expected_time = current_time + datetime.timedelta(minutes=60)
expected_text = "Muted until %s %s" % (
expected_time.strftime('%H:%M'), "today" if current_time.hour < 23 else "tomorrow")
chat = self.homes[1].get_chat(self.chat_name)
chat.long_press_element()
if self.homes[1].mute_chat_button.text != transl["unmute-chat"]:
pytest.fail("Chat is not muted")
if not self.homes[1].element_by_text(expected_text).is_element_displayed():
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
self.homes[1].click_system_back_button()
try:
initial_counter = int(self.homes[1].chats_tab.counter.text)
except NoSuchElementException:
initial_counter = 0
self.homes[0].just_fyi("Admin sends a message")
muted_message = "Text message in the muted chat"
self.homes[0].get_chat(self.chat_name).click()
self.chats[0].send_message(muted_message)
self.homes[1].just_fyi("Member 1 checks that chat is muted and message is received")
chat = self.homes[1].get_chat(self.chat_name)
if chat.new_messages_grey_dot.is_element_displayed(30):
self.errors.append("New messages counter near chat name is shown after mute")
self.errors.append("New messages grey dot near chat name is shown after mute")
try:
after_mute_counter = int(self.homes[1].chats_tab.counter.text)
except NoSuchElementException:
@@ -554,30 +564,18 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30):
self.errors.append(
"Message '%s' is not shown in chat for %s after mute" % (muted_message, self.usernames[1]))
self.chats[1].click_system_back_button_until_element_is_shown()
self.chats[1].navigate_back_to_home_view()
self.chats[1].just_fyi("Change device time so chat will be unmuted by timer")
unmute_time = current_time + datetime.timedelta(minutes=61)
self.homes[1].driver.execute_script("mobile: shell",
{"command": "su root date %s" % unmute_time.strftime("%m%d%H%M%Y.%S")}
)
chat.long_press_element()
if self.homes[1].mute_chat_button.text != transl["unmute-chat"]:
self.errors.append("Chat is not muted")
# expected_text = "Muted until %s today" % device_time + 1
expected_text = "Muted until you turn it back on"
if not self.homes[1].element_by_text(expected_text).is_element_displayed():
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
self.chats[1].just_fyi("Member 1 unmutes the chat")
# self.chats[1].just_fyi("Close app and change device time so chat will be unmuted by timer")
# self.homes[1].put_app_to_background()
# self.homes[1].driver.execute('mobile: shell', {
# 'command': 'date',
# 'args': [str(device_time + 1)]
# })
# self.homes[1].driver.launch_app()
# self.sign_in_views[1].sign_in()
# self.homes[1].chats_tab.click()
# chat.long_press_element()
# if self.homes[1].element_starts_with_text("Muted until").is_element_displayed():
# self.errors.append("Chat is still muted after timeout")
# self.errors.verify_no_errors()
# self.homes[1].click_system_back_button()
self.homes[1].mute_chat_button.click() # ToDo: remove when ^ is enabled
if self.homes[1].element_starts_with_text("Muted until").is_element_displayed():
self.errors.append("Chat is still muted after timeout")
self.errors.verify_no_errors()
self.homes[1].click_system_back_button()
unmuted_message = "Chat is unmuted now"
self.homes[2].just_fyi("Member 2 sends a message")

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