Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
778fc842be | ||
|
|
efdb3a7950 |
@@ -5,7 +5,14 @@ let
|
||||
# Import a jsbundle compiled out of clojure codebase
|
||||
jsbundle = callPackage ./jsbundle { };
|
||||
|
||||
release = callPackage ./release.nix { inherit jsbundle status-go; };
|
||||
# Import a patched version of watchman (important for sandboxed builds on macOS)
|
||||
watchmanFactory = callPackage ./watchman.nix { };
|
||||
|
||||
# TARGETS
|
||||
release = callPackage ./release.nix {
|
||||
inherit jsbundle status-go watchmanFactory;
|
||||
};
|
||||
|
||||
in {
|
||||
# TARGETS
|
||||
inherit release jsbundle;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ stdenv, pkgs, deps, lib
|
||||
{ stdenv, pkgs, deps, lib, watchmanFactory
|
||||
, androidPkgs, patchMavenSources, jsbundle, status-go }:
|
||||
|
||||
{
|
||||
@@ -6,8 +6,13 @@
|
||||
buildEnv ? "prod",
|
||||
# Path to the file containing secret environment variables
|
||||
secretsFile ? "",
|
||||
# Path to the socket file exposed by an external watchman instance
|
||||
# (workaround needed for building Android on macOS)
|
||||
watchmanSockPath ? "",
|
||||
}:
|
||||
|
||||
assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
|
||||
|
||||
let
|
||||
inherit (lib) toLower optionalString stringLength getConfig makeLibraryPath elem;
|
||||
|
||||
@@ -21,8 +26,8 @@ let
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude = getConfig "android.abi-include" "armeabi-v7a;arm64-v8a;x86";
|
||||
|
||||
envFileName =
|
||||
if androidAbiInclude == "x86" then ".env.e2e"
|
||||
envFileName =
|
||||
if androidAbiInclude == "x86" then ".env.e2e"
|
||||
else if (elem buildType ["release" "nightly"]) then ".env.${buildType}"
|
||||
else if (elem buildType ["pr" "manual"]) then ".env.jenkins"
|
||||
else ".env";
|
||||
@@ -31,6 +36,7 @@ let
|
||||
gradleBuildType = if buildType == "pr" then "Pr" else "Release";
|
||||
|
||||
apksPath = "./android/app/build/outputs/apk/${toLower gradleBuildType}";
|
||||
patchedWatchman = watchmanFactory watchmanSockPath;
|
||||
|
||||
baseName = "${buildType}-android";
|
||||
in stdenv.mkDerivation rec {
|
||||
@@ -48,17 +54,15 @@ in stdenv.mkDerivation rec {
|
||||
"package.json" "yarn.lock" "metro.config.js" ".babelrc"
|
||||
"resources/.*" "translations/.*" "src/js/worklet_factory.js"
|
||||
"modules/react-native-status/android.*" "android/.*"
|
||||
envFileName "VERSION" "status-go-version.json" "react-native.config.js"
|
||||
envFileName "VERSION" ".watchmanconfig"
|
||||
"status-go-version.json" "react-native.config.js"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
buildInputs = with pkgs; [ nodejs openjdk ];
|
||||
nativeBuildInputs = with pkgs; [ bash gradle unzip ]
|
||||
++ lib.optionals stdenv.isDarwin [ file gnumake ];
|
||||
|
||||
# Disable metro watching for file changes. (#13783)
|
||||
CI = true;
|
||||
++ lib.optionals stdenv.isDarwin [ file gnumake patchedWatchman ];
|
||||
|
||||
# Used by Clojure at compile time to include JS modules
|
||||
BUILD_ENV = buildEnv;
|
||||
@@ -88,8 +92,8 @@ in stdenv.mkDerivation rec {
|
||||
# Ensure we have the right .env file
|
||||
cp -bf ./${envFileName} ./.env
|
||||
|
||||
# Export all vars from .env file
|
||||
export $(cut -d= -f1 .env)
|
||||
# Export all vars from .env file
|
||||
export $(cut -d= -f1 .env)
|
||||
|
||||
# Copy index.js and app/ input files
|
||||
cp -ra --no-preserve=ownership ${builtJsBundle}/* ./
|
||||
@@ -117,7 +121,7 @@ in stdenv.mkDerivation rec {
|
||||
buildPhase = let
|
||||
adhocEnvVars = optionalString stdenv.isLinux
|
||||
"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ pkgs.zlib ]}";
|
||||
in
|
||||
in
|
||||
assert ANDROID_ABI_SPLIT != null && ANDROID_ABI_SPLIT != "";
|
||||
assert stringLength ANDROID_ABI_INCLUDE > 0;
|
||||
''
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{ stdenv, runCommand, makeWrapper,
|
||||
watchman }:
|
||||
|
||||
let
|
||||
patchedWatchmanFactory = watchmanSockPath:
|
||||
assert (builtins.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
|
||||
if stdenv.isDarwin then
|
||||
assert (builtins.stringLength watchmanSockPath) > 0;
|
||||
# Create a wrapper to watchman that includes the --sockname flag
|
||||
runCommand "patched-watchman" { nativeBuildInputs = [ makeWrapper ]; } ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
makeWrapper ${watchman}/bin/watchman \
|
||||
$out/bin/watchman \
|
||||
--add-flags "--sockname=${watchmanSockPath}"
|
||||
'' else watchman;
|
||||
|
||||
in patchedWatchmanFactory
|
||||
|
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 468 B |
|
Before Width: | Height: | Size: 525 B |
|
Before Width: | Height: | Size: 759 B |
|
Before Width: | Height: | Size: 358 B |
|
Before Width: | Height: | Size: 570 B |
|
Before Width: | Height: | Size: 618 B |
|
Before Width: | Height: | Size: 618 B |
|
Before Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 673 B |
|
Before Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 488 B |
|
Before Width: | Height: | Size: 684 B |
|
Before Width: | Height: | Size: 597 B |
|
Before Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 633 B |
|
Before Width: | Height: | Size: 633 B |
|
Before Width: | Height: | Size: 543 B |
|
Before Width: | Height: | Size: 734 B |
@@ -47,17 +47,24 @@ if [[ -n "${OPENSEA_API_KEY}" ]]; then append_env_export 'OPENSEA_API_KEY'; fi
|
||||
if [[ -s "${SECRETS_FILE_PATH}" ]]; then
|
||||
nixOpts+=("--argstr" "secretsFile" "${SECRETS_FILE_PATH}")
|
||||
fi
|
||||
nixOpts+=("--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH}")
|
||||
|
||||
# Used by Clojure at compile time to include JS modules
|
||||
nixOpts+=("--argstr" "buildEnv" "$(must_get_env BUILD_ENV)")
|
||||
|
||||
# On Darwin we hit a sandbox serialization limit of 65535.
|
||||
# https://github.com/NixOS/nix/issues/4119
|
||||
if [[ "$(uname -s)" =~ Darwin ]]; then
|
||||
nixOpts+=("--option" "build-use-sandbox" "false")
|
||||
# Start a watchman instance if not started already and store its socket path.
|
||||
# In order to get access to the right versions of watchman and jq,
|
||||
# we start an ad-hoc nix-shell that imports the packages from nix/nixpkgs-bootstrap.
|
||||
WATCHMAN_SOCKFILE=$(watchman get-sockname --no-pretty | jq -r .sockname)
|
||||
nixOpts+=(
|
||||
"--argstr" "watchmanSockPath" "${WATCHMAN_SOCKFILE}"
|
||||
"--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH} ${WATCHMAN_SOCKFILE}"
|
||||
)
|
||||
else
|
||||
nixOpts+=("--option" "build-use-sandbox" "true")
|
||||
nixOpts+=(
|
||||
"--option" "build-use-sandbox" "true"
|
||||
"--option" "extra-sandbox-paths" "${KEYSTORE_PATH} ${SECRETS_FILE_PATH}"
|
||||
)
|
||||
fi
|
||||
|
||||
nixOpts+=("--arg" "config" "{${config}}")
|
||||
|
||||
@@ -50,4 +50,4 @@ exec keytool -genkey -v \
|
||||
-alias "${KEYSTORE_ALIAS}" \
|
||||
-storepass "${KEYSTORE_PASSWORD}" \
|
||||
-keypass "${KEYSTORE_KEY_PASSWORD}" \
|
||||
>&2
|
||||
> /dev/stderr
|
||||
|
||||
@@ -100,8 +100,6 @@
|
||||
:clearInterval js/clearInterval}}))
|
||||
|
||||
(def keychain #js {:setGenericPassword (constantly (.resolve js/Promise true))
|
||||
:setInternetCredentials #(js/Promise.resolve)
|
||||
:resetInternetCredentials #(js/Promise.resolve)
|
||||
"ACCESSIBLE" {}
|
||||
"ACCESS_CONTROL" {}})
|
||||
|
||||
@@ -135,9 +133,7 @@
|
||||
(def react-native-navigation #js {:Navigation #js {:constants (fn [] #js {:then identity})
|
||||
:setDefaultOptions identity
|
||||
:setRoot identity
|
||||
:dismissOverlay #(js/Promise.resolve)
|
||||
:setLazyComponentRegistrator identity
|
||||
:pop identity
|
||||
:push identity
|
||||
:registerComponent identity
|
||||
:events
|
||||
@@ -242,7 +238,7 @@
|
||||
|
||||
(def react-native-permissions #js {:default #js {}})
|
||||
|
||||
(def push-notification-ios #js {:default #js {:abandonPermissions identity}})
|
||||
(def push-notification-ios #js {})
|
||||
|
||||
(def rn-emoji-keyboard
|
||||
#js {:EmojiKeyboard #js {}})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
(def haptic-methods
|
||||
{:selection "selection"
|
||||
:impact-light "impactLight"
|
||||
:impacet-light "impactLight"
|
||||
:impact-medium "impactMedium"
|
||||
:impact-heavy "impactHeavy"
|
||||
:notification-success "notificationSuccess"
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
(ns quo2.components.activity-logs
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.status-tags :as status-tags]
|
||||
[quo2.components.button :as quo2.button]
|
||||
[quo2.components.text :as text]
|
||||
[quo2.components.icon :as quo2.icons]))
|
||||
|
||||
(defn activity-logs [_]
|
||||
(fn [{:keys [title
|
||||
button-1
|
||||
button-2
|
||||
icon
|
||||
unread
|
||||
status
|
||||
message
|
||||
timestamp]}]
|
||||
[rn/view {:flex-direction :row
|
||||
:flex 1
|
||||
:border-radius 16
|
||||
:padding-top 8
|
||||
:padding-horizontal 12
|
||||
:padding-bottom 12
|
||||
:background-color (when unread
|
||||
colors/primary-50-opa-10)}
|
||||
[rn/view {:height 32
|
||||
:width 32
|
||||
:border-radius 100
|
||||
:margin-top 8
|
||||
:background-color colors/neutral-80-opa-60
|
||||
:flex-direction :column
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[quo2.icons/icon icon {:color colors/white}]]
|
||||
[rn/view {:flex-direction :column
|
||||
:padding-left 8
|
||||
:flex 1}
|
||||
[rn/view {:flex 1
|
||||
:flex-wrap :wrap}
|
||||
[rn/view {:flex-direction :row}
|
||||
[text/text {:weight :semi-bold
|
||||
:style {:color colors/white}
|
||||
:size :paragraph-1}
|
||||
title]
|
||||
[rn/view {:margin-left 8
|
||||
:margin-top 5}
|
||||
[text/text {:size :label
|
||||
:style {:text-transform :none
|
||||
:color colors/neutral-40}} timestamp]]]]
|
||||
(when message
|
||||
[rn/view {:border-radius 12
|
||||
:margin-top 13
|
||||
:padding-horizontal 12
|
||||
:padding-vertical 8
|
||||
:background-color :red}
|
||||
[text/text {:style {:color colors/white}
|
||||
:size :paragraph-1}
|
||||
message]])
|
||||
(when status
|
||||
[rn/view {:padding-top 10
|
||||
:align-items :flex-start}
|
||||
[status-tags/status-tag {:size :small
|
||||
:override-theme :dark
|
||||
:status status}]])
|
||||
(when (or button-1 button-2)
|
||||
[rn/view {:padding-top 10
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :flex-start}
|
||||
(when button-1
|
||||
[quo2.button/button
|
||||
(assoc button-1
|
||||
:override-them :dark
|
||||
:style {:margin-right 8})
|
||||
(:label button-1)])
|
||||
(when button-2
|
||||
[quo2.button/button
|
||||
(assoc button-2
|
||||
:override-theme
|
||||
:dark)
|
||||
(:label button-2)])])]]))
|
||||
@@ -1,32 +0,0 @@
|
||||
(ns quo2.components.base-tag
|
||||
(:require
|
||||
[quo.react-native :as rn]))
|
||||
|
||||
(defn style-container [size disabled border-color border-width background-color label type]
|
||||
(merge {:height size
|
||||
:border-color border-color
|
||||
:background-color background-color
|
||||
:border-width border-width
|
||||
:border-radius size
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when disabled
|
||||
{:opacity 0.3})
|
||||
(when (and (or (= type :icon) (= type :emoji)) (not label))
|
||||
{:width size})))
|
||||
|
||||
(defn base-tag
|
||||
"opts
|
||||
{:type :icon/:emoji/:label/:token/:permission
|
||||
:size 32/24}
|
||||
:labelled true"
|
||||
[_]
|
||||
(fn [{:keys [id size disabled border-color border-width background-color on-press
|
||||
accessibility-label label type] :or {size 32}} children]
|
||||
[rn/touchable-without-feedback (merge {:disabled disabled
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press #(on-press id)}))
|
||||
[rn/view {:style (merge (style-container size disabled border-color border-width
|
||||
background-color label type))}
|
||||
children]]))
|
||||
@@ -28,11 +28,6 @@
|
||||
:ghost {:icon-color colors/neutral-50
|
||||
:label {:style {:color colors/black}}
|
||||
:background-color {:pr:pressedess colors/neutral-10}}
|
||||
:success {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/success-50
|
||||
:pressed colors/success-70
|
||||
:disabled colors/success-50}}
|
||||
:danger {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/danger-50
|
||||
@@ -60,11 +55,6 @@
|
||||
:ghost {:icon-color colors/neutral-40
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:pressed colors/neutral-80}}
|
||||
:success {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/success-60
|
||||
:pressed colors/success-40
|
||||
:disabled colors/success-60}}
|
||||
:danger {:icon-color colors/white
|
||||
:label {:style {:color colors/white}}
|
||||
:background-color {:default colors/danger-50
|
||||
@@ -89,11 +79,7 @@
|
||||
:padding-left (when-not (or icon before)
|
||||
(case size 56 16 40 16 32 12 24 8))
|
||||
:padding-right (when-not (or icon after)
|
||||
(case size 56 16 40 16 32 12 24 8))
|
||||
:padding-top (when-not (or icon before after)
|
||||
(case size 56 0 40 9 32 5 24 3))
|
||||
:padding-bottom (when-not (or icon before after)
|
||||
(case size 56 0 40 9 32 5 24 4))}
|
||||
(case size 56 16 40 16 32 12 24 8))}
|
||||
(when width
|
||||
{:width width})
|
||||
(when icon
|
||||
@@ -119,15 +105,12 @@
|
||||
[_ _]
|
||||
(let [pressed (reagent/atom false)]
|
||||
(fn [{:keys [on-press disabled type size before after above width
|
||||
override-theme
|
||||
on-long-press accessibility-label icon style]
|
||||
:or {type :primary
|
||||
size 40}}
|
||||
children]
|
||||
(let [{:keys [icon-color background-color label border-color]}
|
||||
(get-in themes [(or
|
||||
override-theme
|
||||
(theme/get-theme)) type])
|
||||
(get-in themes [(theme/get-theme) type])
|
||||
state (cond disabled :disabled @pressed :pressed :else :default)
|
||||
icon-size (when (= 24 size) 12)]
|
||||
[rn/touchable-without-feedback (merge {:disabled disabled
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
(ns quo2.components.context-tags
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[re-frame.core :as re-frame]
|
||||
[quo2.components.text :as text]
|
||||
[quo2.components.group-avatar :as group-avatar]
|
||||
[quo.react-native :as rn]))
|
||||
|
||||
(defn padding-left-for-type [type]
|
||||
(case type
|
||||
:group-avatar 3
|
||||
8))
|
||||
|
||||
(defn trim-public-key [pk]
|
||||
(str (subs pk 0 6) "..." (subs pk (- (count pk) 3))))
|
||||
|
||||
(defn base-tag [_ _]
|
||||
(fn [{:keys [override-theme style]} & children]
|
||||
(let [theme (or override-theme (quo.theme/get-theme))]
|
||||
(into
|
||||
[rn/view
|
||||
(merge
|
||||
{:border-radius 100
|
||||
:padding-vertical 3
|
||||
:flex-direction :row
|
||||
:padding-right 8
|
||||
:padding-left 8
|
||||
:background-color (if (= theme :light)
|
||||
colors/neutral-10
|
||||
colors/neutral-80)} style)]
|
||||
children))))
|
||||
|
||||
(defn group-avatar-tag [_ _]
|
||||
(fn [label opts]
|
||||
[base-tag {:style {:padding-left 3}}
|
||||
[group-avatar/group-avatar opts]
|
||||
[text/text {:weight :medium
|
||||
:size :paragraph-2}
|
||||
|
||||
(str " " label)]]))
|
||||
|
||||
(defn public-key-tag [_ _]
|
||||
(fn [params public-key]
|
||||
[base-tag params
|
||||
[text/text {:weight :monospace
|
||||
:size :paragraph-2}
|
||||
(trim-public-key public-key)]]))
|
||||
|
||||
(defn user-avatar-tag [_ _]
|
||||
(fn [params public-key]
|
||||
(let [{:keys [name photo]} @(re-frame/subscribe [:contacts/name-and-photo public-key])]
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
[rn/image {:style {:width 20
|
||||
:border-radius 10
|
||||
:background-color :white
|
||||
:height 20}
|
||||
:source {:uri photo}}]
|
||||
[text/text {:weight :medium
|
||||
:size :paragraph-2}
|
||||
|
||||
(str " " name)]])))
|
||||
@@ -1,27 +0,0 @@
|
||||
(ns quo2.components.group-avatar
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo.react-native :as rn]))
|
||||
|
||||
(def sizes
|
||||
{:icon {:small 12
|
||||
:medium 16
|
||||
:large 20}
|
||||
:container {:small 20
|
||||
:medium 32
|
||||
:large 48}})
|
||||
|
||||
(defn group-avatar [_]
|
||||
(fn [{:keys [color size override-theme]}]
|
||||
(let [theme (or override-theme (quo.theme/get-theme))
|
||||
container-size (get-in sizes [:container size])
|
||||
icon-size (get-in sizes [:icon size])]
|
||||
[rn/view {:width container-size
|
||||
:height container-size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius (/ container-size 2)
|
||||
:background-color (colors/custom-color color theme)}
|
||||
[icon/icon :total-members {:size icon-size
|
||||
:color colors/white-opa-70}]])))
|
||||
@@ -10,17 +10,11 @@
|
||||
[icons/icon (str (name icon-name) size) (merge props
|
||||
{:width size
|
||||
:height size})])))
|
||||
(defn icon-for-theme
|
||||
([icon-name theme]
|
||||
(icon-for-theme icon-name theme nil))
|
||||
([icon-name theme props]
|
||||
(let [theme-icon-name (if (= theme :dark)
|
||||
(str (name icon-name) "-dark")
|
||||
icon-name)]
|
||||
(icon theme-icon-name props))))
|
||||
|
||||
(defn theme-icon
|
||||
([icon-name]
|
||||
(theme-icon icon-name nil))
|
||||
([icon-name props]
|
||||
(icon-for-theme icon-name (theme/get-theme) props)))
|
||||
(let [theme-icon-name (if (theme/dark?)
|
||||
(str (name icon-name) "-dark")
|
||||
icon-name)]
|
||||
(icon theme-icon-name props))))
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
(ns quo2.components.info-message
|
||||
(:require [quo.theme :as theme]
|
||||
[quo.react-native :as rn]
|
||||
[quo2.components.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as quo2.icons]))
|
||||
|
||||
(def themes
|
||||
{:light {:default colors/neutral-40
|
||||
:success colors/success-50
|
||||
:error colors/danger-50}
|
||||
:dark {:default colors/neutral-60
|
||||
:success colors/success-60
|
||||
:error colors/danger-60}})
|
||||
|
||||
(defn get-color [key]
|
||||
(get-in themes [(theme/get-theme) key]))
|
||||
|
||||
(defn info-message
|
||||
"[info-message opts \"message\"]
|
||||
opts
|
||||
{:type :default/:success/:error
|
||||
:size :default/:tiny
|
||||
:icon :main-icons/info ;; info message icon
|
||||
:text-color colors/white ;; text color override
|
||||
:icon-color colors/white ;; icon color override"
|
||||
[{:keys [type size icon text-color icon-color]} message]
|
||||
(let [weight (if (= size :default) :regular :medium)
|
||||
size (if (= size :default) :paragraph-2 :label)
|
||||
text-color (or text-color (get-color type))
|
||||
icon-color (or icon-color text-color)]
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:flex 1}}
|
||||
[quo2.icons/icon icon {:color icon-color
|
||||
:size 12
|
||||
:container-style {:margin-top 3}}]
|
||||
[text/text {:size size
|
||||
:weight weight
|
||||
:style {:color text-color
|
||||
:margin-horizontal 8}} message]]))
|
||||
@@ -1,91 +0,0 @@
|
||||
(ns quo2.components.information-box
|
||||
(:require [quo.theme :as theme]
|
||||
[quo.react-native :as rn]
|
||||
[clojure.string :as string]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.button :as quo2.button]
|
||||
[quo2.components.info-message :as info-message]))
|
||||
|
||||
(def themes
|
||||
{:light {:default {:bg colors/white
|
||||
:border colors/neutral-20
|
||||
:icon colors/neutral-50
|
||||
:text colors/black}
|
||||
:informative {:bg colors/primary-50-opa-5
|
||||
:border colors/primary-50-opa-10
|
||||
:icon colors/primary-50
|
||||
:text colors/black}
|
||||
:error {:bg colors/danger-50-opa-5
|
||||
:border colors/danger-50-opa-10
|
||||
:icon colors/danger-50
|
||||
:text colors/danger-50}
|
||||
:close-button colors/black}
|
||||
:dark {:default {:bg colors/neutral-90
|
||||
:border colors/neutral-70
|
||||
:icon colors/neutral-40
|
||||
:text colors/white}
|
||||
:informative {:bg colors/primary-50-opa-5
|
||||
:border colors/primary-50-opa-10
|
||||
:icon colors/white
|
||||
:text colors/white}
|
||||
:error {:bg colors/danger-50-opa-5
|
||||
:border colors/danger-50-opa-10
|
||||
:icon colors/danger-50
|
||||
:text colors/danger-50}
|
||||
:close-button colors/white}})
|
||||
|
||||
(defn get-color [key]
|
||||
(get-in themes [(theme/get-theme) key]))
|
||||
|
||||
(defn get-color-by-type [type key]
|
||||
(get-in themes [(theme/get-theme) type key]))
|
||||
|
||||
(defn information-box
|
||||
"[information-box opts \"message\"]
|
||||
opts
|
||||
{:type :default/:informative/:error
|
||||
:closable? true/false ;; allow information box to be closed?
|
||||
:closed? true/false ;; information box's state
|
||||
:id :information-box-id ;; unique id (required for closable? information box)
|
||||
:icon :main-icons/info ;; information box icon
|
||||
:style style
|
||||
:button-label \"PressMe\" ;; add action button with label
|
||||
:on-button-press action ;; (required for information box with button-label)
|
||||
:on-close on-close ;; (optional on-close call)"
|
||||
[{:keys [type closable? closed? id icon style button-label on-button-press on-close]} message]
|
||||
(let [background-color (get-color-by-type type :bg)
|
||||
border-color (get-color-by-type type :border)
|
||||
icon-color (get-color-by-type type :icon)
|
||||
text-color (get-color-by-type type :text)
|
||||
include-button? (not (string/blank? button-label))]
|
||||
(when-not closed?
|
||||
[rn/view {:accessibility-label (or id :information-box)
|
||||
:style (merge {:background-color background-color
|
||||
:border-color border-color
|
||||
:border-width 1
|
||||
:border-radius 12
|
||||
:padding-top (if include-button? 10 11)
|
||||
:padding-bottom (if include-button? 12 11)
|
||||
:padding-horizontal 16} style)}
|
||||
[rn/view {:style {:flex-direction :row
|
||||
:align-self :flex-start}}
|
||||
[info-message/info-message {:size :default
|
||||
:icon icon
|
||||
:text-color text-color
|
||||
:icon-color icon-color} message]
|
||||
(when closable?
|
||||
[rn/touchable-opacity
|
||||
{:on-press on-close
|
||||
:accessibility-label (str (or id "information-box") "-close-button")}
|
||||
[quo2.icons/icon :main-icons2/close {:size 12
|
||||
:color (get-color :close-button)
|
||||
:container-style {:margin-top 4
|
||||
:margin-left 8}}]])]
|
||||
(when include-button?
|
||||
[quo2.button/button {:type :primary
|
||||
:size 24
|
||||
:on-press on-button-press
|
||||
:style {:margin-left 20
|
||||
:margin-top 8
|
||||
:align-self :flex-start}} button-label])])))
|
||||
@@ -1,131 +0,0 @@
|
||||
(ns quo2.components.permission-tag
|
||||
(:require [status-im.ui.components.react :as react]
|
||||
[quo2.components.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.base-tag :as base-tag]
|
||||
[status-im.i18n.i18n :as i18n]))
|
||||
|
||||
(defn outer-resource-container [size background-color]
|
||||
{:background-color background-color
|
||||
:border-radius size
|
||||
:width size
|
||||
:height size
|
||||
:margin-left (case size 32 -12 24 -8)
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(defn extra-count-styles [size]
|
||||
{:background-color (colors/theme-colors
|
||||
colors/neutral-20
|
||||
colors/neutral-70)
|
||||
:height (case size 32 28 24 20)
|
||||
:width (case size 32 28 24 20)
|
||||
:border-radius size
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(defn tag-extra-count [total-group-count selected-count size background-color]
|
||||
(let [extra-group-count (- total-group-count selected-count)]
|
||||
(when (> extra-group-count 0)
|
||||
[react/view (outer-resource-container size background-color)
|
||||
[react/view (extra-count-styles size)
|
||||
(if (< extra-group-count 4)
|
||||
[text/text {:size :label
|
||||
:style {:align-items :center
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}}
|
||||
(str "+" extra-group-count)]
|
||||
[icons/icon :main-icons2/pending-default {:container-style {:align-items :center
|
||||
:justify-content :center}
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)
|
||||
:size 12}])]])))
|
||||
|
||||
(defn tag-or-text [size]
|
||||
[react/view {:align-items :center}
|
||||
[text/text {:weight :medium
|
||||
:size (case size 32 :paragraph-2 24 :label)
|
||||
:style {:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)
|
||||
:padding-left 4
|
||||
:text-transform :lowercase
|
||||
:padding-right (case size 32 16 24 12)}}
|
||||
(i18n/label :t/or)]])
|
||||
|
||||
(defn selected-token-count [group]
|
||||
(cond
|
||||
(= (count group) 3) 3
|
||||
|
||||
(> (count group) 3) 2
|
||||
|
||||
:else
|
||||
(count group)))
|
||||
|
||||
(defn token-group []
|
||||
(fn [{:keys [group size last-group background-color]
|
||||
:or {size 24}}]
|
||||
(let [tokens-count (count group)
|
||||
selected-tokens (take (selected-token-count group) group)]
|
||||
[react/view {:flex-direction :row
|
||||
:align-items :center}
|
||||
(for [{:keys [token-icon]} selected-tokens]
|
||||
^{:key token-icon}
|
||||
[react/view {:flex-direction :row}
|
||||
[react/view (outer-resource-container size background-color)
|
||||
[react/image {:source token-icon
|
||||
:style {:height (case size 32 28 24 20)
|
||||
:width (case size 32 28 24 20)
|
||||
:border-radius size}}]]])
|
||||
|
||||
[tag-extra-count tokens-count (count selected-tokens) size]
|
||||
(when-not last-group
|
||||
[tag-or-text size])])))
|
||||
|
||||
(defn selected-group-count [token-groups]
|
||||
(cond
|
||||
(> (count token-groups) 3) 3
|
||||
|
||||
:else
|
||||
(count token-groups)))
|
||||
|
||||
(defn tokens []
|
||||
(fn [{:keys [token-groups size background-color]
|
||||
:or {size 24}}]
|
||||
(let [selected-groups (take (selected-group-count token-groups) token-groups)
|
||||
last-group-id ((last selected-groups) :id)]
|
||||
[react/view {:flex-direction :row
|
||||
:align-items :center}
|
||||
(for [{:keys [id group]} selected-groups]
|
||||
^{:key id}
|
||||
[token-group {:group group
|
||||
:size size
|
||||
:last-group (if (= id last-group-id) true false)
|
||||
:selected-groups selected-groups
|
||||
:background-color background-color}])])))
|
||||
|
||||
(defn tag
|
||||
[_ _]
|
||||
(fn [{:keys [locked? token-groups size background-color]
|
||||
:or {size 24}}]
|
||||
[base-tag/base-tag {:background-color background-color
|
||||
:size size
|
||||
:type :permission}
|
||||
[react/view {:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :flex-end}
|
||||
[react/view {:padding-left 8
|
||||
:padding-right (case size 32 16 24 12)}
|
||||
[icons/icon (if locked? :main-icons2/locked
|
||||
:main-icons2/unlocked)
|
||||
{:resize-mode :center
|
||||
:size (case size 32 20 24 16)
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}]]
|
||||
[tokens {:token-groups token-groups
|
||||
:size size
|
||||
:background-color background-color}]]]))
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns quo2.components.status-tags
|
||||
(:require [status-im.i18n.i18n :as i18n]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.text :as text]
|
||||
[quo.react-native :as rn]))
|
||||
@@ -25,7 +24,6 @@
|
||||
border-color
|
||||
background-color
|
||||
icon
|
||||
theme
|
||||
text-color
|
||||
label]}]
|
||||
(let [paragraph-size (if (= size :small) :paragraph-2 :paragraph-1)]
|
||||
@@ -33,62 +31,49 @@
|
||||
(assoc (if (= size :small)
|
||||
small-container-style
|
||||
large-container-style)
|
||||
:border-width 1
|
||||
:border-color border-color
|
||||
:background-color background-color)
|
||||
[rn/view {:flex-direction :row
|
||||
:flex 1}
|
||||
[rn/view {:style {:justify-content :center
|
||||
:align-items :center}}
|
||||
[icon/icon-for-theme
|
||||
icon
|
||||
theme
|
||||
{:no-color true
|
||||
:size 12}]]
|
||||
[text/text {:size paragraph-size}
|
||||
[icon/theme-icon icon {:color :none
|
||||
:size 12}]
|
||||
[text/text {:size paragraph-size
|
||||
:weight :medium
|
||||
:style {:padding-left 5
|
||||
:color text-color}} label]]])))
|
||||
:style {:color text-color}} (str " " label)]]])))
|
||||
|
||||
(defn positive [_ _]
|
||||
(fn [size theme]
|
||||
(defn positive [_]
|
||||
(fn [size]
|
||||
[base-tag {:size size
|
||||
:background-color colors/success-50-opa-10
|
||||
:icon :verified
|
||||
:border-color colors/success-50-opa-20
|
||||
:text-color (if (= theme :light) colors/success-50
|
||||
colors/success-60)
|
||||
:text-color (colors/theme-colors colors/success-50
|
||||
colors/success-60)
|
||||
:label (i18n/label :positive)}]))
|
||||
|
||||
(defn negative [_ _]
|
||||
(fn [size theme]
|
||||
(defn negative [_]
|
||||
(fn [size]
|
||||
[base-tag {:size size
|
||||
:icon :untrustworthy
|
||||
:background-color colors/danger-50-opa-10
|
||||
:border-color colors/danger-50-opa-20
|
||||
:text-color (if (= theme :light)
|
||||
colors/danger-50
|
||||
colors/danger-60)
|
||||
:text-color (colors/theme-colors colors/danger-50
|
||||
colors/danger-60)
|
||||
:label (i18n/label :negative)}]))
|
||||
|
||||
(defn pending [_ _]
|
||||
(fn [size theme]
|
||||
(defn pending [_]
|
||||
(fn [size]
|
||||
[base-tag {:size size
|
||||
:icon :pending
|
||||
:background-color (if (= theme :light)
|
||||
colors/neutral-10
|
||||
colors/neutral-80)
|
||||
:border-color (if (= theme :light)
|
||||
colors/neutral-20
|
||||
colors/neutral-70)
|
||||
:background-color (colors/theme-colors colors/neutral-10
|
||||
colors/neutral-80)
|
||||
:border-color (colors/theme-colors colors/neutral-20
|
||||
colors/neutral-70)
|
||||
:text-color colors/neutral-50
|
||||
:label (i18n/label :pending)}]))
|
||||
|
||||
(defn status-tag [_]
|
||||
(fn [{:keys [status size override-theme]}]
|
||||
(let [theme (or override-theme (quo.theme/get-theme))]
|
||||
[(case status
|
||||
:positive positive
|
||||
:negative negative
|
||||
:pending pending
|
||||
nil) size theme])))
|
||||
(fn [{:keys [status size]}]
|
||||
[(case status
|
||||
:positive positive
|
||||
:negative negative
|
||||
:pending pending
|
||||
nil) size]))
|
||||
|
||||
@@ -183,67 +183,6 @@
|
||||
(def info-50-opa-30 (alpha info-50 0.3))
|
||||
(def info-50-opa-40 (alpha info-50 0.4))
|
||||
|
||||
;; Customization
|
||||
(def purple-50 "#8661C1")
|
||||
(def purple-60 "#5E478C")
|
||||
(def indigo-50 "#496289")
|
||||
(def indigo-60 "#3D5273")
|
||||
(def turquoise-50 "#448EA2")
|
||||
(def turquoise-60 "#397788")
|
||||
(def blue-50 "#4CB4EF")
|
||||
(def blue-60 "#4097C9")
|
||||
(def green-50 "#5BCC95")
|
||||
(def green-60 "#4CAB7D")
|
||||
(def yellow-50 "#FFCB53")
|
||||
(def yellow-60 "#D6AA46")
|
||||
(def orange-50 "#FB8F61")
|
||||
(def orange-60 "#D37851")
|
||||
(def red-50 "#F46666")
|
||||
(def red-60 "#CD565")
|
||||
(def pink-50 "#FC7BAB")
|
||||
(def pink-60 "#D46790")
|
||||
(def brown-50 "#99604D")
|
||||
(def brown-60 "#805141")
|
||||
(def beige-50 "#CAAE93")
|
||||
(def beige-60 "#AA927C")
|
||||
|
||||
(def customization
|
||||
{:dark {:purple purple-60
|
||||
:indigo indigo-60
|
||||
:turquoise turquoise-60
|
||||
:blue blue-60
|
||||
:green green-60
|
||||
:yellow yellow-60
|
||||
:orange orange-60
|
||||
:red red-60
|
||||
:pink pink-60
|
||||
:brown brown-60
|
||||
:beige beige-60}
|
||||
:light {:purple purple-50
|
||||
:indigo indigo-50
|
||||
:turquoise turquoise-50
|
||||
:blue blue-50
|
||||
:green green-50
|
||||
:yellow yellow-50
|
||||
:orange orange-50
|
||||
:red red-50
|
||||
:pink pink-50
|
||||
:brown brown-50
|
||||
:beige beige-50}})
|
||||
|
||||
(defn custom-color [color theme]
|
||||
(get-in customization [theme color]))
|
||||
|
||||
;;;;Switcher
|
||||
(def switcher-background "#040B14")
|
||||
|
||||
;;switcher-screen with transparency
|
||||
(def switcher-background-opa-60 (alpha switcher-background 0.6))
|
||||
(def switcher-background-opa-70 (alpha switcher-background 0.7))
|
||||
(def switcher-background-opa-80 (alpha switcher-background 0.8))
|
||||
(def switcher-background-opa-90 (alpha switcher-background 0.9))
|
||||
(def switcher-background-opa-95 (alpha switcher-background 0.95))
|
||||
|
||||
;;General
|
||||
|
||||
;; background
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
(ns quo2.foundations.typography)
|
||||
|
||||
;; Formulat for letter spacing from figma %: font-size*{figma-percentage}/100
|
||||
(def heading-1 {:font-size 27
|
||||
:line-height 32
|
||||
:letter-spacing -0.567})
|
||||
(def heading-1 {:font-size 27
|
||||
:line-height 32.4
|
||||
:letter-spacing -0.5})
|
||||
|
||||
(def heading-2 {:font-size 19
|
||||
:line-height 25.65
|
||||
:letter-spacing -0.304})
|
||||
(def heading-2 {:font-size 19
|
||||
:line-height 25.65
|
||||
:letter-spacing -0.4})
|
||||
|
||||
(def paragraph-1 {:font-size 15
|
||||
:line-height 21.75
|
||||
:letter-spacing -0.135})
|
||||
(def paragraph-1 {:font-size 15
|
||||
:line-height 21.75
|
||||
:letter-spacing -0.1})
|
||||
|
||||
(def paragraph-2 {:font-size 13
|
||||
:line-height 18.2
|
||||
:letter-spacing -0.039})
|
||||
(def paragraph-2 {:font-size 13
|
||||
:line-height 18.2
|
||||
:letter-spacing 0})
|
||||
|
||||
(def label {:font-size 11
|
||||
:line-height 15.62
|
||||
:letter-spacing -0.055})
|
||||
(def label {:font-size 11
|
||||
:line-height 15.62
|
||||
:letter-spacing -0.055
|
||||
:text-transform :uppercase})
|
||||
|
||||
(def font-regular {:font-family "Inter-Regular"}) ; 400
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
|
||||
(def font-bold {:font-family "Inter-Bold"}) ; 700
|
||||
|
||||
(def monospace {:font-family "InterStatus-Regular"})
|
||||
(def monospace {:font-family "InterStatus-Regular"})
|
||||
@@ -1,87 +0,0 @@
|
||||
(ns quo2.screens.activity-logs
|
||||
(:require [reagent.core :as reagent]
|
||||
[quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.screens.status-tags :as status-tags]
|
||||
[quo2.components.activity-logs :as activity-logs]))
|
||||
|
||||
(def descriptor [{:label "Unread:"
|
||||
:key :unread
|
||||
:type :boolean}
|
||||
{:label "Icon"
|
||||
:key :icon
|
||||
:type :select
|
||||
:options [{:key :placeholder
|
||||
:value :placeholder}]}
|
||||
{:label "Title"
|
||||
:key :title
|
||||
:type :text}
|
||||
{:label :message
|
||||
:key :message
|
||||
:type :text}
|
||||
{:label "Timestamp"
|
||||
:key :timestamp
|
||||
:type :text}
|
||||
{:label "Button 1 type"
|
||||
:key :button-1-type
|
||||
:type :select
|
||||
:options [{:value "Danger"
|
||||
:key :danger}
|
||||
{:value "Primary"
|
||||
:key :primary}
|
||||
{:value "Success"
|
||||
:key :success}]}
|
||||
{:label "Button 1 label"
|
||||
:key :button-1-label
|
||||
:type :text}
|
||||
{:label "Button 2 type"
|
||||
:key :button-2-type
|
||||
:type :select
|
||||
:options [{:value "Danger"
|
||||
:key :danger}
|
||||
{:value "Primary"
|
||||
:key :primary}
|
||||
{:value "Success"
|
||||
:key :success}]}
|
||||
{:label "Button 2 label"
|
||||
:key :button-2-label
|
||||
:type :text}
|
||||
status-tags/status-tags-options])
|
||||
|
||||
(defn preview []
|
||||
(let [state (reagent/atom {:title "Activity Title"
|
||||
:timestamp "Yesterday ∙ 10:41"
|
||||
:message "Hello Alisher! Do you remember me from the web 3.0 conference in Porto?"
|
||||
:icon :placeholder})]
|
||||
(fn []
|
||||
(let [{:keys [button-1-type
|
||||
button-1-label
|
||||
button-2-type
|
||||
button-2-label]} @state
|
||||
props (cond-> @state
|
||||
(and (seq button-1-label)
|
||||
button-1-type)
|
||||
(assoc :button-1 {:label button-1-label
|
||||
:type button-1-type})
|
||||
|
||||
(and (seq button-2-label)
|
||||
button-2-type)
|
||||
(assoc :button-2 {:label button-2-label
|
||||
:type button-2-type}))]
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-vertical 60
|
||||
:background-color colors/neutral-95-opa-80
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
[activity-logs/activity-logs props]]]))))
|
||||
|
||||
(defn preview-activity-logs []
|
||||
[rn/view {:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [preview]
|
||||
:key-fn str}]])
|
||||
@@ -1,70 +0,0 @@
|
||||
(ns quo2.screens.context-tags
|
||||
(:require [reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.context-tags :as quo2]))
|
||||
|
||||
(def group-avatar-default-params
|
||||
{:size :small
|
||||
:color :purple})
|
||||
|
||||
(def example-pk "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917")
|
||||
|
||||
(def descriptor [{:label "Type"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :public-key
|
||||
:value "Public key"}
|
||||
{:key :avatar
|
||||
:value "Avatar"}
|
||||
{:key :group-avatar
|
||||
:value "Group avatar"}]}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:label "Name"
|
||||
:type :group-avatar})]
|
||||
(fn []
|
||||
(let [contacts @(re-frame/subscribe [:contacts/contacts])
|
||||
descriptor
|
||||
(cond-> descriptor
|
||||
(= (:type @state) :group-avatar)
|
||||
(conj {:label "Label"
|
||||
:key :label
|
||||
:type :text})
|
||||
(= (:type @state) :avatar)
|
||||
(conj {:label "Contacts"
|
||||
:key :contact
|
||||
:type :select
|
||||
:options
|
||||
(map (fn [{:keys [public-key]}]
|
||||
{:key public-key
|
||||
:value (multiaccounts/displayed-name
|
||||
(get contacts public-key))})
|
||||
(vals contacts))}))]
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-vertical 60
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
(case (:type @state)
|
||||
:group-avatar
|
||||
[quo2/group-avatar-tag (:label @state) group-avatar-default-params]
|
||||
:public-key
|
||||
[quo2/public-key-tag {} example-pk]
|
||||
|
||||
:avatar
|
||||
[quo2/user-avatar-tag {} (:contact @state)])]]))))
|
||||
|
||||
(defn preview-context-tags []
|
||||
[rn/view {:background-color (colors/theme-colors colors/white
|
||||
colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -1,50 +0,0 @@
|
||||
(ns quo2.screens.group-avatar
|
||||
(:require [reagent.core :as reagent]
|
||||
[quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.group-avatar :as quo2]))
|
||||
|
||||
(def descriptor [{:label "Size"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key :small
|
||||
:value "Small"}
|
||||
{:key :medium
|
||||
:value "Medium"}
|
||||
{:key :large
|
||||
:value "Large"}]}
|
||||
{:label "Color"
|
||||
:key :color
|
||||
:type :select
|
||||
:options
|
||||
(map
|
||||
(fn [c]
|
||||
{:key c
|
||||
:value c})
|
||||
(-> colors/customization
|
||||
:light
|
||||
keys))}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:theme :light
|
||||
:color :purple
|
||||
:size :small})]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-vertical 60
|
||||
:flex-direction :row
|
||||
:justify-content :center}
|
||||
[quo2/group-avatar @state]]])))
|
||||
|
||||
(defn preview-group-avatar []
|
||||
[rn/view {:background-color (colors/theme-colors colors/white
|
||||
colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -1,47 +0,0 @@
|
||||
(ns quo2.screens.info-message
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.info-message :as quo2]))
|
||||
|
||||
(def descriptor [{:label "Type:"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :default
|
||||
:value "Default"}
|
||||
{:key :success
|
||||
:value "Success"}
|
||||
{:key :error
|
||||
:value "Error"}]}
|
||||
{:label "Size:"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key :default
|
||||
:value "Default"}
|
||||
{:key :tiny
|
||||
:value "Tiny"}]}
|
||||
{:label "Message"
|
||||
:key :message
|
||||
:type :text}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:type :default
|
||||
:size :default
|
||||
:icon :main-icons2/placeholder
|
||||
:message "This is a message"})]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view {:padding-vertical 60
|
||||
:align-items :center}
|
||||
[quo2/info-message @state (:message @state)]]])))
|
||||
|
||||
(defn preview-info-message []
|
||||
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -1,51 +0,0 @@
|
||||
(ns quo2.screens.information-box
|
||||
(:require [quo.react-native :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.information-box :as quo2]))
|
||||
|
||||
(def descriptor [{:label "Type:"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :default
|
||||
:value "Default"}
|
||||
{:key :informative
|
||||
:value "Informative"}
|
||||
{:key :error
|
||||
:value "Error"}]}
|
||||
{:label "Closable?:"
|
||||
:key :closable?
|
||||
:type :boolean}
|
||||
{:label "Message"
|
||||
:key :message
|
||||
:type :text}
|
||||
{:label "Button Label"
|
||||
:key :button-label
|
||||
:type :text}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:type :default
|
||||
:closable? true
|
||||
:icon :main-icons2/placeholder
|
||||
:message "This is an information box This is an information"
|
||||
:button-label "Press Me"
|
||||
:style {:width 335}
|
||||
:id (keyword (str "id-" (rand-int 10000)))})
|
||||
closed? (reagent/cursor state [:closed?])
|
||||
on-close #(reset! closed? true)]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[preview/customizer state descriptor]
|
||||
[rn/view {:padding-vertical 60
|
||||
:align-items :center}
|
||||
[quo2/information-box (merge @state {:on-close on-close}) (:message @state)]]])))
|
||||
|
||||
(defn preview-information-box []
|
||||
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -7,15 +7,9 @@
|
||||
[quo2.screens.text :as text]
|
||||
[quo2.screens.tabs :as tabs]
|
||||
[quo2.screens.status-tags :as status-tags]
|
||||
[quo2.screens.context-tags :as context-tags]
|
||||
[quo2.screens.group-avatar :as group-avatar]
|
||||
[quo2.screens.activity-logs :as activity-logs]
|
||||
[quo2.screens.counter :as counter]
|
||||
[quo2.screens.segmented :as segmented]
|
||||
[quo2.screens.info-message :as info-message]
|
||||
[quo2.screens.information-box :as information-box]
|
||||
[quo.components.safe-area :as safe-area]
|
||||
[quo2.screens.permission-tag :as permission-tag]
|
||||
[quo.core :as quo]))
|
||||
|
||||
(def screens [{:name :quo2-texts
|
||||
@@ -27,15 +21,6 @@
|
||||
{:name :quo2-status-tags
|
||||
:insets {:top false}
|
||||
:component status-tags/preview-status-tags}
|
||||
{:name :quo2-context-tags
|
||||
:insets {:top false}
|
||||
:component context-tags/preview-context-tags}
|
||||
{:name :quo2-group-avatar
|
||||
:insets {:top false}
|
||||
:component group-avatar/preview-group-avatar}
|
||||
{:name :quo2-activity-logs
|
||||
:insets {:top false}
|
||||
:component activity-logs/preview-activity-logs}
|
||||
{:name :quo2-tabs
|
||||
:insets {:top false}
|
||||
:component tabs/preview-tabs}
|
||||
@@ -44,16 +29,7 @@
|
||||
:component segmented/preview-segmented}
|
||||
{:name :quo2-counter
|
||||
:insets {:top false}
|
||||
:component counter/preview-counter}
|
||||
{:name :info-message
|
||||
:insets {:top false}
|
||||
:component info-message/preview-info-message}
|
||||
{:name :information-box
|
||||
:insets {:top false}
|
||||
:component information-box/preview-information-box}
|
||||
{:name :quo2-permission-tag
|
||||
:insets {:top false}
|
||||
:component permission-tag/preview-permission-tag}])
|
||||
:component counter/preview-counter}])
|
||||
|
||||
(defn theme-switcher []
|
||||
[rn/view {:style {:flex-direction :row
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
(ns quo2.screens.permission-tag
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.components.permission-tag :as permission-tag]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def descriptor [{:label "Size:"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key 32
|
||||
:value "32"}
|
||||
{:key 24
|
||||
:value "24"}]}
|
||||
{:label "Locked:"
|
||||
:key :locked?
|
||||
:type :boolean}])
|
||||
|
||||
(def community-tokens
|
||||
[{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 1 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 3 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 3 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 3 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}]}
|
||||
{:token-groups [{:id 1 :group [{:id 1 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 2 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}]}
|
||||
{:id 3 :group [{:id 1 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 2 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 3 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 4 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 5 :token-icon (resources/get-image :status-logo)}
|
||||
{:id 6 :token-icon (resources/get-image :status-logo)}]}]}])
|
||||
|
||||
(defn cool-preview []
|
||||
(let [state (reagent/atom {:size 32})]
|
||||
(fn []
|
||||
[rn/view {:margin-bottom 50
|
||||
:padding 16}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view {:padding-vertical 60
|
||||
:justify-content :center}
|
||||
(when @state
|
||||
(for [{:keys [token-groups]} community-tokens]
|
||||
^{:key token-groups}
|
||||
[rn/view {:margin-top 20
|
||||
:align-self :flex-end}
|
||||
[permission-tag/tag (merge @state
|
||||
{:token-groups token-groups
|
||||
:background-color (colors/theme-colors
|
||||
colors/neutral-10
|
||||
colors/neutral-80)})]]))]])))
|
||||
|
||||
(defn preview-permission-tag []
|
||||
[rn/view {:background-color (colors/theme-colors
|
||||
colors/neutral-5
|
||||
colors/neutral-95)
|
||||
:flex 1}
|
||||
[rn/flat-list {:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
||||
@@ -5,18 +5,15 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.status-tags :as quo2]))
|
||||
|
||||
(def status-tags-options
|
||||
{:label "Status"
|
||||
:key :status
|
||||
:type :select
|
||||
:options [{:value "Positive"
|
||||
:key :positive}
|
||||
{:value "Negative"
|
||||
:key :negative}
|
||||
{:value "Pending"
|
||||
:key :pending}]})
|
||||
|
||||
(def descriptor [status-tags-options
|
||||
(def descriptor [{:label "Status"
|
||||
:key :status
|
||||
:type :select
|
||||
:options [{:value "Positive"
|
||||
:key :positive}
|
||||
{:value "Negative"
|
||||
:key :negative}
|
||||
{:value "Pending"
|
||||
:key :pending}]}
|
||||
{:label "Size"
|
||||
:key :size
|
||||
:type :select
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
(def ^:const timeline-chat-type 5)
|
||||
(def ^:const community-chat-type 6)
|
||||
|
||||
(def ^:const contact-request-message-state-none 0)
|
||||
(def ^:const contact-request-message-state-pending 1)
|
||||
(def ^:const contact-request-message-state-accepted 2)
|
||||
(def ^:const contact-request-message-state-declined 3)
|
||||
|
||||
@@ -312,45 +312,3 @@
|
||||
cofx
|
||||
(navigation/open-modal :buy-crypto nil)
|
||||
(wallet/keep-watching-history)))
|
||||
|
||||
;; Information Box
|
||||
|
||||
(def closable-information-boxes
|
||||
[{:id :ens-banner
|
||||
:global? true}]) ;; global? - close information box across all profiles
|
||||
|
||||
(defn information-box-id-hash [id public-key global?]
|
||||
(if global?
|
||||
(hash id)
|
||||
(hash (str public-key id))))
|
||||
|
||||
(fx/defn close-information-box
|
||||
{:events [:close-information-box]}
|
||||
[{:keys [db]} id global?]
|
||||
(let [public-key (get-in db [:multiaccount :public-key])
|
||||
hash (information-box-id-hash id public-key global?)]
|
||||
{::async-storage/set! {hash true}
|
||||
:db (assoc-in db [:information-box-states id] true)}))
|
||||
|
||||
(fx/defn information-box-states-loaded
|
||||
{:events [:information-box-states-loaded]}
|
||||
[{:keys [db]} hashes states]
|
||||
{:db (assoc db :information-box-states (reduce
|
||||
(fn [acc [id hash]]
|
||||
(assoc acc id (get states hash)))
|
||||
{} hashes))})
|
||||
|
||||
(fx/defn load-information-box-states
|
||||
{:events [:load-information-box-states]}
|
||||
[{:keys [db]}]
|
||||
(let [public-key (get-in db [:multiaccount :public-key])
|
||||
{:keys [keys hashes]} (reduce (fn [acc {:keys [id global?]}]
|
||||
(let [hash (information-box-id-hash
|
||||
id public-key global?)]
|
||||
(-> acc
|
||||
(assoc-in [:hashes id] hash)
|
||||
(update :keys #(conj % hash)))))
|
||||
{} closable-information-boxes)]
|
||||
{::async-storage/get {:keys keys
|
||||
:cb #(re-frame/dispatch
|
||||
[:information-box-states-loaded hashes %])}}))
|
||||
|
||||
@@ -57,8 +57,7 @@
|
||||
(assoc :multiaccounts/logout? logout?)
|
||||
(assoc :multiaccounts/loading false))
|
||||
:dispatch-n [[::initialize-view]
|
||||
[:get-opted-in-to-new-terms-of-service]
|
||||
[:load-information-box-states]]})))
|
||||
[:get-opted-in-to-new-terms-of-service]]})))
|
||||
|
||||
(fx/defn start-app
|
||||
{:events [:init/app-started]}
|
||||
|
||||
@@ -3,48 +3,37 @@
|
||||
[day8.re-frame.test :as rf-test]
|
||||
[re-frame.core :as rf]
|
||||
status-im.events
|
||||
[status-im.multiaccounts.logout.core :as logout]
|
||||
[status-im.transport.core :as transport]
|
||||
status-im.subs ;;so integration tests can run independently
|
||||
[status-im.ethereum.core :as ethereum]
|
||||
[status-im.utils.test :as utils.test]))
|
||||
|
||||
(def password "testabc")
|
||||
|
||||
(def community {:membership 1 :name "foo" :description "bar"})
|
||||
|
||||
(def account-name "account-abc")
|
||||
|
||||
(utils.test/init!)
|
||||
|
||||
(defn initialize-app! []
|
||||
(rf/dispatch-sync [:init/app-started]))
|
||||
(def initialize-app!
|
||||
#(rf/dispatch-sync [:init/app-started]))
|
||||
|
||||
(defn generate-and-derive-addresses! []
|
||||
(rf/dispatch [:generate-and-derive-addresses]))
|
||||
(def generate-and-derive-addresses!
|
||||
#(rf/dispatch [:generate-and-derive-addresses]))
|
||||
|
||||
(defn create-multiaccount! []
|
||||
(rf/dispatch [:create-multiaccount password]))
|
||||
(def create-multiaccount!
|
||||
#(rf/dispatch [:create-multiaccount password]))
|
||||
|
||||
(defn assert-app-initialized []
|
||||
(let [app-state @(rf/subscribe [:app-state])
|
||||
multiaccounts-loading? @(rf/subscribe [:multiaccounts/loading])]
|
||||
(is (= "active" app-state))
|
||||
(is (false? multiaccounts-loading?))))
|
||||
(def assert-app-initialized
|
||||
#(let [app-state @(rf/subscribe [:app-state])
|
||||
multiaccounts-loading? @(rf/subscribe [:multiaccounts/loading])]
|
||||
(is (= "active" app-state))
|
||||
(is (false? multiaccounts-loading?))))
|
||||
|
||||
(defn assert-logout []
|
||||
(let [multiaccounts-loading? @(rf/subscribe [:multiaccounts/loading])]
|
||||
(is multiaccounts-loading?)))
|
||||
|
||||
(defn assert-multiaccounts-generated []
|
||||
(let [wizard-state @(rf/subscribe [:intro-wizard/choose-key])]
|
||||
(is (= 5 (count (:multiaccounts wizard-state))))))
|
||||
(def assert-multiaccounts-generated
|
||||
#(let [wizard-state @(rf/subscribe [:intro-wizard/choose-key])]
|
||||
(is (= 5 (count (:multiaccounts wizard-state))))))
|
||||
|
||||
(defn messenger-started []
|
||||
@(rf/subscribe [:messenger/started?]))
|
||||
|
||||
(defn assert-messenger-started []
|
||||
(is (messenger-started)))
|
||||
(def assert-messenger-started
|
||||
#(is (messenger-started)))
|
||||
|
||||
(deftest initialize-app-test
|
||||
(rf-test/run-test-sync
|
||||
@@ -54,21 +43,6 @@
|
||||
(defn assert-multiaccount-loaded []
|
||||
(is (false? @(rf/subscribe [:multiaccounts/loading]))))
|
||||
|
||||
(defn assert-community-created []
|
||||
(is (= @(rf/subscribe [:communities/create]) community)))
|
||||
|
||||
(defn create-new-account! []
|
||||
(rf/dispatch-sync [:wallet.accounts/start-adding-new-account {:type :generate}])
|
||||
(rf/dispatch-sync [:set-in [:add-account :account :name] account-name])
|
||||
(rf/dispatch [:wallet.accounts/add-new-account (ethereum/sha3 password)]))
|
||||
|
||||
(defn assert-new-account-created []
|
||||
(is (true? (some #(= (:name %) account-name)
|
||||
@(rf/subscribe [:multiaccount/accounts])))))
|
||||
|
||||
(defn logout! []
|
||||
(rf/dispatch [:logout]))
|
||||
|
||||
(deftest create-account-test
|
||||
(rf-test/run-test-async
|
||||
(initialize-app!) ; initialize app
|
||||
@@ -81,55 +55,7 @@
|
||||
(create-multiaccount!) ; create a multiaccount
|
||||
(rf-test/wait-for ; wait for login
|
||||
[::transport/messenger-started]
|
||||
(assert-messenger-started)
|
||||
(logout!)
|
||||
(rf-test/wait-for [::logout/logout-method] ; we need to logout to make sure the node is not in an inconsistent state between tests
|
||||
(assert-logout)))))))
|
||||
|
||||
(deftest create-community-test
|
||||
(rf-test/run-test-async
|
||||
(initialize-app!) ; initialize app
|
||||
(rf-test/wait-for
|
||||
[:status-im.init.core/initialize-multiaccounts]
|
||||
(generate-and-derive-addresses!) ; generate 5 new keys
|
||||
(rf-test/wait-for
|
||||
[:multiaccount-generate-and-derive-addresses-success]
|
||||
(assert-multiaccount-loaded) ; assert keys are generated
|
||||
(create-multiaccount!) ; create a multiaccount
|
||||
(rf-test/wait-for ; wait for login
|
||||
[::transport/messenger-started]
|
||||
(assert-messenger-started)
|
||||
(rf/dispatch-sync [:status-im.communities.core/open-create-community])
|
||||
(doseq [[k v] (dissoc community :membership)]
|
||||
(rf/dispatch-sync [:status-im.communities.core/create-field k v]))
|
||||
(rf/dispatch [:status-im.communities.core/create-confirmation-pressed])
|
||||
(rf-test/wait-for
|
||||
[:status-im.communities.core/community-created]
|
||||
(assert-community-created)
|
||||
(logout!)
|
||||
(rf-test/wait-for [::logout/logout-method]
|
||||
(assert-logout))))))))
|
||||
|
||||
(deftest create-wallet-account-test
|
||||
(rf-test/run-test-async
|
||||
(initialize-app!) ; initialize app
|
||||
(rf-test/wait-for
|
||||
[:status-im.init.core/initialize-multiaccounts]
|
||||
(generate-and-derive-addresses!) ; generate 5 new keys
|
||||
(rf-test/wait-for
|
||||
[:multiaccount-generate-and-derive-addresses-success]
|
||||
(assert-multiaccount-loaded) ; assert keys are generated
|
||||
(create-multiaccount!) ; create a multiaccount
|
||||
(rf-test/wait-for ; wait for login
|
||||
[::transport/messenger-started]
|
||||
(assert-messenger-started)
|
||||
(create-new-account!) ; create a new account
|
||||
(rf-test/wait-for
|
||||
[:wallet.accounts/account-stored]
|
||||
(assert-new-account-created) ; assert account was created
|
||||
(logout!)
|
||||
(rf-test/wait-for [::logout/logout-method] ; we need to logout to make sure the node is not in an inconsistent state between tests
|
||||
(assert-logout))))))))
|
||||
(assert-messenger-started))))))
|
||||
|
||||
(comment
|
||||
(run-tests))
|
||||
|
||||
@@ -12,34 +12,25 @@
|
||||
|
||||
(fx/defn handle-activities [{:keys [db]} activities]
|
||||
(let [{:keys [unread-count notifications]}
|
||||
(reduce (fn [acc {:keys [read dismissed accepted chat-id] :as notification}]
|
||||
(if (= "" chat-id)
|
||||
;; TODO(rasom): sometimes messages come with empty `chat-id`s
|
||||
;; (specifically it happens on `SyncActivityCenterRead` message).
|
||||
;; In result, if notification is received with notification center
|
||||
;; screen opened, and there is another paired device online, the
|
||||
;; last notification disappear from the screen and is shown only
|
||||
;; after reopening. It likely makes sense to fix it on status-go
|
||||
;; side, but I got lost a bit.
|
||||
acc
|
||||
(let [index-existing (->> (map-indexed vector (:notifications acc))
|
||||
(filter (fn [[idx {:keys [id]}]] (= id (:id notification))))
|
||||
first
|
||||
first)]
|
||||
(as-> acc a
|
||||
(if read
|
||||
(update a :unread-count dec)
|
||||
(update a :unread-count inc))
|
||||
(reduce (fn [acc {:keys [read dismissed accepted] :as notification}]
|
||||
(let [index-existing (->> (map-indexed vector (:notifications acc))
|
||||
(filter (fn [[idx {:keys [id]}]] (= id (:id notification))))
|
||||
first
|
||||
first)]
|
||||
(as-> acc a
|
||||
(if read
|
||||
(update a :unread-count dec)
|
||||
(update a :unread-count inc))
|
||||
|
||||
(if index-existing
|
||||
(if (or dismissed accepted)
|
||||
;; Remove at specific location
|
||||
(assoc a :notifications
|
||||
(into (subvec (:notifications a) 0 index-existing) (subvec (:notifications a) (inc index-existing))))
|
||||
;; Replace element
|
||||
(do
|
||||
(assoc-in a [:notifications index-existing] notification)))
|
||||
(update a :notifications conj notification))))))
|
||||
(if index-existing
|
||||
(if (or dismissed accepted)
|
||||
;; Remove at specific location
|
||||
(assoc a :notifications
|
||||
(into (subvec (:notifications a) 0 index-existing) (subvec (:notifications a) (inc index-existing))))
|
||||
;; Replace element
|
||||
(do
|
||||
(assoc-in a [:notifications index-existing] notification)))
|
||||
(update a :notifications conj notification)))))
|
||||
{:unread-count (get db :activity.center/notifications-count 0)
|
||||
:notifications (into [] (get-in db [:activity.center/notifications :notifications]))}
|
||||
activities)]
|
||||
|
||||
@@ -273,14 +273,6 @@
|
||||
|
||||
(reg-root-key-sub :messenger/started? :messenger/started?)
|
||||
|
||||
(reg-root-key-sub :information-box-states :information-box-states)
|
||||
|
||||
(re-frame/reg-sub
|
||||
:information-box-closed?
|
||||
:<- [:information-box-states]
|
||||
(fn [states [_ id]]
|
||||
(get states id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities
|
||||
:<- [:raw-communities]
|
||||
@@ -1936,25 +1928,19 @@
|
||||
(re-frame/reg-sub
|
||||
:activity.center/notifications-grouped-by-date
|
||||
:<- [:activity.center/notifications]
|
||||
:<- [:contacts/contacts]
|
||||
(fn [[{:keys [notifications]} contacts]]
|
||||
(fn [{:keys [notifications]}]
|
||||
(let [supported-notifications
|
||||
(filter (fn [{:keys [type last-message message]}]
|
||||
(filter (fn [{:keys [type last-message]}]
|
||||
(or (and (= constants/activity-center-notification-type-one-to-one-chat type)
|
||||
(not (nil? last-message)))
|
||||
(and (= constants/activity-center-notification-type-contact-request type)
|
||||
(not= constants/contact-request-message-state-none
|
||||
(-> contacts
|
||||
(multiaccounts/contact-by-identity (:from message))
|
||||
:contact-request-state)))
|
||||
(= constants/activity-center-notification-type-contact-request type)
|
||||
(= constants/activity-center-notification-type-contact-request-retracted type)
|
||||
(= constants/activity-center-notification-type-private-group-chat type)
|
||||
(= constants/activity-center-notification-type-reply type)
|
||||
(= constants/activity-center-notification-type-mention type)))
|
||||
notifications)]
|
||||
(group-notifications-by-date
|
||||
(map #(assoc % :timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %))))
|
||||
:contact (multiaccounts/contact-by-identity contacts (get-in % [:message :from])))
|
||||
(map #(assoc % :timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %)))))
|
||||
supported-notifications)))))
|
||||
|
||||
;;WALLET TRANSACTIONS ==================================================================================================
|
||||
|
||||
@@ -7,15 +7,12 @@
|
||||
[quo.components.animated.pressable :as pressable]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.screens.chat.components.style :as styles]
|
||||
[re-frame.core :as re-frame]
|
||||
[quo2.foundations.colors :as quo2.colors :refer [theme-colors]]
|
||||
[quo2.components.button :as quo2.button]
|
||||
[quo2.components.text :as quo2.text]))
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(defn input-focus [text-input-ref]
|
||||
(some-> ^js (quo.react/current-ref text-input-ref) .focus))
|
||||
|
||||
(defn edit-message-old []
|
||||
(defn edit-message []
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[rn/view {}
|
||||
[icons/icon :tiny-icons/tiny-edit {:container-style {:margin-top 5}}]]
|
||||
@@ -29,24 +26,6 @@
|
||||
[icons/icon :main-icons/close-circle {:container-style (styles/close-button)
|
||||
:color (:icon-02 @quo.colors/theme)}]]]])
|
||||
|
||||
(defn edit-message []
|
||||
[rn/view {:style {:flex-direction :row :height 24}}
|
||||
[rn/view {:style (styles/reply-content)}
|
||||
[icons/icon :main-icons/edit-connector {:color (theme-colors quo2.colors/neutral-40 quo2.colors/neutral-60)
|
||||
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}]
|
||||
[rn/view {:style {:position :absolute :left 36 :right 54 :top 3 :flex-direction :row :align-items :center}}
|
||||
[quo2.text/text {:weight :medium
|
||||
:size :paragraph-2}
|
||||
(i18n/label :t/editing-message)]]]
|
||||
[quo2.button/button {:width 24
|
||||
:size 24
|
||||
:type :outline
|
||||
:accessibility-label :reply-cancel-button
|
||||
:on-press #(re-frame/dispatch [:chat.ui/cancel-message-edit])}
|
||||
[icons/icon :main-icons/close {:width 16
|
||||
:height 16
|
||||
:color (theme-colors quo2.colors/black quo2.colors/neutral-40)}]]])
|
||||
|
||||
(defn focus-input-on-edit [edit had-edit text-input-ref]
|
||||
;;when we show edit we focus input
|
||||
(when-not (= edit @had-edit)
|
||||
@@ -54,13 +33,6 @@
|
||||
(when edit
|
||||
(js/setTimeout #(input-focus text-input-ref) 250))))
|
||||
|
||||
(defn edit-message-wrapper-old [edit]
|
||||
[rn/view {:style {:padding-horizontal 15
|
||||
:border-top-width 1
|
||||
:border-top-color (:ui-01 @quo.colors/theme)
|
||||
:padding-vertical 8}}
|
||||
[edit-message-old edit]])
|
||||
|
||||
(defn edit-message-wrapper [edit]
|
||||
[rn/view {:style {:padding-horizontal 15
|
||||
:border-top-width 1
|
||||
@@ -68,14 +40,6 @@
|
||||
:padding-vertical 8}}
|
||||
[edit-message edit]])
|
||||
|
||||
(defn edit-message-auto-focus-wrapper-old [text-input-ref]
|
||||
(let [had-edit (atom nil)]
|
||||
(fn []
|
||||
(let [edit @(re-frame/subscribe [:chats/edit-message])]
|
||||
(focus-input-on-edit edit had-edit text-input-ref)
|
||||
(when edit
|
||||
[edit-message-wrapper-old])))))
|
||||
|
||||
(defn edit-message-auto-focus-wrapper [text-input-ref]
|
||||
(let [had-edit (atom nil)]
|
||||
(fn []
|
||||
|
||||
@@ -350,12 +350,11 @@
|
||||
:active active-panel
|
||||
:set-active set-active-panel}])])
|
||||
|
||||
(defn chat-toolbar [{:keys [chat-id]}]
|
||||
(let [actions-ref (quo.react/create-ref)
|
||||
send-ref (quo.react/create-ref)
|
||||
sticker-ref (quo.react/create-ref)
|
||||
toolbar-options (re-frame/subscribe [:chats/chat-toolbar])
|
||||
show-send (seq (get @input-texts chat-id))]
|
||||
(defn chat-toolbar []
|
||||
(let [actions-ref (quo.react/create-ref)
|
||||
send-ref (quo.react/create-ref)
|
||||
sticker-ref (quo.react/create-ref)
|
||||
toolbar-options (re-frame/subscribe [:chats/chat-toolbar])]
|
||||
(fn [{:keys [active-panel set-active-panel text-input-ref chat-id]}]
|
||||
(let [;we want to control components on native level, so instead of RN state we set native props via reference
|
||||
;we don't react on input text in this view, @input-texts below is a regular atom
|
||||
@@ -364,7 +363,7 @@
|
||||
:sticker-ref sticker-ref
|
||||
:text-input-ref text-input-ref}
|
||||
{:keys [send stickers image extensions audio sending-image]} @toolbar-options
|
||||
show-send (or show-send sending-image)
|
||||
show-send (or sending-image (seq (get @input-texts chat-id)))
|
||||
contact-request @(re-frame/subscribe [:chats/sending-contact-request])]
|
||||
[rn/view {:style (styles/toolbar)
|
||||
:on-layout on-chat-toolbar-layout}
|
||||
|
||||
@@ -587,7 +587,7 @@
|
||||
:on-close on-close
|
||||
:on-update-inset on-update}
|
||||
[react/view
|
||||
[edit/edit-message-auto-focus-wrapper-old text-input-ref]
|
||||
[edit/edit-message-auto-focus-wrapper text-input-ref]
|
||||
[reply/reply-message-auto-focus-wrapper-old text-input-ref]
|
||||
;; We set the key so we can force a re-render as
|
||||
;; it does not rely on ratom but just atoms
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[status-im.ui.components.chat-icon.styles :as chat-icon.styles]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[quo2.components.button :as quo2.button]
|
||||
[quo2.components.information-box :as information-box])
|
||||
[quo2.components.button :as quo2.button])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn home-tooltip-view []
|
||||
@@ -190,8 +189,7 @@
|
||||
|
||||
(views/defview communities-and-chats-old []
|
||||
(views/letsubs [{:keys [items search-filter]} [:home-items]
|
||||
hide-home-tooltip? [:hide-home-tooltip?]
|
||||
information-box-closed? [:information-box-closed? :ens-banner]]
|
||||
hide-home-tooltip? [:hide-home-tooltip?]]
|
||||
(if (and (empty? items)
|
||||
(empty? search-filter)
|
||||
hide-home-tooltip?
|
||||
@@ -207,18 +205,6 @@
|
||||
:header [:<>
|
||||
(when (or (seq items) @search-active? (seq search-filter))
|
||||
[search-input-wrapper-old search-filter (empty? items)])
|
||||
[information-box/information-box
|
||||
{:type :informative
|
||||
:closable? true
|
||||
:closed? information-box-closed?
|
||||
:icon :main-icons/info
|
||||
:style {:margin 20}
|
||||
:button-label (i18n/label :t/open-dapp2)
|
||||
:on-button-press #(re-frame/dispatch
|
||||
[:browser.ui/open-url "https://ens-collect.status.im/"])
|
||||
:id :ens-banner
|
||||
:on-close #(re-frame/dispatch [:close-information-box :ens-banner true])}
|
||||
(i18n/label :t/ens-banner-message)]
|
||||
(when (and (empty? items)
|
||||
(or @search-active? (seq search-filter)))
|
||||
[start-suggestion search-filter])]
|
||||
|
||||
@@ -132,5 +132,4 @@
|
||||
constants/contact-request-message-state-declined
|
||||
[quo/text {:style {:color colors/red}} (i18n/label :t/declined)]
|
||||
constants/contact-request-message-state-pending
|
||||
[contact-request-actions (:message-id message)]
|
||||
nil)])]))
|
||||
[contact-request-actions (:message-id message)])])]))
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
config
|
||||
accounts-data))
|
||||
|
||||
:logout (fn []
|
||||
(.logout native-status))
|
||||
:generateAliasAndIdenticonAsync (fn [seed callback]
|
||||
(let [generated-identicon (.identicon native-status seed)
|
||||
generated-alias (.generateAlias native-status seed)]
|
||||
@@ -52,16 +50,6 @@
|
||||
(.multiAccountGenerateAndDeriveAddresses
|
||||
native-status
|
||||
json)))
|
||||
:multiAccountLoadAccount (fn [json callback]
|
||||
(callback
|
||||
(.multiAccountLoadAccount
|
||||
native-status
|
||||
json)))
|
||||
:multiAccountDeriveAddresses (fn [json callback]
|
||||
(callback
|
||||
(.multiAccountDeriveAddresses
|
||||
native-status
|
||||
json)))
|
||||
:initKeystore (fn [key-uid callback]
|
||||
(callback
|
||||
(.initKeystore
|
||||
|
||||
@@ -52,11 +52,11 @@ class TestOnboardingOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
self.profile.share_via_messenger()
|
||||
if not self.profile.element_by_text_part(public_key).is_element_present():
|
||||
self.errors.append("Can't share public key")
|
||||
self.profile.click_system_back_button_until_element_is_shown()
|
||||
self.profile.click_system_back_button()
|
||||
|
||||
self.home.just_fyi("Check that can paste contact code in chat message input")
|
||||
self.profile.home_button.double_click()
|
||||
chat = self.home.add_contact(transaction_senders['M']['public_key'])
|
||||
home = self.profile.home_button.click()
|
||||
chat = home.add_contact(transaction_senders['M']['public_key'])
|
||||
chat.chat_message_input.click()
|
||||
chat.paste_text()
|
||||
input_text = chat.chat_message_input.text
|
||||
@@ -80,7 +80,7 @@ class TestOnboardingOneDeviceMerged(MultipleSharedDeviceTestCase):
|
||||
wallet.share_via_messenger()
|
||||
if not wallet.element_by_text_part(address).is_element_present():
|
||||
self.errors.append("Can't share address")
|
||||
wallet.click_system_back_button_until_element_is_shown()
|
||||
wallet.click_system_back_button()
|
||||
|
||||
self.home.just_fyi("Check that can paste wallet address in chat message input")
|
||||
wallet.home_button.click()
|
||||
|
||||
@@ -96,7 +96,7 @@ class TestDeeplinkChatProfileOneDevice(MultipleSharedDeviceTestCase):
|
||||
'https://join.status.im/u/%s' % dummy_user["public_key"]).is_element_present():
|
||||
self.errors.append("Can't share public key of contact")
|
||||
for _ in range(2):
|
||||
chat.click_system_back_button_until_element_is_shown()
|
||||
chat.click_system_back_button()
|
||||
|
||||
@marks.testrail_id(702252)
|
||||
def test_share_user_profile_url_public_chat(self):
|
||||
@@ -112,7 +112,7 @@ class TestDeeplinkChatProfileOneDevice(MultipleSharedDeviceTestCase):
|
||||
'https://join.status.im/%s' % self.public_chat_name).is_element_present():
|
||||
self.errors.append("Can't share link to public chat")
|
||||
for _ in range(2):
|
||||
self.public_chat.click_system_back_button_until_element_is_shown()
|
||||
self.public_chat.click_system_back_button()
|
||||
self.public_chat.get_back_to_home_view()
|
||||
|
||||
@marks.testrail_id(702251)
|
||||
@@ -131,7 +131,7 @@ class TestDeeplinkChatProfileOneDevice(MultipleSharedDeviceTestCase):
|
||||
browser.element_by_text_part(expeceted_text_2).is_element_present()):
|
||||
self.errors.append("Can't share link to URL")
|
||||
|
||||
browser.click_system_back_button_until_element_is_shown()
|
||||
browser.click_system_back_button(1)
|
||||
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
|
||||
@@ -986,8 +986,6 @@
|
||||
"open": "Open",
|
||||
"open-home": "Open...",
|
||||
"open-dapp": "Open ÐApp",
|
||||
"open-dapp2": "Open dApp",
|
||||
"ens-banner-message": "If you registered a stateofus.eth name you might be eligible to collect $ENS",
|
||||
"open-dapp-store": "Discover ÐApps",
|
||||
"open-nfc-settings": "Open NFC settings",
|
||||
"open-on-block-explorer": "Open on block explorer",
|
||||
|
||||