Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aac90672b0 | ||
|
|
2a1d0d9562 | ||
|
|
cc10044f30 | ||
|
|
cad32158cd | ||
|
|
2033ab8804 | ||
|
|
9eccd0fa3d | ||
|
|
4f397c83f2 | ||
|
|
75aeb336e1 | ||
|
|
720ee3f4ad | ||
|
|
88445791a9 | ||
|
|
4e130a71a5 | ||
|
|
ced0f5e289 | ||
|
|
1721b40b3f | ||
|
|
ec6800216b | ||
|
|
15add24cd7 | ||
|
|
28f790b436 | ||
|
|
9aafe61f5f | ||
|
|
02d45fa06f | ||
|
|
99dc79842d | ||
|
|
2a8e6cb304 | ||
|
|
eb3de978ce | ||
|
|
e672bf9163 | ||
|
|
e33c877989 | ||
|
|
c5a486622d | ||
|
|
00f39225ea | ||
|
|
0ac6817488 | ||
|
|
33d41dc5d5 | ||
|
|
76eea91ba2 | ||
|
|
1b2ad33926 | ||
|
|
9731e7039c | ||
|
|
b14757b120 | ||
|
|
2317e856bf | ||
|
|
32f18c3d3c | ||
|
|
e99f6de434 | ||
|
|
bb3b3061c6 | ||
|
|
0067468d57 | ||
|
|
b2cbed444c | ||
|
|
1d0186a12e |
@@ -22,7 +22,6 @@ KEYCARD_TEST_MENU=0
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
ENABLE_QUO_PREVIEW=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -21,7 +21,6 @@ COMMANDS_ENABLED=1
|
||||
KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
|
||||
@@ -26,7 +26,6 @@ VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
TEST_STATEOFUS=1
|
||||
BLANK_PREVIEW=0
|
||||
MAX_IMAGES_BATCH=5
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
COMMUNITIES_ENABLED=1
|
||||
COMMUNITIES_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -17,7 +17,6 @@ RPC_NETWORKS_ONLY=0
|
||||
PARTITIONED_TOPIC=0
|
||||
CONTRACT_NODES=1
|
||||
ENABLE_ROOT_ALERT=1
|
||||
MAX_IMAGES_BATCH=5
|
||||
BLANK_PREVIEW=0
|
||||
COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Bug Report
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: E:MobileBugfixesMVP
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -22,8 +22,7 @@ assignees: ''
|
||||
|
||||
### Reproduction
|
||||
|
||||
1) Open Status
|
||||
2)
|
||||
1.
|
||||
|
||||
### Additional Information
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: Wont fix Report
|
||||
about: to facilitate future handling, identify and address non-urgent issues that won't be prioritized in the near future
|
||||
title: ''
|
||||
labels: likely_wont_fix
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
|
||||
#### Expected behavior
|
||||
|
||||
|
||||
#### Actual behavior
|
||||
|
||||
|
||||
### Reproduction
|
||||
|
||||
1.
|
||||
|
||||
### Additional Information
|
||||
|
||||
- Status version: release
|
||||
- Operating System: Android, iOS
|
||||
|
||||
|
||||
[comment]: # (Please, add logs/notes if necessary)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{:host "localhost" :port 59423}
|
||||
+2
-2
@@ -626,10 +626,10 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void loginWithKeycard(final String accountData, final String password, final String chatKey) {
|
||||
public void loginWithKeycard(final String accountData, final String password, final String chatKey, final String nodeConfigJSON) {
|
||||
Log.d(TAG, "loginWithKeycard");
|
||||
this.migrateKeyStoreDir(accountData, password);
|
||||
String result = Statusgo.loginWithKeycard(accountData, password, chatKey);
|
||||
String result = Statusgo.loginWithKeycard(accountData, password, chatKey, nodeConfigJSON);
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "LoginWithKeycard result: " + result);
|
||||
} else {
|
||||
|
||||
@@ -633,14 +633,15 @@ RCT_EXPORT_METHOD(loginAccount:(NSString *)request) {
|
||||
|
||||
RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
|
||||
password:(NSString *)password
|
||||
chatKey:(NSString *)chatKey) {
|
||||
chatKey:(NSString *)chatKey
|
||||
nodeConfigJSON:(NSString *)nodeConfigJSON) {
|
||||
#if DEBUG
|
||||
NSLog(@"LoginWithKeycard() method called");
|
||||
#endif
|
||||
[self getExportDbFilePath];
|
||||
[self migrateKeystore:accountData password:password];
|
||||
|
||||
NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey);
|
||||
NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey, nodeConfigJSON);
|
||||
|
||||
NSLog(@"%@", result);
|
||||
}
|
||||
|
||||
@@ -1041,7 +1041,7 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
|
||||
if (args.Length() != 3) {
|
||||
if (args.Length() != 4) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for LoginWithKeycard")));
|
||||
@@ -1065,6 +1065,11 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'keyHex'")));
|
||||
return;
|
||||
}
|
||||
if (!args[3]->IsString()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'nodeConfigJSON'")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
|
||||
@@ -1073,9 +1078,11 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
|
||||
char *arg1 = *arg1Obj;
|
||||
String::Utf8Value arg2Obj(isolate, args[2]->ToString(context).ToLocalChecked());
|
||||
char *arg2 = *arg2Obj;
|
||||
String::Utf8Value arg3Obj(isolate, args[3]->ToString(context).ToLocalChecked());
|
||||
char *arg3 = *arg3Obj;
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = LoginWithKeycard(arg0, arg1, arg2);
|
||||
char *c = LoginWithKeycard(arg0, arg1, arg2, arg3);
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -225,12 +225,12 @@
|
||||
(.verifyDatabasePassword ^js (status) key-uid hashed-password callback))
|
||||
|
||||
(defn login-with-keycard
|
||||
[{:keys [key-uid multiaccount-data password chat-key]}]
|
||||
[{:keys [key-uid multiaccount-data password chat-key node-config]}]
|
||||
(log/debug "[native-module] login-with-keycard")
|
||||
(clear-web-data)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.loginWithKeycard ^js (status) multiaccount-data password chat-key)))
|
||||
#(.loginWithKeycard ^js (status) multiaccount-data password chat-key (types/clj->json node-config))))
|
||||
|
||||
(defn set-soft-input-mode
|
||||
[mode]
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
:border-radius dimensions}))
|
||||
|
||||
(defn initials-avatar
|
||||
[size draw-ring? customization-color]
|
||||
[size draw-ring? customization-color theme]
|
||||
(let [outer-dimensions (get-in sizes [size :outer])
|
||||
inner-dimensions (get-in sizes [size (if draw-ring? :inner :outer)])]
|
||||
{:position :absolute
|
||||
@@ -52,7 +52,7 @@
|
||||
:border-radius inner-dimensions
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60)}))
|
||||
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)}))
|
||||
|
||||
(def initials-avatar-text
|
||||
{:color colors/white-opa-70})
|
||||
@@ -67,7 +67,7 @@
|
||||
:background-color background}))
|
||||
|
||||
(defn dot
|
||||
[size ring?]
|
||||
[size ring? theme]
|
||||
(let [dimensions (get-in sizes [size :status-indicator])
|
||||
border-width (get-in sizes [size :status-indicator-border])
|
||||
right (case size
|
||||
@@ -89,5 +89,5 @@
|
||||
:height dimensions
|
||||
:border-width border-width
|
||||
:border-radius dimensions
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100)
|
||||
:border-color (colors/theme-colors colors/white colors/neutral-100)}))
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:border-color (colors/theme-colors colors/white colors/neutral-100 theme)}))
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
(ns quo2.components.avatars.user-avatar.view
|
||||
(:require [quo2.components.avatars.user-avatar.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
utils.string))
|
||||
|
||||
(defn initials-avatar
|
||||
[{:keys [full-name size draw-ring? customization-color]}]
|
||||
[{:keys [full-name size draw-ring? customization-color theme]}]
|
||||
(let [font-size (get-in style/sizes [size :font-size])
|
||||
amount-initials (if (#{:xs :xxs :xxxs} size) 1 2)]
|
||||
[rn/view
|
||||
{:accessibility-label :initials-avatar
|
||||
:style (style/initials-avatar size draw-ring? customization-color)}
|
||||
:style (style/initials-avatar size draw-ring? customization-color theme)}
|
||||
[text/text
|
||||
{:style style/initials-avatar-text
|
||||
:size font-size
|
||||
@@ -20,12 +21,12 @@
|
||||
|
||||
(def valid-ring-sizes #{:big :medium :small})
|
||||
|
||||
(defn user-avatar
|
||||
(defn- user-avatar-internal
|
||||
"If no `profile-picture` is given, draws the initials based on the `full-name` and
|
||||
uses `ring-background` to display the ring behind the initials when given. Otherwise,
|
||||
shows the `profile-picture` which already comes with the ring drawn."
|
||||
[{:keys [full-name status-indicator? online? size profile-picture ring-background
|
||||
customization-color static? muted?]
|
||||
customization-color static? muted? theme]
|
||||
:or {status-indicator? true
|
||||
online? true
|
||||
size :big
|
||||
@@ -49,11 +50,14 @@
|
||||
{:full-name full-name
|
||||
:size size
|
||||
:draw-ring? draw-ring?
|
||||
:customization-color customization-color}])
|
||||
:customization-color customization-color
|
||||
:theme theme}])
|
||||
(when status-indicator?
|
||||
[rn/view
|
||||
{:accessibility-label :status-indicator
|
||||
:style (style/dot size draw-ring?)}
|
||||
:style (style/dot size draw-ring? theme)}
|
||||
[rn/view
|
||||
{:accessibility-label :inner-status-indicator-dot
|
||||
:style (style/inner-dot size online?)}]])]))
|
||||
|
||||
(def user-avatar (quo.theme/with-theme user-avatar-internal))
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
(ns quo2.components.browser.browser-input.component-spec
|
||||
(:require [quo2.components.browser.browser-input.view :as browser-input]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Browser input"
|
||||
(h/test "Renders empty in default state"
|
||||
(h/render [browser-input/browser-input
|
||||
{:on-change-text (h/mock-fn)
|
||||
:value ""}])
|
||||
(h/is-truthy (h/get-by-label-text :browser-input)))
|
||||
|
||||
(h/test "On change text is fired"
|
||||
(let [on-change-text (h/mock-fn)]
|
||||
(h/render [browser-input/browser-input
|
||||
{:on-change-text on-change-text
|
||||
:value "mock text"}])
|
||||
(h/fire-event :change-text (h/get-by-label-text :browser-input) "mock-text-new")
|
||||
(h/was-called on-change-text)))
|
||||
|
||||
(h/describe "Input Label"
|
||||
(h/test "Doesn't render label text when input is focused"
|
||||
(h/render [browser-input/browser-input
|
||||
{:auto-focus true}])
|
||||
(h/is-null (h/query-by-label-text :browser-input-label)))
|
||||
|
||||
(h/test "Renders label text when input has a value and input is not focused"
|
||||
(h/render [browser-input/browser-input
|
||||
{:default-value "mock default"}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-label)))
|
||||
|
||||
(h/test "Renders site favicon when specified"
|
||||
(h/render [browser-input/browser-input
|
||||
{:default-value "mock default" :favicon :i/verified}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-favicon)))
|
||||
|
||||
(h/test "Renders lock icon when lock is enabled"
|
||||
(h/render [browser-input/browser-input
|
||||
{:default-value "mock default" :locked? true}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-locked-icon))))
|
||||
|
||||
(h/describe "Clear button"
|
||||
(h/test "Doesn't render in default state"
|
||||
(h/render [browser-input/browser-input])
|
||||
(h/is-null (h/query-by-label-text :browser-input-clear-button)))
|
||||
|
||||
(h/test "Renders when there is a value"
|
||||
(h/render [browser-input/browser-input
|
||||
{:default-value "mock text"}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-clear-button)))
|
||||
|
||||
(h/test "Is pressable"
|
||||
(let [on-clear (h/mock-fn)]
|
||||
(h/render [browser-input/browser-input
|
||||
{:default-value "mock text"
|
||||
:on-clear on-clear}])
|
||||
(h/is-truthy (h/query-by-label-text :browser-input-clear-button))
|
||||
(h/fire-event :press (h/query-by-label-text :browser-input-clear-button))
|
||||
(h/was-called on-clear)))))
|
||||
@@ -0,0 +1,56 @@
|
||||
(ns quo2.components.browser.browser-input.style
|
||||
(:require [quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(def clear-icon-container
|
||||
{:align-items :center
|
||||
:height 20
|
||||
:justify-content :center
|
||||
:margin-left 8
|
||||
:top 4
|
||||
:width 20})
|
||||
|
||||
(def favicon-icon-container
|
||||
{:margin-right 2})
|
||||
|
||||
(defn input
|
||||
[disabled?]
|
||||
(assoc (text/text-style {:size :paragraph-1
|
||||
:weight :regular})
|
||||
:flex 1
|
||||
:min-height 36
|
||||
:min-width 120
|
||||
:opacity (if disabled? 0.3 1)))
|
||||
|
||||
(def lock-icon-container
|
||||
{:margin-left 2})
|
||||
|
||||
(defn active-container
|
||||
[display?]
|
||||
{:align-items :center
|
||||
:flex-direction :row
|
||||
:justify-content :center
|
||||
:opacity (if display? 1 0)})
|
||||
|
||||
(def default-container
|
||||
{:align-items :center
|
||||
:bottom 0
|
||||
:flex-direction :row
|
||||
:left 0
|
||||
:padding-horizontal 20
|
||||
:position :absolute
|
||||
:right 0
|
||||
:top 0
|
||||
:z-index 10})
|
||||
|
||||
(defn text
|
||||
[]
|
||||
(assoc (text/text-style {:size :paragraph-1
|
||||
:weight :medium})
|
||||
:color
|
||||
(colors/theme-colors colors/neutral-100 colors/white)))
|
||||
|
||||
(def root-container
|
||||
{:height 60
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 8})
|
||||
@@ -0,0 +1,144 @@
|
||||
(ns quo2.components.browser.browser-input.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.components.browser.browser-input.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo2.theme]
|
||||
[clojure.string :as string]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn remove-http-https-www
|
||||
[value]
|
||||
(string/replace value #"(https?://(www\.)?|http://)" ""))
|
||||
|
||||
(defn clear-icon-color
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)))
|
||||
|
||||
(defn lock-icon-color
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn- clear-button
|
||||
[{:keys [on-press blur? theme]}]
|
||||
[rn/touchable-opacity
|
||||
{:accessibility-label :browser-input-clear-button
|
||||
:on-press on-press
|
||||
:style style/clear-icon-container}
|
||||
[icon/icon :i/clear
|
||||
{:color (clear-icon-color blur? theme)}]])
|
||||
|
||||
(defn lock-icon
|
||||
[{:keys [blur? theme]}]
|
||||
[rn/view
|
||||
[icon/icon :i/locked
|
||||
{:accessibility-label :browser-input-locked-icon
|
||||
:color (lock-icon-color blur? theme)
|
||||
:container-style style/lock-icon-container
|
||||
:size 16}]])
|
||||
|
||||
(defn cursor-color
|
||||
[customization-color theme]
|
||||
(colors/theme-colors (colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme))
|
||||
|
||||
(defn placeholder-color
|
||||
[state blur? theme]
|
||||
(cond
|
||||
(and blur? (= state :active))
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
|
||||
blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
|
||||
|
||||
(= state :active)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
|
||||
:else
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(def ^:private props-to-remove
|
||||
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
|
||||
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
|
||||
|
||||
(defn browser-input-internal
|
||||
[{:keys [default-value]
|
||||
:or {default-value ""}}]
|
||||
(let [state (reagent/atom :default)
|
||||
value (reagent/atom default-value)
|
||||
set-active #(reset! state :active)
|
||||
set-default #(reset! state :default)
|
||||
set-value #(reset! value %)
|
||||
ref (atom nil)
|
||||
clear-input (fn []
|
||||
(.clear ^js @ref)
|
||||
(reset! value ""))
|
||||
focus-input (fn []
|
||||
(set-active)
|
||||
(.focus ^js @ref))]
|
||||
(fn [{:keys [disabled? blur? on-change-text customization-color
|
||||
on-clear on-focus on-blur theme get-ref locked?
|
||||
favicon favicon-color favicon-size]
|
||||
:as props}]
|
||||
(let [clean-props (apply dissoc props props-to-remove)]
|
||||
[rn/view {:style style/root-container}
|
||||
(when (and (seq @value) (= @state :default))
|
||||
[rn/touchable-opacity
|
||||
{:style style/default-container
|
||||
:on-press focus-input}
|
||||
(when favicon
|
||||
[icon/icon favicon
|
||||
{:accessibility-label :browser-input-favicon
|
||||
:color favicon-color
|
||||
:container-style style/favicon-icon-container
|
||||
:size favicon-size}])
|
||||
[rn/text
|
||||
{:accessibility-label :browser-input-label
|
||||
:style (style/text)} (remove-http-https-www @value)]
|
||||
(when locked?
|
||||
[lock-icon
|
||||
{:blur? blur?
|
||||
:theme theme}])])
|
||||
[rn/view {:style (style/active-container (or (empty? @value) (= @state :active)))}
|
||||
[rn/text-input
|
||||
(merge
|
||||
clean-props
|
||||
{:accessibility-label :browser-input
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:cursor-color (cursor-color customization-color theme)
|
||||
:editable (not disabled?)
|
||||
:keyboard-appearance (colors/theme-colors :light :dark theme)
|
||||
:keyboard-type :web-search
|
||||
:on-blur (fn []
|
||||
(set-default)
|
||||
(when on-blur (on-blur)))
|
||||
:on-change-text (fn [new-text]
|
||||
(set-value new-text)
|
||||
(when on-change-text (on-change-text new-text)))
|
||||
:on-focus (fn []
|
||||
(set-active)
|
||||
(when on-focus (on-focus)))
|
||||
:placeholder-text-color (placeholder-color @state blur? theme)
|
||||
:ref (fn [r]
|
||||
(reset! ref r)
|
||||
(when get-ref (get-ref r)))
|
||||
:selection-color (when platform/ios?
|
||||
(cursor-color customization-color theme))
|
||||
:select-text-on-focus true
|
||||
:style (style/input disabled?)})]
|
||||
(when (seq @value)
|
||||
[clear-button
|
||||
{:blur? blur?
|
||||
:on-press (fn []
|
||||
(clear-input)
|
||||
(when on-clear (on-clear)))
|
||||
:theme theme}])]]))))
|
||||
|
||||
(def browser-input (quo2.theme/with-theme browser-input-internal))
|
||||
@@ -0,0 +1,103 @@
|
||||
(ns quo2.components.buttons.button.properties
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn custom-color-type
|
||||
[customization-color icon-only?]
|
||||
{:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color (colors/custom-color customization-color 50)
|
||||
:border-radius (when icon-only? 24)})
|
||||
|
||||
(defn grey-photo
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-background-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:blur-overlay-color (if pressed?
|
||||
(colors/theme-colors colors/white-opa-50
|
||||
colors/neutral-80-opa-50
|
||||
theme)
|
||||
(colors/theme-colors colors/white-opa-40
|
||||
colors/neutral-80-opa-40
|
||||
theme))
|
||||
:blur-type (if (= theme :light) :light :dark)})
|
||||
|
||||
(defn grey-blur
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))})
|
||||
|
||||
(defn outline-blur
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))})
|
||||
|
||||
(defn grey
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn dark-grey
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-90 theme))})
|
||||
|
||||
(defn outline
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if pressed?
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
|
||||
|
||||
(defn ghost
|
||||
[theme pressed?]
|
||||
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:background-color (when pressed?
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn black
|
||||
[pressed?]
|
||||
{:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color (if pressed? colors/neutral-80 colors/neutral-95)})
|
||||
|
||||
(defn get-values
|
||||
[{:keys [customization-color theme type background pressed? icon-only?]}]
|
||||
(cond
|
||||
(= type :primary) (custom-color-type customization-color icon-only?)
|
||||
(= type :positive) (custom-color-type customization-color icon-only?)
|
||||
(= type :danger) (custom-color-type customization-color icon-only?)
|
||||
;; TODO Remove type blurred - https://github.com/status-im/status-mobile/issues/16535
|
||||
(and (= :photo background) (= type :grey)) (grey-photo theme pressed?)
|
||||
;; TODO Remove type blur-bg - https://github.com/status-im/status-mobile/issues/16535
|
||||
(or (= type :blur-bg)
|
||||
(and (= :blur background) (= type :grey))) (grey-blur theme pressed?)
|
||||
(and (= :blur background) (= type :outline)) (outline-blur theme pressed?)
|
||||
(= type :grey) (grey theme pressed?)
|
||||
(= type :dark-grey) (dark-grey theme pressed?)
|
||||
(= type :outline) (outline theme pressed?)
|
||||
(= type :ghost) (ghost theme pressed?)
|
||||
;; TODO: remove type shell - https://github.com/status-im/status-mobile/issues/16535
|
||||
(or (= type :shell) (= type :black)) (black pressed?)))
|
||||
@@ -1,5 +1,4 @@
|
||||
(ns quo2.components.buttons.button.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
(ns quo2.components.buttons.button.style)
|
||||
|
||||
(def blur-view
|
||||
{:position :absolute
|
||||
@@ -8,254 +7,97 @@
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(defn before-icon-style
|
||||
(defn icon-style
|
||||
[{:keys [icon-container-size icon-background-color icon-container-rounded?
|
||||
icon-size margin-left margin-right]}]
|
||||
(cond-> (merge {:margin-left margin-left
|
||||
:margin-right margin-right
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
icon-container-size
|
||||
(assoc :width icon-container-size :height icon-container-size)
|
||||
icon-background-color
|
||||
(assoc :background-color icon-background-color)
|
||||
icon-container-rounded?
|
||||
(assoc :border-radius (/ (or icon-container-size icon-size) 2))))
|
||||
|
||||
(defn icon-left-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
icon-size]}]
|
||||
(merge
|
||||
{:margin-left (or (get override-margins :left)
|
||||
(if (= size 40) 12 8))
|
||||
:margin-right (or (get override-margins :right) 4)
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when icon-container-size
|
||||
{:width icon-container-size
|
||||
:height icon-container-size})
|
||||
(when icon-background-color
|
||||
{:background-color icon-background-color})
|
||||
(when icon-container-rounded?
|
||||
{:border-radius (/ (or icon-container-size icon-size) 2)})))
|
||||
(icon-style
|
||||
{:margin-left (or (get override-margins :left)
|
||||
(if (= size 40) 12 8))
|
||||
:margin-right (or (get override-margins :right) 4)
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size}))
|
||||
|
||||
(defn after-icon-style
|
||||
(defn icon-right-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
icon-size]}]
|
||||
(merge
|
||||
{:margin-left (or (get override-margins :left) 4)
|
||||
:margin-right (or (get override-margins :right)
|
||||
(if (= size 40) 12 8))
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when icon-container-size
|
||||
{:width icon-container-size
|
||||
:height icon-container-size})
|
||||
(when icon-background-color
|
||||
{:background-color icon-background-color})
|
||||
(when icon-container-rounded?
|
||||
{:border-radius (/ (or icon-container-size icon-size) 2)})))
|
||||
|
||||
(defn themes
|
||||
[customization-color]
|
||||
{:light
|
||||
{:primary {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default (colors/custom-color customization-color 50)
|
||||
:pressed (colors/custom-color customization-color 60)
|
||||
:disabled (colors/custom-color customization-color 50)}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-40
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-20
|
||||
:disabled colors/neutral-10}}
|
||||
:dark-grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-30
|
||||
:disabled colors/neutral-20}}
|
||||
:outline {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-30
|
||||
:pressed colors/neutral-40
|
||||
:disabled colors/neutral-30}}
|
||||
:ghost {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:pressed colors/neutral-10}}
|
||||
:danger {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-50
|
||||
:pressed colors/danger-60
|
||||
:disabled colors/danger-50}}
|
||||
:positive {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-50
|
||||
:pressed colors/success-60
|
||||
:disabled colors/success-50-opa-30}}
|
||||
:photo-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/white-opa-40
|
||||
:pressed colors/white-opa-50
|
||||
:disabled colors/white-opa-40}}
|
||||
:blur-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-80-opa-5
|
||||
:pressed colors/neutral-80-opa-10
|
||||
:disabled colors/neutral-80-opa-5}}
|
||||
:blurred {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-100
|
||||
:icon-background-color {:default colors/neutral-20
|
||||
:blurred colors/neutral-80-opa-10}
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-10
|
||||
:disabled colors/neutral-10-opa-10-blur}
|
||||
:blur-overlay-color colors/neutral-10-opa-40-blur
|
||||
:blur-type :light}
|
||||
:blur-bg-outline {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-80-opa-10
|
||||
:pressed colors/neutral-80-opa-20
|
||||
:disabled colors/neutral-80-opa-10}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-95
|
||||
:pressed colors/neutral-95
|
||||
:disabled colors/neutral-95}}}
|
||||
:dark
|
||||
{:primary {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default (colors/custom-color customization-color 60)
|
||||
:pressed (colors/custom-color customization-color 50)
|
||||
:disabled (colors/custom-color customization-color 60)}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-30
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-90
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-90}}
|
||||
:dark-grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:outline {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:ghost {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:pressed colors/neutral-80}}
|
||||
:danger {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-60
|
||||
:pressed colors/danger-50
|
||||
:disabled colors/danger-60}}
|
||||
:positive {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-60
|
||||
:pressed colors/success-50
|
||||
:disabled colors/success-60-opa-30}}
|
||||
:photo-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-30
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-80-opa-40
|
||||
:pressed colors/neutral-80-opa-50
|
||||
:disabled colors/neutral-80-opa-40}}
|
||||
:blur-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/white-opa-5
|
||||
:pressed colors/white-opa-10
|
||||
:disabled colors/white-opa-5}}
|
||||
:blurred {:icon-color colors/white
|
||||
:icon-secondary-color colors/white
|
||||
:icon-background-color {:default colors/neutral-80
|
||||
:blurred colors/white-opa-10}
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-90
|
||||
:pressed colors/neutral-90
|
||||
:disabled colors/neutral-90-opa-10-blur}
|
||||
:blur-overlay-color colors/neutral-80-opa-40
|
||||
:blur-type :dark}
|
||||
:blur-bg-outline {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/white-opa-10
|
||||
:pressed colors/white-opa-20
|
||||
:disabled colors/white-opa-5}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-95}}}})
|
||||
(icon-style {:margin-left (or (get override-margins :left) 4)
|
||||
:margin-right (or (get override-margins :right)
|
||||
(if (= size 40) 12 8))
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size}))
|
||||
|
||||
(defn shape-style-container
|
||||
[type icon size]
|
||||
[size border-radius]
|
||||
{:height size
|
||||
:border-radius (if (and icon (#{:primary :secondary :danger} type))
|
||||
24
|
||||
:border-radius (if border-radius
|
||||
border-radius
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8))})
|
||||
8))})
|
||||
|
||||
(defn style-container
|
||||
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
|
||||
[{:keys [size disabled border-radius background-color border-color icon-only? icon-above width
|
||||
icon-left icon-right]}]
|
||||
(merge {:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if above :column :row)
|
||||
:padding-horizontal (when-not (or icon before after)
|
||||
:flex-direction (if icon-above :column :row)
|
||||
:padding-horizontal (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 16
|
||||
40 16
|
||||
32 12
|
||||
24 8))
|
||||
:padding-left (when-not (or icon before)
|
||||
8))
|
||||
:padding-left (when-not (or icon-only? icon-left)
|
||||
(case size
|
||||
56 16
|
||||
40 16
|
||||
32 12
|
||||
24 8))
|
||||
:padding-right (when-not (or icon after)
|
||||
8))
|
||||
:padding-right (when-not (or icon-only? icon-right)
|
||||
(case size
|
||||
56 16
|
||||
40 16
|
||||
32 12
|
||||
24 8))
|
||||
:padding-top (when-not (or icon before after)
|
||||
8))
|
||||
:padding-top (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
24 3))
|
||||
:padding-bottom (when-not (or icon before after)
|
||||
3))
|
||||
:padding-bottom (when-not (or icon-only? icon-left icon-right)
|
||||
(case size
|
||||
56 0
|
||||
40 9
|
||||
32 5
|
||||
24 4))
|
||||
:overflow :hidden}
|
||||
(when (or (and (= type :blurred) (not blur-active?))
|
||||
(not= type :blurred))
|
||||
{:background-color background-color})
|
||||
(shape-style-container type icon size)
|
||||
4))
|
||||
:overflow :hidden
|
||||
:background-color background-color}
|
||||
(shape-style-container size border-radius)
|
||||
(when width
|
||||
{:width width})
|
||||
(when icon
|
||||
(when icon-only?
|
||||
{:width size})
|
||||
(when border-color
|
||||
{:border-color border-color
|
||||
|
||||
@@ -5,110 +5,116 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.blur :as blur]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.components.buttons.button.style :as style]))
|
||||
[quo2.components.buttons.button.style :as style]
|
||||
[quo2.components.buttons.button.properties :as button-properties]
|
||||
[quo2.foundations.customization-colors :as customization-colors]))
|
||||
|
||||
(defn- button-internal
|
||||
"with label
|
||||
[button opts \"label\"]
|
||||
opts
|
||||
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
|
||||
:size 40 [default] /32/24
|
||||
{on-press callback
|
||||
on-long-press callback
|
||||
disabled boolean
|
||||
:type :primary/:positive:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:black (TODO remove :photo-bg/:blur-bg/:blur-bg-outline/:shell/:community)
|
||||
background :photo/:blur or nil
|
||||
:size 40 [default] /32/24/56
|
||||
:icon true/false
|
||||
:community-color '#FFFFFF'
|
||||
:community-text-color '#000000'
|
||||
:above :icon-keyword
|
||||
:before :icon-keyword
|
||||
:after :icon-keyword}
|
||||
|
||||
:customization-color keyword or hexstring
|
||||
:theme :light/:dark
|
||||
only icon
|
||||
[button {:icon true} :i/close-circle]"
|
||||
[_ _]
|
||||
(let [pressed-in (reagent/atom false)]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press disabled type size before after above icon-secondary-no-color
|
||||
width customization-color theme override-background-color pressed
|
||||
on-long-press accessibility-label icon icon-no-color style inner-style test-ID
|
||||
blur-active? override-before-margins override-after-margins icon-size icon-container-size
|
||||
icon-container-rounded?]
|
||||
[{:keys [on-press on-long-press disabled type background size before after above
|
||||
width customization-color theme override-background-color
|
||||
accessibility-label icon style inner-style]
|
||||
:or {type :primary
|
||||
size 40
|
||||
customization-color :primary
|
||||
blur-active? true}}
|
||||
customization-color (cond (= type :primary) :blue
|
||||
(= type :positive) :success
|
||||
(= type :danger) :danger
|
||||
:else nil)}}
|
||||
children]
|
||||
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
|
||||
blur-overlay-color icon-background-color]}
|
||||
(get-in (style/themes customization-color)
|
||||
[theme type])
|
||||
state (cond disabled :disabled
|
||||
(or @pressed-in pressed) :pressed
|
||||
:else :default)
|
||||
blur-state (if blur-active? :blurred :default)
|
||||
icon-size (or icon-size (when (= 24 size) 12))
|
||||
(let [icon-only? icon ;; TODO Update external api to icon-only? -
|
||||
;; https://github.com/status-im/status-mobile/issues/16535
|
||||
container-style style ;; TODO Update external api to container-style and remove prop width
|
||||
icon-left before ;; TODO Update external api to icon-left
|
||||
icon-right after ;; TODO Update external api to icon-right
|
||||
icon-above above ;; TODO Update external api to icon-above
|
||||
{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
|
||||
blur-overlay-color icon-background-color border-radius]}
|
||||
(button-properties/get-values {:customization-color customization-color
|
||||
:background background
|
||||
:type type
|
||||
:theme theme
|
||||
:pressed? @pressed?
|
||||
:icon-only? icon-only?})
|
||||
icon-size (when (= 24 size) 12)
|
||||
icon-secondary-color (or icon-secondary-color icon-color)]
|
||||
[rn/touchable-without-feedback
|
||||
(merge {:test-ID test-ID
|
||||
:disabled disabled
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in #(reset! pressed-in true)
|
||||
:on-press-out #(reset! pressed-in nil)}
|
||||
(when on-press
|
||||
{:on-press on-press})
|
||||
(when on-long-press
|
||||
{:on-long-press on-long-press}))
|
||||
{:disabled disabled
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? nil)
|
||||
:on-press on-press
|
||||
:on-long-press on-long-press}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/shape-style-container type icon size)
|
||||
(style/shape-style-container size border-radius)
|
||||
{:width width}
|
||||
style)}
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/style-container {:type type
|
||||
:size size
|
||||
(style/style-container {:size size
|
||||
:disabled disabled
|
||||
:border-radius border-radius
|
||||
:background-color
|
||||
(or override-background-color (get background-color state))
|
||||
:border-color
|
||||
(get border-color state)
|
||||
:icon icon
|
||||
:above above
|
||||
(or override-background-color background-color)
|
||||
:border-color border-color
|
||||
:icon-only? icon-only?
|
||||
:icon-above icon-above
|
||||
:width width
|
||||
:before before
|
||||
:after after
|
||||
:blur-active? blur-active?})
|
||||
(when (= state :pressed) {:opacity 0.9})
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right})
|
||||
inner-style)}
|
||||
(when (and (= type :blurred)
|
||||
blur-active?)
|
||||
(when customization-color
|
||||
[customization-colors/overlay
|
||||
{:customization-color customization-color
|
||||
:theme theme
|
||||
:pressed? @pressed?}])
|
||||
(when (= background :photo)
|
||||
[blur/view
|
||||
{:blur-radius 20
|
||||
:blur-type blur-type
|
||||
:overlay-color blur-overlay-color
|
||||
:style style/blur-view}])
|
||||
(when above
|
||||
(when icon-above
|
||||
[rn/view
|
||||
[quo2.icons/icon above
|
||||
[quo2.icons/icon icon-above
|
||||
{:container-style {:margin-bottom 2}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
(when before
|
||||
(when icon-left
|
||||
[rn/view
|
||||
{:style (style/before-icon-style
|
||||
{:override-margins override-before-margins
|
||||
:size size
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color (get icon-background-color blur-state)
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon before
|
||||
{:style (style/icon-left-icon-style
|
||||
{:size size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon icon-left
|
||||
{:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
(or icon icon-no-color)
|
||||
icon-only?
|
||||
[quo2.icons/icon children
|
||||
{:color icon-color
|
||||
:no-color icon-no-color
|
||||
:size icon-size}]
|
||||
{:color icon-color
|
||||
:size icon-size}]
|
||||
|
||||
(string? children)
|
||||
[text/text
|
||||
@@ -116,23 +122,18 @@
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color label-color}}
|
||||
|
||||
children]
|
||||
|
||||
(vector? children)
|
||||
children)]
|
||||
(when after
|
||||
(when icon-right
|
||||
[rn/view
|
||||
{:style (style/after-icon-style
|
||||
{:override-margins override-after-margins
|
||||
:size size
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color (get icon-background-color blur-state)
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon after
|
||||
{:no-color icon-secondary-no-color
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])]]]))))
|
||||
{:style (style/icon-right-icon-style
|
||||
{:size size
|
||||
:icon-background-color icon-background-color
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon icon-right
|
||||
{:color icon-secondary-color
|
||||
:size icon-size}]])]]]))))
|
||||
|
||||
(def button (theme/with-theme button-internal))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[quo2.components.community.style :as style]
|
||||
[quo2.components.counter.counter :as counter]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.community.icon :as community-icon]
|
||||
@@ -21,18 +22,65 @@
|
||||
:resize-mode :center
|
||||
:size 20
|
||||
:color (colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-50)}]
|
||||
colors/neutral-50
|
||||
colors/neutral-40)}]
|
||||
(pos? unread-mentions-count)
|
||||
[counter/counter {:type :default} unread-mentions-count]
|
||||
|
||||
unread-messages?
|
||||
[unread-grey-dot :unviewed-messages-public]))
|
||||
|
||||
(defn communities-membership-list-item
|
||||
(defn communities-list-view-item
|
||||
[props
|
||||
{:keys [name
|
||||
muted?
|
||||
locked?
|
||||
status
|
||||
muted
|
||||
unread-messages?
|
||||
unread-mentions-count
|
||||
community-icon
|
||||
tokens]}]
|
||||
[rn/view
|
||||
{:style (merge (style/community-card 16)
|
||||
{:margin-bottom 12})}
|
||||
[rn/touchable-highlight
|
||||
(merge {:style {:height 56
|
||||
:border-radius 16}}
|
||||
props)
|
||||
[rn/view {:style style/detail-container}
|
||||
[rn/view (style/list-info-container)
|
||||
[community-icon/community-icon
|
||||
{:images community-icon} 32]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:margin-horizontal 12}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:accessibility-label :community-name-text
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:style {:color (when muted
|
||||
(colors/theme-colors
|
||||
colors/neutral-40
|
||||
colors/neutral-60))}}
|
||||
name]
|
||||
[community-view/community-stats-column
|
||||
{:type :list-view}]]
|
||||
(if (= status :gated)
|
||||
[community-view/permission-tag-container
|
||||
{:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view
|
||||
{:muted? muted
|
||||
:unread-mentions-count unread-mentions-count
|
||||
:unread-messages? unread-messages?}])]]]])
|
||||
|
||||
(defn communities-membership-list-item
|
||||
[props
|
||||
bottom-sheet?
|
||||
{:keys [name
|
||||
muted
|
||||
unviewed-messages-count
|
||||
unviewed-mentions-count
|
||||
status
|
||||
@@ -59,17 +107,22 @@
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
:size :paragraph-1
|
||||
:style (when muted
|
||||
{:color (if (theme/dark?)
|
||||
colors/neutral-60
|
||||
colors/neutral-40)})}
|
||||
name]]
|
||||
|
||||
[rn/view
|
||||
{:justify-content :center
|
||||
:margin-right 16}
|
||||
:margin-right (when bottom-sheet?
|
||||
16)}
|
||||
(if (= status :gated)
|
||||
[community-view/permission-tag-container
|
||||
{:locked? locked?
|
||||
:tokens tokens}]
|
||||
[notification-view
|
||||
{:muted? muted?
|
||||
{:muted? muted
|
||||
:unread-mentions-count unviewed-mentions-count
|
||||
:unread-messages? (pos? unviewed-messages-count)}])]]])
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn divider
|
||||
[]
|
||||
[theme]
|
||||
{:border-top-width 1
|
||||
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-90)
|
||||
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)
|
||||
:margin-top 8
|
||||
:margin-bottom 7
|
||||
:align-items :center
|
||||
@@ -45,6 +45,6 @@
|
||||
:width 20})
|
||||
|
||||
(defn right-text
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:margin-right 12})
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
(ns quo2.components.drawers.action-drawers.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.drawers.action-drawers.style :as style]
|
||||
[quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.drawers.action-drawers.style :as style]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- get-icon-color
|
||||
[danger? override-theme]
|
||||
[danger? theme]
|
||||
(if danger?
|
||||
colors/danger-60
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)))
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn- divider
|
||||
[]
|
||||
[theme]
|
||||
[rn/view
|
||||
{:style (style/divider)
|
||||
{:style (style/divider theme)
|
||||
:accessible true
|
||||
:accessibility-label :divider}])
|
||||
|
||||
@@ -24,7 +25,7 @@
|
||||
[rn/view (dissoc props :on-press) child]
|
||||
[rn/touchable-highlight props child]))
|
||||
|
||||
(defn- action
|
||||
(defn- action-internal
|
||||
[{:keys [icon
|
||||
label
|
||||
sub-label
|
||||
@@ -34,65 +35,66 @@
|
||||
disabled?
|
||||
on-press
|
||||
add-divider?
|
||||
override-theme
|
||||
theme
|
||||
accessibility-label
|
||||
icon-color]
|
||||
:as action-props}]
|
||||
(when action-props
|
||||
[:<> {:key label}
|
||||
(when add-divider?
|
||||
[divider])
|
||||
[maybe-pressable disabled?
|
||||
{:accessibility-label accessibility-label
|
||||
:style (style/container sub-label disabled?)
|
||||
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 override-theme)
|
||||
:on-press on-press}
|
||||
[rn/view
|
||||
{:style (style/row-container sub-label)}
|
||||
[rn/view
|
||||
{:accessibility-label :left-icon-for-action
|
||||
:accessible true
|
||||
:style style/left-icon}
|
||||
[icon/icon icon
|
||||
{:color (or icon-color (get-icon-color danger? override-theme))
|
||||
:size 20}]]
|
||||
[rn/view
|
||||
{:style style/text-container}
|
||||
icon-color]}]
|
||||
[:<>
|
||||
(when add-divider?
|
||||
[divider theme])
|
||||
[maybe-pressable disabled?
|
||||
{:accessibility-label accessibility-label
|
||||
:style (style/container sub-label disabled?)
|
||||
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
|
||||
:on-press on-press}
|
||||
[rn/view
|
||||
{:style (style/row-container sub-label)}
|
||||
[rn/view
|
||||
{:accessibility-label :left-icon-for-action
|
||||
:accessible true
|
||||
:style style/left-icon}
|
||||
[icon/icon icon
|
||||
{:color (or icon-color (get-icon-color danger? theme))
|
||||
:size 20}]]
|
||||
[rn/view
|
||||
{:style style/text-container}
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:color
|
||||
(cond
|
||||
danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
:else (colors/theme-colors colors/neutral-100 colors/white theme))}}
|
||||
label]
|
||||
(when sub-label
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style {:color
|
||||
(cond
|
||||
danger? (colors/theme-colors colors/danger-50 colors/danger-60 override-theme)
|
||||
:else (colors/theme-colors colors/neutral-100 colors/white override-theme))}}
|
||||
label]
|
||||
(when sub-label
|
||||
{:size :paragraph-2
|
||||
:style {:color
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
sub-label])]
|
||||
(when (or right-text right-icon)
|
||||
[rn/view {:style style/right-side-container}
|
||||
(when right-text
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style {:color
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)}}
|
||||
sub-label])]
|
||||
(when (or right-text right-icon)
|
||||
[rn/view {:style style/right-side-container}
|
||||
(when right-text
|
||||
[text/text
|
||||
{:accessibility-label :right-text-for-action
|
||||
:size :paragraph-1
|
||||
:style (style/right-text override-theme)}
|
||||
right-text])
|
||||
(when right-icon
|
||||
[rn/view
|
||||
{:style style/right-icon
|
||||
:accessible true
|
||||
:accessibility-label :right-icon-for-action}
|
||||
[icon/icon right-icon
|
||||
{:color (get-icon-color danger? override-theme)
|
||||
:size 20}]])])]]]))
|
||||
{:accessibility-label :right-text-for-action
|
||||
:size :paragraph-1
|
||||
:style (style/right-text theme)}
|
||||
right-text])
|
||||
(when right-icon
|
||||
[rn/view
|
||||
{:style style/right-icon
|
||||
:accessible true
|
||||
:accessibility-label :right-icon-for-action}
|
||||
[icon/icon right-icon
|
||||
{:color (get-icon-color danger? theme)
|
||||
:size 20}]])])]]])
|
||||
|
||||
(def ^:private action (quo.theme/with-theme action-internal))
|
||||
|
||||
(defn action-drawer
|
||||
[sections]
|
||||
[:<>
|
||||
(doall
|
||||
(for [actions sections]
|
||||
(doall
|
||||
(map action actions))))])
|
||||
(let [filtered-actions (filter some? actions)]
|
||||
(doall
|
||||
(map #(with-meta [action %] {:key (:label %)}) filtered-actions)))))])
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
(ns quo2.components.dropdowns.dropdown
|
||||
(:require [quo2.components.buttons.button.view :as button]))
|
||||
(:require [quo2.components.dropdowns.old-button-view :as old-button]))
|
||||
|
||||
(defn dropdown
|
||||
[_ _]
|
||||
(fn [{:keys [on-change selected] :as opts} children]
|
||||
[button/button
|
||||
;TODO: Dropdown needs to be implemented/refactored to be its own component -
|
||||
;https://github.com/status-im/status-mobile/issues/16456
|
||||
[old-button/button
|
||||
(merge
|
||||
opts
|
||||
{:after (if selected :i/chevron-top :i/chevron-down)
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
(ns quo2.components.dropdowns.old-button-style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def blur-view
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(defn before-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
icon-size]}]
|
||||
(merge
|
||||
{:margin-left (or (get override-margins :left)
|
||||
(if (= size 40) 12 8))
|
||||
:margin-right (or (get override-margins :right) 4)
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when icon-container-size
|
||||
{:width icon-container-size
|
||||
:height icon-container-size})
|
||||
(when icon-background-color
|
||||
{:background-color icon-background-color})
|
||||
(when icon-container-rounded?
|
||||
{:border-radius (/ (or icon-container-size icon-size) 2)})))
|
||||
|
||||
(defn after-icon-style
|
||||
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
|
||||
icon-size]}]
|
||||
(merge
|
||||
{:margin-left (or (get override-margins :left) 4)
|
||||
:margin-right (or (get override-margins :right)
|
||||
(if (= size 40) 12 8))
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
(when icon-container-size
|
||||
{:width icon-container-size
|
||||
:height icon-container-size})
|
||||
(when icon-background-color
|
||||
{:background-color icon-background-color})
|
||||
(when icon-container-rounded?
|
||||
{:border-radius (/ (or icon-container-size icon-size) 2)})))
|
||||
|
||||
(defn themes
|
||||
[customization-color]
|
||||
{:light
|
||||
{:primary {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default (colors/custom-color customization-color 50)
|
||||
:pressed (colors/custom-color customization-color 60)
|
||||
:disabled (colors/custom-color customization-color 50)}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-40
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-20
|
||||
:disabled colors/neutral-10}}
|
||||
:dark-grey {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-20
|
||||
:pressed colors/neutral-30
|
||||
:disabled colors/neutral-20}}
|
||||
:outline {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-30
|
||||
:pressed colors/neutral-40
|
||||
:disabled colors/neutral-30}}
|
||||
:ghost {:icon-color colors/neutral-50
|
||||
:icon-secondary-color colors/neutral-50
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:pressed colors/neutral-10}}
|
||||
:danger {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-50
|
||||
:pressed colors/danger-60
|
||||
:disabled colors/danger-50}}
|
||||
:positive {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-50
|
||||
:pressed colors/success-60
|
||||
:disabled colors/success-50-opa-30}}
|
||||
:photo-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/white-opa-40
|
||||
:pressed colors/white-opa-50
|
||||
:disabled colors/white-opa-40}}
|
||||
:blur-bg {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-80-opa-5
|
||||
:pressed colors/neutral-80-opa-10
|
||||
:disabled colors/neutral-80-opa-5}}
|
||||
:blurred {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-100
|
||||
:icon-background-color {:default colors/neutral-20
|
||||
:blurred colors/neutral-80-opa-10}
|
||||
:label-color colors/neutral-100
|
||||
:background-color {:default colors/neutral-10
|
||||
:pressed colors/neutral-10
|
||||
:disabled colors/neutral-10-opa-10-blur}
|
||||
:blur-overlay-color colors/neutral-10-opa-40-blur
|
||||
:blur-type :light}
|
||||
:blur-bg-outline {:icon-color colors/neutral-100
|
||||
:icon-secondary-color colors/neutral-80-opa-40
|
||||
:label-color colors/neutral-100
|
||||
:border-color {:default colors/neutral-80-opa-10
|
||||
:pressed colors/neutral-80-opa-20
|
||||
:disabled colors/neutral-80-opa-10}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-95
|
||||
:pressed colors/neutral-95
|
||||
:disabled colors/neutral-95}}}
|
||||
:dark
|
||||
{:primary {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default (colors/custom-color customization-color 60)
|
||||
:pressed (colors/custom-color customization-color 50)
|
||||
:disabled (colors/custom-color customization-color 60)}}
|
||||
:secondary {:icon-color colors/primary-50
|
||||
:label-color colors/primary-50
|
||||
:background-color {:default colors/primary-50-opa-20
|
||||
:pressed colors/primary-50-opa-30
|
||||
:disabled colors/primary-50-opa-20}}
|
||||
:grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-90
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-90}}
|
||||
:dark-grey {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:outline {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/neutral-70
|
||||
:pressed colors/neutral-60
|
||||
:disabled colors/neutral-70}}
|
||||
:ghost {:icon-color colors/neutral-40
|
||||
:icon-secondary-color colors/neutral-40
|
||||
:label-color colors/white
|
||||
:background-color {:pressed colors/neutral-80}}
|
||||
:danger {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/danger-60
|
||||
:pressed colors/danger-50
|
||||
:disabled colors/danger-60}}
|
||||
:positive {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/success-60
|
||||
:pressed colors/success-50
|
||||
:disabled colors/success-60-opa-30}}
|
||||
:photo-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/neutral-30
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-80-opa-40
|
||||
:pressed colors/neutral-80-opa-50
|
||||
:disabled colors/neutral-80-opa-40}}
|
||||
:blur-bg {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-70
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/white-opa-5
|
||||
:pressed colors/white-opa-10
|
||||
:disabled colors/white-opa-5}}
|
||||
:blurred {:icon-color colors/white
|
||||
:icon-secondary-color colors/white
|
||||
:icon-background-color {:default colors/neutral-80
|
||||
:blurred colors/white-opa-10}
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-90
|
||||
:pressed colors/neutral-90
|
||||
:disabled colors/neutral-90-opa-10-blur}
|
||||
:blur-overlay-color colors/neutral-80-opa-40
|
||||
:blur-type :dark}
|
||||
:blur-bg-outline {:icon-color colors/white
|
||||
:icon-secondary-color colors/white-opa-40
|
||||
:label-color colors/white
|
||||
:border-color {:default colors/white-opa-10
|
||||
:pressed colors/white-opa-20
|
||||
:disabled colors/white-opa-5}}
|
||||
:shell {:icon-color colors/white
|
||||
:label-color colors/white
|
||||
:background-color {:default colors/neutral-95}}}})
|
||||
|
||||
(defn shape-style-container
|
||||
[type icon size]
|
||||
{:height size
|
||||
:border-radius (if (and icon (#{:primary :secondary :danger} type))
|
||||
24
|
||||
(case size
|
||||
56 12
|
||||
40 12
|
||||
32 10
|
||||
24 8))})
|
||||
|
||||
(defn style-container
|
||||
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
|
||||
(merge {:height size
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:flex-direction (if above :column :row)
|
||||
:padding-horizontal (when-not (or icon before after)
|
||||
(case size
|
||||
56 16
|
||||
40 16
|
||||
32 12
|
||||
24 8))
|
||||
: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))
|
||||
:overflow :hidden}
|
||||
(when (or (and (= type :blurred) (not blur-active?))
|
||||
(not= type :blurred))
|
||||
{:background-color background-color})
|
||||
(shape-style-container type icon size)
|
||||
(when width
|
||||
{:width width})
|
||||
(when icon
|
||||
{:width size})
|
||||
(when border-color
|
||||
{:border-color border-color
|
||||
:border-width 1})
|
||||
(when disabled
|
||||
{:opacity 0.3})))
|
||||
@@ -0,0 +1,138 @@
|
||||
(ns quo2.components.dropdowns.old-button-view
|
||||
(:require [quo2.components.icon :as quo2.icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.blur :as blur]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.components.dropdowns.old-button-style :as style]))
|
||||
|
||||
(defn- button-internal
|
||||
"with label
|
||||
[button opts \"label\"]
|
||||
opts
|
||||
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
|
||||
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
|
||||
:size 40 [default] /32/24
|
||||
:icon true/false
|
||||
:community-color '#FFFFFF'
|
||||
:community-text-color '#000000'
|
||||
:before :icon-keyword
|
||||
:after :icon-keyword}
|
||||
|
||||
only icon
|
||||
[button {:icon true} :i/close-circle]"
|
||||
[_ _]
|
||||
(let [pressed-in (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press disabled type size before after above icon-secondary-no-color
|
||||
width customization-color theme override-background-color pressed
|
||||
on-long-press accessibility-label icon icon-no-color style inner-style test-ID
|
||||
blur-active? override-before-margins override-after-margins icon-size icon-container-size
|
||||
icon-container-rounded?]
|
||||
:or {type :primary
|
||||
size 40
|
||||
customization-color :primary
|
||||
blur-active? true}}
|
||||
children]
|
||||
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
|
||||
blur-overlay-color icon-background-color]}
|
||||
(get-in (style/themes customization-color)
|
||||
[theme type])
|
||||
state (cond disabled :disabled
|
||||
(or @pressed-in pressed) :pressed
|
||||
:else :default)
|
||||
blur-state (if blur-active? :blurred :default)
|
||||
icon-size (or icon-size (when (= 24 size) 12))
|
||||
icon-secondary-color (or icon-secondary-color icon-color)]
|
||||
[rn/touchable-without-feedback
|
||||
(merge {:test-ID test-ID
|
||||
:disabled disabled
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in #(reset! pressed-in true)
|
||||
:on-press-out #(reset! pressed-in nil)}
|
||||
(when on-press
|
||||
{:on-press on-press})
|
||||
(when on-long-press
|
||||
{:on-long-press on-long-press}))
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/shape-style-container type icon size)
|
||||
{:width width}
|
||||
style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/style-container {:type type
|
||||
:size size
|
||||
:disabled disabled
|
||||
:background-color
|
||||
(or override-background-color (get background-color state))
|
||||
:border-color
|
||||
(get border-color state)
|
||||
:icon icon
|
||||
:above above
|
||||
:width width
|
||||
:before before
|
||||
:after after
|
||||
:blur-active? blur-active?})
|
||||
(when (= state :pressed) {:opacity 0.9})
|
||||
inner-style)}
|
||||
(when (and (= type :blurred)
|
||||
blur-active?)
|
||||
[blur/view
|
||||
{:blur-radius 20
|
||||
:blur-type blur-type
|
||||
:overlay-color blur-overlay-color
|
||||
:style style/blur-view}])
|
||||
(when above
|
||||
[rn/view
|
||||
[quo2.icons/icon above
|
||||
{:container-style {:margin-bottom 2}
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
(when before
|
||||
[rn/view
|
||||
{:style (style/before-icon-style
|
||||
{:override-margins override-before-margins
|
||||
:size size
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color (get icon-background-color blur-state)
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon before
|
||||
{:color icon-secondary-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
(or icon icon-no-color)
|
||||
[quo2.icons/icon children
|
||||
{:color icon-color
|
||||
:no-color icon-no-color
|
||||
:size icon-size}]
|
||||
|
||||
(string? children)
|
||||
[text/text
|
||||
{:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color label-color}}
|
||||
|
||||
children]
|
||||
|
||||
(vector? children)
|
||||
children)]
|
||||
(when after
|
||||
[rn/view
|
||||
{:style (style/after-icon-style
|
||||
{:override-margins override-after-margins
|
||||
:size size
|
||||
:icon-container-size icon-container-size
|
||||
:icon-background-color (get icon-background-color blur-state)
|
||||
:icon-container-rounded? icon-container-rounded?
|
||||
:icon-size icon-size})}
|
||||
[quo2.icons/icon after
|
||||
{:no-color icon-secondary-no-color
|
||||
:color icon-secondary-color
|
||||
:size icon-size}]])]]]))))
|
||||
|
||||
(def button (theme/with-theme button-internal))
|
||||
@@ -24,7 +24,3 @@
|
||||
{:color colors/white}))
|
||||
|
||||
(def button-container {:margin-top 20})
|
||||
|
||||
(defn upper-button-color
|
||||
[customization-color]
|
||||
(colors/custom-color-by-theme customization-color 50 60))
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
upper-button-on-press :on-press} upper-button]
|
||||
[rn/view {:style styles/button-container}
|
||||
[button/button
|
||||
{:type :primary
|
||||
:size 32
|
||||
:override-background-color (styles/upper-button-color customization-color)
|
||||
:on-press upper-button-on-press}
|
||||
{:type :primary
|
||||
:size 32
|
||||
:customization-color customization-color
|
||||
:on-press upper-button-on-press}
|
||||
upper-button-text]
|
||||
(when-let [{lower-button-text :text
|
||||
lower-button-on-press :on-press} lower-button]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[quo2.components.icons.icons :as icons]
|
||||
[quo2.components.icons.svg :as icons.svg]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- valid-color?
|
||||
@@ -12,11 +13,10 @@
|
||||
(not (string/blank? color)))))
|
||||
|
||||
(defn memo-icon-fn
|
||||
[icon-name
|
||||
{:keys [color color-2 no-color
|
||||
container-style size accessibility-label]
|
||||
[{:keys [color color-2 no-color
|
||||
container-style size accessibility-label theme]
|
||||
:or {accessibility-label :icon}}
|
||||
_]
|
||||
icon-name]
|
||||
(let [size (or size 20)]
|
||||
^{:key icon-name}
|
||||
(if-let [svg-icon (icons.svg/get-icon icon-name size)]
|
||||
@@ -34,15 +34,15 @@
|
||||
(when (not no-color)
|
||||
{:tint-color (if (and (string? color) (not (string/blank? color)))
|
||||
color
|
||||
(colors/theme-colors colors/neutral-100 colors/white))})
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
container-style)
|
||||
:accessibility-label accessibility-label
|
||||
:source (icons/icon-source (str (name icon-name) size))}])))
|
||||
|
||||
(def themed-icon (memoize memo-icon-fn))
|
||||
(def ^:private themed-icon (memoize (quo.theme/with-theme memo-icon-fn)))
|
||||
|
||||
(defn icon
|
||||
([icon-name] (icon icon-name nil))
|
||||
([icon-name params]
|
||||
(themed-icon icon-name params (colors/dark?))))
|
||||
(themed-icon params icon-name)))
|
||||
|
||||
@@ -35,4 +35,5 @@
|
||||
(get-icons 16)
|
||||
(get-icons 20)
|
||||
(get-icons 24)
|
||||
(get-icons 32)))
|
||||
(get-icons 32)
|
||||
(get-icons 48)))
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.inputs.profile-input.style :as style]
|
||||
[quo2.components.inputs.title-input.view :as title-input]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hole-view :as hole-view]))
|
||||
|
||||
@@ -35,16 +34,16 @@
|
||||
:status-indicator? false
|
||||
:size :medium)]]
|
||||
[buttons/button
|
||||
{:accessibility-label :select-profile-picture-button
|
||||
:type :grey
|
||||
:override-background-color (colors/alpha colors/white 0.05)
|
||||
:on-press on-press
|
||||
:icon-size 20
|
||||
:width 24
|
||||
:size 24
|
||||
:icon :i/camera
|
||||
:style style/button
|
||||
:inner-style style/button-inner} :i/camera]]
|
||||
{:accessibility-label :select-profile-picture-button
|
||||
:type :grey
|
||||
:background :blur
|
||||
:on-press on-press
|
||||
:icon-size 20
|
||||
:width 24
|
||||
:size 24
|
||||
:icon :i/camera
|
||||
:style style/button
|
||||
:inner-style style/button-inner} :i/camera]]
|
||||
[rn/view {:style style/input-container}
|
||||
[title-input/title-input
|
||||
(merge title-input-props
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
(defn themes
|
||||
[type]
|
||||
(case type
|
||||
:main {:icon-color (theme-colors colors/neutral-50 colors/neutral-10)
|
||||
:background (theme-colors colors/white colors/neutral-90)
|
||||
:main {:icon-color (theme-colors colors/neutral-50 colors/neutral-40)
|
||||
:background (theme-colors colors/white colors/neutral-95)
|
||||
:text-color (theme-colors colors/neutral-100 colors/white)}
|
||||
:danger {:icon-color (theme-colors colors/danger-50 colors/danger-60)
|
||||
:background (theme-colors colors/white colors/neutral-90)
|
||||
:background (theme-colors colors/white colors/neutral-95)
|
||||
:text-color (theme-colors colors/danger-50 colors/danger-60)}
|
||||
:transparent {:icon-color (theme-colors colors/neutral-50 colors/neutral-10)
|
||||
:text-color (theme-colors colors/neutral-100 colors/white)}))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
(ns quo2.components.markdown.text
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn text-style
|
||||
[{:keys [size align weight style]}]
|
||||
[{:keys [size align weight style theme]}]
|
||||
(merge (case (or weight :regular)
|
||||
:regular typography/font-regular
|
||||
:medium typography/font-medium
|
||||
@@ -25,14 +25,23 @@
|
||||
{:text-align (or align :auto)}
|
||||
(if (:color style)
|
||||
style
|
||||
(assoc style :color (if (= (theme/get-theme) :dark) colors/white colors/neutral-100)))))
|
||||
(assoc style
|
||||
:color
|
||||
(if (= (or theme (quo.theme/get-theme)) :dark) colors/white colors/neutral-100)))))
|
||||
|
||||
(defn- text-view-internal
|
||||
[props & children]
|
||||
(let [style (text-style props)]
|
||||
(into [rn/text
|
||||
(merge {:style style}
|
||||
(dissoc props :style :size :align :weight :color :theme))]
|
||||
children)))
|
||||
|
||||
(def ^:private text-view (quo.theme/with-theme text-view-internal))
|
||||
|
||||
(defn text
|
||||
[]
|
||||
(let [this (reagent/current-component)
|
||||
props (reagent/props this)
|
||||
style (text-style props)]
|
||||
(into [rn/text
|
||||
(merge {:style style}
|
||||
(dissoc props :style :size :align :weight :color))]
|
||||
(reagent/children this))))
|
||||
(let [this (reagent/current-component)
|
||||
props (reagent/props this)
|
||||
children (reagent/children this)]
|
||||
(into [text-view props] children)))
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
(ns quo2.components.notifications.activity-logs-photos.style)
|
||||
|
||||
(def photos-container
|
||||
{:flex 1
|
||||
:height 40
|
||||
:flex-direction :row})
|
||||
|
||||
(defn photo
|
||||
[index]
|
||||
{:width 40
|
||||
:height 40
|
||||
:border-radius 10
|
||||
:margin-left (if (= index 0) 0 8)})
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns quo2.components.notifications.activity-logs-photos.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.notifications.activity-logs-photos.style :as style]))
|
||||
|
||||
(defn view
|
||||
[{:keys [photos]}]
|
||||
[rn/view {:style style/photos-container}
|
||||
(map-indexed
|
||||
(fn [index photo]
|
||||
^{:key index}
|
||||
[rn/image
|
||||
{:source photo
|
||||
:style (style/photo index)}])
|
||||
photos)])
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns quo2.components.notifications.count-down-circle
|
||||
(:require [goog.string :as gstring]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.svg :as svg]
|
||||
[reagent.core :as reagent]))
|
||||
@@ -48,8 +48,8 @@
|
||||
{:color {:dark colors/neutral-80-opa-40
|
||||
:light colors/white-opa-40}})
|
||||
|
||||
(defn circle-timer
|
||||
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time]}]
|
||||
(defn- circle-timer-internal
|
||||
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time theme]}]
|
||||
(let [rotation (or rotation :clockwise)
|
||||
duration (or duration 4)
|
||||
stroke-width (or stroke-width 1)
|
||||
@@ -98,8 +98,10 @@
|
||||
[svg/path
|
||||
{:d path
|
||||
:fill :none
|
||||
:stroke (or color (get-in themes [:color (theme/get-theme)]))
|
||||
:stroke (or color (get-in themes [:color theme]))
|
||||
:stroke-linecap :square
|
||||
:stroke-width stroke-width
|
||||
:stroke-dasharray path-length
|
||||
:stroke-dashoffset (linear-ease @display-time 0 path-length duration)}])]])})))
|
||||
|
||||
(def circle-timer (quo.theme/with-theme circle-timer-internal))
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.shadows :as shadows]))
|
||||
|
||||
(def box-container
|
||||
{:margin-horizontal 12
|
||||
:border-radius 12
|
||||
:overflow :hidden})
|
||||
(defn box-container
|
||||
[theme]
|
||||
(merge (shadows/get 1 theme)
|
||||
{:margin-horizontal 12
|
||||
:border-radius 12
|
||||
:overflow :hidden}))
|
||||
|
||||
(def blur-container
|
||||
{:height "100%"
|
||||
@@ -19,35 +21,33 @@
|
||||
|
||||
(defn content-container
|
||||
[theme]
|
||||
(merge
|
||||
(shadows/get 1 theme)
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 8
|
||||
:padding-left 10
|
||||
:padding-right 8
|
||||
:border-radius 12}))
|
||||
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical 8
|
||||
:padding-left 10
|
||||
:padding-right 8
|
||||
:border-radius 12})
|
||||
|
||||
(defn title
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(defn text
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
|
||||
(defn icon
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)
|
||||
:container-style {:width 20 :height 20}})
|
||||
|
||||
(def left-side-container {:padding 2})
|
||||
(def right-side-container {:padding 4 :flex 1})
|
||||
|
||||
(defn action-container
|
||||
[override-theme]
|
||||
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 override-theme)
|
||||
[theme]
|
||||
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 theme)
|
||||
:flex-direction :row
|
||||
:padding-vertical 3
|
||||
:padding-horizontal 8
|
||||
|
||||
@@ -4,33 +4,40 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.notifications.count-down-circle :as count-down-circle]
|
||||
[quo2.components.notifications.toast.style :as style]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn toast-action-container
|
||||
[{:keys [on-press style]} & children]
|
||||
[{:keys [on-press style theme]} & children]
|
||||
[rn/touchable-highlight
|
||||
{:on-press on-press
|
||||
:underlay-color :transparent}
|
||||
[into
|
||||
[rn/view
|
||||
{:style (merge (style/action-container (theme/get-theme)) style)}]
|
||||
{:style (merge (style/action-container theme) style)}]
|
||||
children]])
|
||||
|
||||
(defn toast-undo-action
|
||||
[duration on-press override-theme]
|
||||
[toast-action-container {:on-press on-press :accessibility-label :toast-undo-action}
|
||||
(defn toast-undo-action-internal
|
||||
[{:keys [undo-duration undo-on-press theme]}]
|
||||
[toast-action-container
|
||||
{:on-press undo-on-press
|
||||
:accessibility-label :toast-undo-action
|
||||
:theme theme}
|
||||
[rn/view {:style {:margin-right 5}}
|
||||
[count-down-circle/circle-timer {:duration duration}]]
|
||||
[count-down-circle/circle-timer {:duration undo-duration}]]
|
||||
[text/text
|
||||
{:size :paragraph-2 :weight :medium :style (style/text override-theme)}
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text theme)}
|
||||
[i18n/label :t/undo]]])
|
||||
|
||||
(defn- toast-container
|
||||
[{:keys [left title text right container-style override-theme]}]
|
||||
[rn/view {:style (merge style/box-container container-style)}
|
||||
(def ^:private toast-undo-action (quo.theme/with-theme toast-undo-action-internal))
|
||||
|
||||
(defn- toast-container-internal
|
||||
[{:keys [left title text right container-style theme]}]
|
||||
[rn/view {:style (merge (style/box-container theme) container-style)}
|
||||
[blur/view
|
||||
{:style style/blur-container
|
||||
:blur-amount 13
|
||||
@@ -38,7 +45,7 @@
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}]
|
||||
|
||||
[rn/view {:style (style/content-container override-theme)}
|
||||
[rn/view {:style (style/content-container theme)}
|
||||
[rn/view {:style style/left-side-container}
|
||||
left]
|
||||
[rn/view {:style style/right-side-container}
|
||||
@@ -46,34 +53,39 @@
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:style (style/title override-theme)
|
||||
:style (style/title theme)
|
||||
:accessibility-label :toast-title}
|
||||
title])
|
||||
(when text
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text override-theme)
|
||||
:style (style/text theme)
|
||||
:accessibility-label :toast-content}
|
||||
text])]
|
||||
right]])
|
||||
|
||||
(def ^:private toast-container (quo.theme/with-theme toast-container-internal))
|
||||
|
||||
(defn toast
|
||||
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
|
||||
override-theme user]}]
|
||||
[toast-container
|
||||
{:left (cond icon
|
||||
[icon/icon icon
|
||||
(cond-> (style/icon override-theme)
|
||||
icon-color
|
||||
(assoc :color icon-color))]
|
||||
theme user]}]
|
||||
(let [context-theme (or theme (quo.theme/get-theme))]
|
||||
[quo.theme/provider {:theme context-theme}
|
||||
[toast-container
|
||||
{:left (cond icon
|
||||
[icon/icon icon
|
||||
(cond-> (style/icon context-theme)
|
||||
icon-color
|
||||
(assoc :color icon-color))]
|
||||
|
||||
user
|
||||
[user-avatar/user-avatar user])
|
||||
:title title
|
||||
:text text
|
||||
:right (if undo-duration
|
||||
[toast-undo-action undo-duration undo-on-press override-theme]
|
||||
action)
|
||||
:container-style container-style
|
||||
:override-theme override-theme}])
|
||||
user
|
||||
[user-avatar/user-avatar user])
|
||||
:title title
|
||||
:text text
|
||||
:right (if undo-duration
|
||||
[toast-undo-action
|
||||
{:undo-duration undo-duration
|
||||
:undo-on-press undo-on-press}]
|
||||
action)
|
||||
:container-style container-style}]]))
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture profile-picture
|
||||
:override-theme :dark
|
||||
:size :medium
|
||||
:status-indicator? false
|
||||
:customization-color customization-color
|
||||
@@ -66,7 +65,7 @@
|
||||
:size 32
|
||||
:blurred? true
|
||||
:labelled? true
|
||||
:resource :main-icons2/check
|
||||
:resource :i/check
|
||||
:accessibility-label :logged-in-tag
|
||||
:icon-color colors/success-50
|
||||
:override-theme :dark
|
||||
@@ -74,9 +73,9 @@
|
||||
(when show-options-button?
|
||||
[button/button
|
||||
{:size 32
|
||||
:type :blur-bg
|
||||
:type :grey
|
||||
:background :blur
|
||||
:icon true
|
||||
:override-theme :dark
|
||||
:style style/option-button
|
||||
:on-press on-options-press
|
||||
:accessibility-label :profile-card-options}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns quo2.components.settings.category.component-spec
|
||||
(:require [test-helpers.component :as h]
|
||||
[quo2.components.settings.category.view :as category]))
|
||||
|
||||
(h/describe "category tests"
|
||||
(h/test "category label renders"
|
||||
(h/render [category/category
|
||||
{:label "label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "label")))
|
||||
|
||||
(h/test "category item renders"
|
||||
(h/render [category/category
|
||||
{:label "label"
|
||||
:data [{:title "Item 1"
|
||||
:left-icon :i/browser
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "Item 1"))))
|
||||
@@ -0,0 +1,44 @@
|
||||
(ns quo2.components.settings.category.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:left 0
|
||||
:right 0
|
||||
:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 8})
|
||||
|
||||
(defn items
|
||||
[theme blur?]
|
||||
{:margin-top 12
|
||||
:border-radius 16
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))
|
||||
:border-width 1
|
||||
:border-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn separator
|
||||
[theme blur?]
|
||||
{:height 1
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn blur-container
|
||||
[]
|
||||
{:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:top 0
|
||||
:overflow :hidden})
|
||||
|
||||
(defn blur-view
|
||||
[]
|
||||
{:style {:flex 1}
|
||||
:blur-radius 10
|
||||
:blur-type (colors/theme-colors :light :dark)
|
||||
:blur-amount 20})
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns quo2.components.settings.category.view
|
||||
(:require
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.settings.settings-list.view :as settings-list]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[quo2.components.settings.category.style :as style]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- category-internal
|
||||
[{:keys [label data blur? theme]}]
|
||||
[rn/view {:style style/container}
|
||||
(when blur?
|
||||
[rn/view (style/blur-container) [blur/view (style/blur-view)]])
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
label]
|
||||
[rn/flat-list
|
||||
{:data data
|
||||
:style (style/items theme blur?)
|
||||
:render-fn (fn [item] [settings-list/settings-list item])
|
||||
:separator [rn/view {:style (style/separator theme blur?)}]}]])
|
||||
|
||||
(def category (quo.theme/with-theme category-internal))
|
||||
@@ -42,7 +42,14 @@
|
||||
(colors/theme-colors colors/neutral-100 colors/white override-theme))
|
||||
|
||||
(def community-tag
|
||||
{:padding-vertical 2})
|
||||
{:padding-vertical 2
|
||||
:padding-left 2})
|
||||
|
||||
(def community-tag-text-container
|
||||
{:margin-left 4
|
||||
:flex 1
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defn community-tag-text
|
||||
[override-theme]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(ns quo2.components.tags.context-tag.view
|
||||
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.avatars.group-avatar :as group-avatar]
|
||||
(:require [quo2.components.avatars.group-avatar :as group-avatar]
|
||||
[quo2.components.avatars.user-avatar.style :as user-avatar-style]
|
||||
[quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.icon :as icons]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.components.tags.context-tag.style :as style]
|
||||
[quo2.components.avatars.user-avatar.style :as user-avatar-style]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn trim-public-key
|
||||
@@ -40,31 +40,39 @@
|
||||
(trim-public-key public-key)]])
|
||||
|
||||
(defn context-tag
|
||||
[{:keys [text-style blur? no-avatar-placeholder?] :as params} photo name channel-name]
|
||||
(let [text-params {:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (assoc text-style :justify-content :center)}
|
||||
[{:keys [text-style blur? no-avatar-placeholder? text-container-style ellipsize-text?]
|
||||
:as props}
|
||||
photo
|
||||
name
|
||||
channel-name]
|
||||
(let [text-props {:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (assoc text-style :justify-content :center)
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :tail}
|
||||
empty-photo? (nil? photo)
|
||||
avatar-size :xxs
|
||||
avatar-outer-size (get-in user-avatar-style/sizes [avatar-size :outer])]
|
||||
[rn/view {:flex-direction :row}
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
(if (and empty-photo? no-avatar-placeholder?)
|
||||
[rn/view {:style {:width avatar-outer-size}}]
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size avatar-size
|
||||
:status-indicator? false}])
|
||||
[rn/view {:style style/context-tag-text-container}
|
||||
[text/text text-params (str " " name)]
|
||||
(when channel-name
|
||||
[:<>
|
||||
[icons/icon
|
||||
:i/chevron-right
|
||||
{:color (style/context-tag-icon-color blur?)
|
||||
:size 16}]
|
||||
[text/text text-params (str "# " channel-name)]])]]]))
|
||||
[base-tag (update-in props [:style :padding-left] #(or % 3))
|
||||
(if (and empty-photo? no-avatar-placeholder?)
|
||||
[rn/view {:style {:width avatar-outer-size}}]
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size avatar-size
|
||||
:status-indicator? false}])
|
||||
[rn/view {:style (or text-container-style style/context-tag-text-container)}
|
||||
(if ellipsize-text?
|
||||
[rn/view {:style {:flex 1}}
|
||||
[text/text text-props name]]
|
||||
[text/text text-props (str " " name)])
|
||||
(when channel-name
|
||||
[:<>
|
||||
[icons/icon
|
||||
:i/chevron-right
|
||||
{:color (style/context-tag-icon-color blur?)
|
||||
:size 16}]
|
||||
[text/text text-props (str "# " channel-name)]])]]))
|
||||
|
||||
(defn user-avatar-tag
|
||||
[params username photo]
|
||||
@@ -88,8 +96,10 @@
|
||||
(defn community-tag
|
||||
[avatar community-name {:keys [override-theme] :as params}]
|
||||
[context-tag
|
||||
(merge {:style style/community-tag
|
||||
:text-style (style/community-tag-text override-theme)}
|
||||
(merge {:style style/community-tag
|
||||
:text-style (style/community-tag-text override-theme)
|
||||
:text-container-style style/community-tag-text-container
|
||||
:ellipsize-text? true}
|
||||
params)
|
||||
avatar
|
||||
community-name])
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
quo2.components.buttons.dynamic-button
|
||||
quo2.components.buttons.predictive-keyboard.view
|
||||
quo2.components.buttons.slide-button.view
|
||||
quo2.components.browser.browser-input.view
|
||||
quo2.components.code.snippet
|
||||
quo2.components.colors.color-picker.view
|
||||
quo2.components.common.separator.view
|
||||
@@ -62,6 +63,7 @@
|
||||
quo2.components.navigation.floating-shell-button
|
||||
quo2.components.navigation.page-nav
|
||||
quo2.components.notifications.activity-log.view
|
||||
quo2.components.notifications.activity-logs-photos.view
|
||||
quo2.components.notifications.count-down-circle
|
||||
quo2.components.notifications.info-count
|
||||
quo2.components.notifications.notification-dot
|
||||
@@ -82,6 +84,7 @@
|
||||
quo2.components.settings.privacy-option
|
||||
quo2.components.settings.reorder-item.view
|
||||
quo2.components.settings.settings-list.view
|
||||
quo2.components.settings.category.view
|
||||
quo2.components.share.qr-code.view
|
||||
quo2.components.share.share-qr-code.view
|
||||
quo2.components.tabs.account-selector
|
||||
@@ -137,6 +140,9 @@
|
||||
(def predictive-keyboard quo2.components.buttons.predictive-keyboard.view/view)
|
||||
(def slide-button quo2.components.buttons.slide-button.view/view)
|
||||
|
||||
;;;; BROWSER
|
||||
(def browser-input quo2.components.browser.browser-input.view/browser-input)
|
||||
|
||||
;;;; CODE
|
||||
(def snippet quo2.components.code.snippet/snippet)
|
||||
|
||||
@@ -209,6 +215,7 @@
|
||||
|
||||
;;;; NOTIFICATIONS
|
||||
(def activity-log quo2.components.notifications.activity-log.view/view)
|
||||
(def activity-logs-photos quo2.components.notifications.activity-logs-photos.view/view)
|
||||
(def info-count quo2.components.notifications.info-count/info-count)
|
||||
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
|
||||
(def count-down-circle quo2.components.notifications.count-down-circle/circle-timer)
|
||||
@@ -231,6 +238,7 @@
|
||||
(def account quo2.components.settings.accounts.view/account)
|
||||
(def settings-list quo2.components.settings.settings-list.view/settings-list)
|
||||
(def reorder-item quo2.components.settings.reorder-item.view/reorder-item)
|
||||
(def category quo2.components.settings.category.view/category)
|
||||
|
||||
;;;; SHARE
|
||||
(def qr-code quo2.components.share.qr-code.view/qr-code)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[quo2.components.buttons.button.component-spec]
|
||||
[quo2.components.buttons.predictive-keyboard.component-spec]
|
||||
[quo2.components.buttons.slide-button.component-spec]
|
||||
[quo2.components.browser.browser-input.component-spec]
|
||||
[quo2.components.colors.color-picker.component-spec]
|
||||
[quo2.components.counter.--tests--.counter-component-spec]
|
||||
[quo2.components.counter.step.component-spec]
|
||||
@@ -37,5 +38,6 @@
|
||||
[quo2.components.selectors.selectors.component-spec]
|
||||
[quo2.components.settings.reorder-item.component-spec]
|
||||
[quo2.components.settings.settings-list.component-spec]
|
||||
[quo2.components.settings.category.component-spec]
|
||||
[quo2.components.share.share-qr-code.component-spec]
|
||||
[quo2.components.tags.--tests--.status-tags-component-spec]))
|
||||
|
||||
@@ -136,6 +136,8 @@
|
||||
;;Solid
|
||||
(def black "#000000")
|
||||
(def black-opa-0 (alpha black 0))
|
||||
(def black-opa-30 (alpha black 0.3))
|
||||
(def black-opa-60 (alpha black 0.6))
|
||||
(def onboarding-header-black "#000716")
|
||||
|
||||
;;;;Primary
|
||||
@@ -180,6 +182,8 @@
|
||||
(def danger-50 "#E95460")
|
||||
(def danger-60 "#BA434D")
|
||||
|
||||
(def system-yellow "#FFD60A")
|
||||
|
||||
;;50 with transparency
|
||||
(def danger-50-opa-5 (alpha danger-50 0.05))
|
||||
(def danger-50-opa-10 (alpha danger-50 0.1))
|
||||
@@ -244,11 +248,13 @@
|
||||
([color suffix]
|
||||
(custom-color color suffix nil))
|
||||
([color suffix opacity]
|
||||
(let [color-keyword (keyword color)
|
||||
(let [hex? (not (keyword? color))
|
||||
color-keyword (keyword color)
|
||||
base-color (get-in colors-map
|
||||
[color-keyword suffix]
|
||||
color)]
|
||||
(if opacity (alpha base-color (/ opacity 100)) base-color))))))
|
||||
[color-keyword suffix])]
|
||||
(if hex?
|
||||
color
|
||||
(if opacity (alpha base-color (/ opacity 100)) base-color)))))))
|
||||
|
||||
(defn custom-color-by-theme
|
||||
"(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark)
|
||||
@@ -256,11 +262,14 @@
|
||||
suffix-light 50/60
|
||||
suffix-dark 50/60
|
||||
opacity-light 0-100 (optional)
|
||||
opacity-dark 0-100 (optional)"
|
||||
opacity-dark 0-100 (optional)
|
||||
theme :light/:dark (optional)"
|
||||
([color suffix-light suffix-dark]
|
||||
(custom-color-by-theme color suffix-light suffix-dark nil nil))
|
||||
(custom-color-by-theme color suffix-light suffix-dark nil nil (theme/get-theme)))
|
||||
([color suffix-light suffix-dark opacity-light opacity-dark]
|
||||
(if (theme/dark?)
|
||||
(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark (theme/get-theme)))
|
||||
([color suffix-light suffix-dark opacity-light opacity-dark theme]
|
||||
(if (= theme :dark)
|
||||
(custom-color color suffix-dark opacity-dark)
|
||||
(custom-color color suffix-light opacity-light))))
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns quo2.foundations.customization-colors
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn get-overlay-color
|
||||
[theme pressed? customization-color]
|
||||
(let [community-color (string? customization-color)]
|
||||
(if (or community-color (= theme :light))
|
||||
(colors/alpha colors/black (if pressed? 0.2 0))
|
||||
(colors/alpha colors/black (if pressed? 0 0.2)))))
|
||||
|
||||
(defn overlay
|
||||
[{:keys [theme pressed? customization-color]}]
|
||||
[rn/view
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:background-color (get-overlay-color theme pressed? customization-color)}])
|
||||
@@ -1,8 +1,16 @@
|
||||
(ns react-native.camera-kit
|
||||
(:require ["react-native-camera-kit" :refer (Camera CameraType)]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[oops.core :as oops]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def camera (reagent/adapt-react-class Camera))
|
||||
|
||||
(def camera-type-front (.-Front CameraType))
|
||||
(def camera-type-back (.-Back CameraType))
|
||||
|
||||
(defn capture
|
||||
[^js camera-ref on-success]
|
||||
(-> (.capture camera-ref)
|
||||
(.then #(on-success (oops/oget % :uri)))
|
||||
(.catch #(log/warn "couldn't capture photo" {:error %}))))
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[react-native.share :as share]
|
||||
[react-native.cameraroll :as cameraroll]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im2.config :as config]
|
||||
[react-native.fs :as fs]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.utils.platform :as platform]
|
||||
[taoensso.timbre :as log]))
|
||||
@@ -48,7 +48,7 @@
|
||||
[{:keys [db]} chat-id uri]
|
||||
(let [current-chat-id (or chat-id (:current-chat-id db))
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (and (< (count images) config/max-images-batch)
|
||||
(when (and (< (count images) constants/max-album-photos)
|
||||
(not (get images uri)))
|
||||
{::image-selected [uri current-chat-id]})))
|
||||
|
||||
@@ -68,5 +68,5 @@
|
||||
[{:keys [db]} chat-id]
|
||||
(let [current-chat-id (or chat-id (:current-chat-id db))
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (< (count images) config/max-images-batch)
|
||||
(when (< (count images) constants/max-album-photos)
|
||||
{::chat-open-image-picker-camera current-chat-id})))
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
(ns status-im.chat.models.mentions
|
||||
(:require [clojure.set :as set]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[utils.debounce :as debounce]
|
||||
[status-im2.contexts.chat.composer.constants :as constants]))
|
||||
|
||||
(defn- transfer-input-segments
|
||||
[segments]
|
||||
@@ -57,18 +59,22 @@
|
||||
mentionable-users))
|
||||
(defn- transfer-mention-result
|
||||
[result]
|
||||
(let [{:keys [input-segments mentionable-users state chat-id new-text]}
|
||||
(let [{:keys [input-segments mentionable-users state chat-id new-text call-id call-time]}
|
||||
(set/rename-keys result
|
||||
{:InputSegments :input-segments
|
||||
:MentionSuggestions :mentionable-users
|
||||
:MentionState :state
|
||||
:ChatID :chat-id
|
||||
:NewText :new-text})]
|
||||
:NewText :new-text
|
||||
:CallID :call-id
|
||||
:CallTime :call-time})]
|
||||
{:chat-id chat-id
|
||||
:input-segments (transfer-input-segments input-segments)
|
||||
:mentionable-users (rename-mentionable-users mentionable-users)
|
||||
:state (rename-state state)
|
||||
:new-text new-text}))
|
||||
:new-text new-text
|
||||
:call-id call-id
|
||||
:call-time call-time}))
|
||||
|
||||
(rf/defn on-error
|
||||
{:events [:mention/on-error]}
|
||||
@@ -98,11 +104,13 @@
|
||||
(assoc-in [:chats/mentions chat-id :mentions] state)
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
||||
|
||||
(defonce current-call-id (atom 0))
|
||||
|
||||
(rf/defn on-change-text
|
||||
{:events [:mention/on-change-text]}
|
||||
[{:keys [db]} text]
|
||||
(let [chat-id (:current-chat-id db)
|
||||
params [chat-id text]
|
||||
params [chat-id text (swap! current-call-id inc) (js/Date.now)]
|
||||
method "wakuext_chatMentionOnChangeText"]
|
||||
(log/debug "[mentions] on-change-text" {:params params})
|
||||
{:json-rpc/call [{:method method
|
||||
@@ -116,11 +124,31 @@
|
||||
{:events [:mention/on-change-text-success]}
|
||||
[{:keys [db]} result]
|
||||
(log/debug "[mentions] on-change-text-success" {:result result})
|
||||
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
|
||||
{:db (-> db
|
||||
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
|
||||
(assoc-in [:chats/mentions chat-id :mentions] state)
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
||||
(let [{:keys [state chat-id mentionable-users
|
||||
input-segments call-id call-time]} (transfer-mention-result result)]
|
||||
(when (= call-id @current-call-id)
|
||||
(debounce/debounce-and-dispatch [:mention/re-render-text-input
|
||||
{:chat-id chat-id
|
||||
:mentionable-users mentionable-users
|
||||
:state state
|
||||
:input-segments input-segments
|
||||
:call-id call-id
|
||||
:response-time (- (js/Date.now) call-time)}]
|
||||
constants/mention-rerender-debounce-ms)
|
||||
)))
|
||||
|
||||
(rf/defn re-render-text-input
|
||||
{:events [:mention/re-render-text-input]}
|
||||
[{:keys [db]}
|
||||
{:keys [chat-id mentionable-users state input-segments] :as params}]
|
||||
(log/debug "[mentions] re-render-text-input" params)
|
||||
{:db (-> db
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id]
|
||||
input-segments)
|
||||
(assoc-in [:chats/mention-suggestions chat-id]
|
||||
mentionable-users)
|
||||
(assoc-in [:chats/mentions chat-id :mentions]
|
||||
state))})
|
||||
|
||||
(rf/defn on-select-mention-success
|
||||
{:events [:mention/on-select-mention-success]}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[clojure.string :as string]
|
||||
[clojure.walk :as walk]
|
||||
[quo.design-system.colors :as colors]
|
||||
[quo2.foundations.colors :as quo2.colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.async-storage.core :as async-storage]
|
||||
@@ -16,6 +17,7 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.contexts.chat.events :as chat.events]))
|
||||
|
||||
(def crop-size 1000)
|
||||
@@ -72,7 +74,8 @@
|
||||
:isMember :is-member?
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata})
|
||||
:communityTokensMetadata :tokens-metadata
|
||||
:muteTill :muted-till})
|
||||
(update :admin-settings
|
||||
set/rename-keys
|
||||
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
|
||||
@@ -938,3 +941,58 @@
|
||||
{:error %
|
||||
:event
|
||||
:communities/check-and-delete-pending-request-to-join-community})}]})
|
||||
|
||||
(rf/defn mute-community-chats
|
||||
{:events [:community/mute-community-chats]}
|
||||
[{:keys [db]} chat-id muted? muted-till]
|
||||
(log/debug "muted community chat successfully" chat-id muted?)
|
||||
{:db (update-in db [:chats chat-id] merge {:muted muted? :muted-till muted-till})})
|
||||
|
||||
(rf/defn mute-and-unmute-community-chats
|
||||
{:events [:community/update-community-chats-mute-status]}
|
||||
[{:keys [db]} community-id muted? mute-till]
|
||||
(let [channels (get-in db [:communities community-id :chats])
|
||||
chats (mapv vector (keys channels) (vals channels))]
|
||||
(doseq [x chats]
|
||||
(doseq [{:keys [id]} x]
|
||||
(let [chat-id (str community-id id)]
|
||||
(rf/dispatch [:community/mute-community-chats chat-id muted? mute-till]))))))
|
||||
|
||||
(rf/defn mute-chat-failed
|
||||
{:events [:community/mute-community-failed]}
|
||||
[{:keys [db]} community-id muted? error]
|
||||
(log/error "mute community failed" community-id error)
|
||||
{:db (update-in db [:communities community-id :muted] (not muted?))}
|
||||
(rf/dispatch [:community/update-community-chats-mute-status community-id muted? error]))
|
||||
|
||||
(rf/defn mute-community-successfully
|
||||
{:events [:community/mute-community-successful]}
|
||||
[{:keys [db]} community-id muted? muted-till]
|
||||
(log/debug "muted community successfully" community-id muted-till)
|
||||
(rf/dispatch [:community/update-community-chats-mute-status community-id muted? muted-till])
|
||||
(let [time-string (fn [mute-title mute-duration]
|
||||
(i18n/label mute-title {:duration mute-duration}))]
|
||||
{:db (assoc-in db [:communities community-id :muted-till] muted-till)
|
||||
:dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
:icon-color (quo2.colors/theme-colors
|
||||
quo2.colors/success-60
|
||||
quo2.colors/success-50)
|
||||
:text (if muted?
|
||||
(when (some? muted-till)
|
||||
(time-string :t/muted-until (format-mute-till muted-till)))
|
||||
(i18n/label :t/community-unmuted))}]}))
|
||||
|
||||
|
||||
(rf/defn set-community-muted
|
||||
{:events [:community/set-muted]}
|
||||
[{:keys [db]} community-id muted? muted-type]
|
||||
(let [params (if muted? [{:communityId community-id :mutedType muted-type}] [community-id])
|
||||
method (if muted? "wakuext_muteCommunityChats" "wakuext_unMuteCommunityChats")]
|
||||
{:db (assoc-in db [:communities community-id :muted] muted?)
|
||||
:json-rpc/call [{:method method
|
||||
:params params
|
||||
:on-error #(rf/dispatch [:community/mute-community-failed community-id
|
||||
muted? %])
|
||||
:on-success #(rf/dispatch [:community/mute-community-successful
|
||||
community-id muted? %])}]}))
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
|
||||
(defn login
|
||||
[args]
|
||||
(native-module/login-with-keycard args))
|
||||
(native-module/login-with-keycard (assoc args :node-config {:ProcessBackedupMessages false})))
|
||||
|
||||
(defn send-transaction-with-signature
|
||||
[{:keys [transaction signature on-completed]}]
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
(assoc :recovered-account? true))
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
(navigation/navigate-to :keycard-recovery-intro nil)))
|
||||
(navigation/navigate-to-within-stack [:keycard-recovery-intro :new-to-status])))
|
||||
|
||||
(rf/defn access-key-pressed
|
||||
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
|
||||
@@ -253,7 +253,8 @@
|
||||
encryption-pass
|
||||
#(let [{:keys [error]} (types/json->clj %)]
|
||||
(if (string/blank? error)
|
||||
(native-module/login-with-keycard login-params)
|
||||
(native-module/login-with-keycard
|
||||
(assoc login-params :node-config {:ProcessBackedupMessages true}))
|
||||
(throw
|
||||
(js/Error.
|
||||
"Please shake the phone to report this error and restart the app. Migration failed unexpectedly.")))))))
|
||||
|
||||
@@ -39,10 +39,11 @@
|
||||
(contact.db/public-key->new-contact identity)))
|
||||
|
||||
(defn contact-two-names-by-identity
|
||||
[contact current-multiaccount identity]
|
||||
(let [me? (= (:public-key current-multiaccount) identity)]
|
||||
[contact profile identity]
|
||||
(let [me? (= (:public-key profile) identity)]
|
||||
(if me?
|
||||
[(or (:preferred-name current-multiaccount)
|
||||
[(or (:preferred-name profile)
|
||||
(:display-name profile)
|
||||
(:primary-name contact)
|
||||
(gfycat/generate-gfy identity))]
|
||||
[(:primary-name contact) (:secondary-name contact)])))
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn handle
|
||||
[override-theme]
|
||||
[theme]
|
||||
{:width 32
|
||||
:height 4
|
||||
:background-color (colors/theme-colors colors/neutral-100 colors/white override-theme)
|
||||
:opacity (theme/theme-value 0.05 0.1)
|
||||
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:opacity (theme/theme-value 0.05 0.1 theme)
|
||||
:border-radius 100
|
||||
:align-self :center
|
||||
:margin-vertical 8})
|
||||
|
||||
(defn sheet
|
||||
[{:keys [top bottom]} window-height override-theme padding-bottom-override shell?]
|
||||
[{:keys [top bottom]} window-height theme padding-bottom-override shell?]
|
||||
{:position :absolute
|
||||
:max-height (- window-height top)
|
||||
:z-index 1
|
||||
@@ -28,7 +28,7 @@
|
||||
:padding-bottom (or padding-bottom-override (+ bottom 8))
|
||||
:background-color (if shell?
|
||||
:transparent
|
||||
(colors/theme-colors colors/white colors/neutral-90 override-theme))})
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
||||
(def shell-bg
|
||||
{:position :absolute
|
||||
@@ -39,7 +39,7 @@
|
||||
:bottom 0})
|
||||
|
||||
(defn selected-item
|
||||
[override-theme window-height sheet-height {:keys [top]}]
|
||||
[theme window-height sheet-height {:keys [top]}]
|
||||
{:position :absolute
|
||||
:bottom 10
|
||||
:max-height (- window-height sheet-height top)
|
||||
@@ -48,4 +48,4 @@
|
||||
:right 0
|
||||
:border-radius 12
|
||||
:margin-horizontal 8
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90 override-theme)})
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im2.common.bottom-sheet.view
|
||||
(:require [oops.core :as oops]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
@@ -52,11 +53,11 @@
|
||||
(show translate-y bg-opacity)
|
||||
(hide translate-y bg-opacity window-height on-close))))))
|
||||
|
||||
(defn f-view
|
||||
(defn- f-view
|
||||
[_ _]
|
||||
(let [sheet-height (reagent/atom 0)]
|
||||
(fn [{:keys [hide? insets]}
|
||||
{:keys [content override-theme selected-item padding-bottom-override on-close shell?]}]
|
||||
(fn [{:keys [hide? insets theme]}
|
||||
{:keys [content selected-item padding-bottom-override on-close shell?]}]
|
||||
(let [{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value window-height)
|
||||
@@ -85,7 +86,7 @@
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/sheet insets
|
||||
window-height
|
||||
override-theme
|
||||
theme
|
||||
padding-bottom-override
|
||||
shell?))
|
||||
:on-layout #(reset! sheet-height (oops/oget % "nativeEvent" "layout" "height"))}
|
||||
@@ -93,10 +94,16 @@
|
||||
[blur/ios-view {:style style/shell-bg}])
|
||||
(when selected-item
|
||||
[rn/view
|
||||
[rn/view {:style (style/selected-item override-theme window-height @sheet-height insets)}
|
||||
[rn/view {:style (style/selected-item theme window-height @sheet-height insets)}
|
||||
[selected-item]]])
|
||||
|
||||
;; handle
|
||||
[rn/view {:style (style/handle override-theme)}]
|
||||
[rn/view {:style (style/handle theme)}]
|
||||
;; content
|
||||
[content]]]]))))
|
||||
|
||||
(defn- internal-view
|
||||
[args sheet]
|
||||
[:f> f-view args sheet])
|
||||
|
||||
(def view (theme/with-theme internal-view))
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
(ns status-im2.common.device-permissions
|
||||
(:require
|
||||
[quo2.foundations.colors :as colors]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn camera
|
||||
[on-allowed]
|
||||
(rf/dispatch
|
||||
[:request-permissions
|
||||
{:permissions [:camera]
|
||||
:on-allowed on-allowed
|
||||
:on-denied #(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:icon :i/info
|
||||
:icon-color colors/danger-50
|
||||
:theme :dark
|
||||
:text (i18n/label :t/camera-permission-denied)}])}]))
|
||||
@@ -8,8 +8,8 @@
|
||||
[status-im2.contexts.contacts.drawers.nickname-drawer.view :as nickname-drawer]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.mute-chat-drawer.view :as mute-chat-drawer]
|
||||
[utils.datetime :as datetime]))
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]))
|
||||
|
||||
(defn- entry
|
||||
[{:keys [icon label on-press danger? sub-label chevron? add-divider? accessibility-label]}]
|
||||
@@ -53,11 +53,15 @@
|
||||
:accessibility-label :edit-nickname}])}]))
|
||||
|
||||
(defn mute-chat-action
|
||||
[chat-id chat-type]
|
||||
[chat-id chat-type muted?]
|
||||
(hide-sheet-and-dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[mute-chat-drawer/mute-chat-drawer chat-id
|
||||
:mute-chat-for-duration chat-type])}]))
|
||||
[mute-drawer/mute-drawer
|
||||
{:id chat-id
|
||||
:community? false
|
||||
:muted? (not muted?)
|
||||
:chat-type chat-type
|
||||
:accessibility-label :mute-community-title}])}]))
|
||||
|
||||
(defn unmute-chat-action
|
||||
[chat-id]
|
||||
@@ -131,12 +135,10 @@
|
||||
:unmute-chat
|
||||
:mute-chat))
|
||||
:sub-label (when (and muted? (some? muted-till))
|
||||
(str (i18n/label :t/muted-until)
|
||||
" "
|
||||
(datetime/format-mute-till muted-till)))
|
||||
(i18n/label :t/muted-until {:duration (format-mute-till muted-till)}))
|
||||
:on-press (if muted?
|
||||
#(unmute-chat-action chat-id)
|
||||
#(mute-chat-action chat-id chat-type))
|
||||
#(mute-chat-action chat-id chat-type muted?))
|
||||
:danger? false
|
||||
:accessibility-label :mute-chat
|
||||
:chevron? (not muted?)})))
|
||||
@@ -215,7 +217,7 @@
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :remove-nickname
|
||||
:icon :correct
|
||||
:icon :i/correct
|
||||
:icon-color (colors/theme-colors colors/success-60
|
||||
colors/success-50)
|
||||
:text (i18n/label
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
(ns status-im2.common.mute-chat-drawer.view
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.mute-chat-drawer.style :as style]))
|
||||
|
||||
(defn not-community-chat?
|
||||
[chat-type]
|
||||
(contains? #{constants/public-chat-type
|
||||
constants/private-group-chat-type
|
||||
constants/one-to-one-chat-type}
|
||||
chat-type))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch event))
|
||||
|
||||
(defn mute-chat-drawer
|
||||
[chat-id accessibility-label chat-type]
|
||||
[rn/view {:accessibility-label accessibility-label}
|
||||
[quo/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/header-text)}
|
||||
(i18n/label
|
||||
(if (not-community-chat? chat-type)
|
||||
:t/mute-chat-capitialized
|
||||
:t/mute-channel))]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-15-mins)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
|
||||
constants/mute-for-15-mins-type]))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-1-hour)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
|
||||
constants/mute-for-1-hour-type]))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-8-hours)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
|
||||
constants/mute-for-8-hours-type]))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-1-week)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
|
||||
constants/mute-for-1-week]))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-till-unmute)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
|
||||
constants/mute-till-unmuted]))}]])
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
(ns status-im2.common.mute-chat-drawer.style
|
||||
(ns status-im2.common.mute-drawer.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn header-text
|
||||
@@ -0,0 +1,100 @@
|
||||
(ns status-im2.common.mute-drawer.view
|
||||
(:require [utils.i18n :as i18n]
|
||||
[quo2.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.mute-drawer.style :as style]))
|
||||
|
||||
(defn not-community-chat?
|
||||
[chat-type]
|
||||
(contains? #{constants/public-chat-type
|
||||
constants/private-group-chat-type
|
||||
constants/one-to-one-chat-type}
|
||||
chat-type))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[{:keys [id community? muted? muted-type]}]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(if community?
|
||||
(rf/dispatch [:community/set-muted id muted? muted-type])
|
||||
(rf/dispatch [:chat.ui/mute id muted? muted-type])))
|
||||
|
||||
(defn mute-drawer
|
||||
[{:keys [id accessibility-label muted? chat-type community?]}]
|
||||
[rn/view {:accessibility-label accessibility-label}
|
||||
[quo/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/header-text)}
|
||||
(i18n/label
|
||||
(if community?
|
||||
:t/mute-community
|
||||
(if (not-community-chat? chat-type)
|
||||
:t/mute-chat-capitialized
|
||||
:t/mute-channel)))]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-15-mins)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch
|
||||
{:id id
|
||||
:chat-type chat-type
|
||||
:muted? muted?
|
||||
:community? community?
|
||||
:muted-type constants/mute-for-15-mins-type}))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-1-hour)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch
|
||||
{:id id
|
||||
:chat-type chat-type
|
||||
:muted? muted?
|
||||
:community? community?
|
||||
:muted-type constants/mute-for-1-hour-type}))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-8-hours)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch
|
||||
{:id id
|
||||
:chat-type chat-type
|
||||
:muted? muted?
|
||||
:community? community?
|
||||
:muted-type constants/mute-for-8-hours-type}))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-for-1-week)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch
|
||||
{:id id
|
||||
:chat-type chat-type
|
||||
:muted? muted?
|
||||
:community? community?
|
||||
:muted-type constants/mute-for-1-week}))}]
|
||||
[quo/menu-item
|
||||
{:type :transparent
|
||||
:title (i18n/label :t/mute-till-unmute)
|
||||
:icon-bg-color :transparent
|
||||
:container-padding-vertical 12
|
||||
:title-column-style {:margin-left 2}
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-dispatch
|
||||
{:id id
|
||||
:chat-type chat-type
|
||||
:muted? muted?
|
||||
:community? community?
|
||||
:muted-type constants/mute-till-unmuted}))}]])
|
||||
@@ -0,0 +1,39 @@
|
||||
(ns status-im2.common.muting.helpers
|
||||
(:require [cljs-time.core :as t]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.datetime :refer
|
||||
[go-default-time int->weekday months
|
||||
time-zone-offset today? tomorrow?]])
|
||||
(:require [cljs-time.format :as t.format]))
|
||||
|
||||
(defn- add-leading-zero
|
||||
[input-string]
|
||||
(if (> 10 input-string)
|
||||
(str "0" input-string)
|
||||
input-string))
|
||||
|
||||
(defn format-mute-till
|
||||
[muted-till-string]
|
||||
(let [parsed-time (t.format/parse (t.format/formatters :date-time-no-ms) muted-till-string)
|
||||
hours-and-minutes (str (add-leading-zero (t/hour (t/plus parsed-time time-zone-offset)))
|
||||
":"
|
||||
(add-leading-zero (t/minute parsed-time)))
|
||||
when-to-unmute (cond (= go-default-time
|
||||
muted-till-string) (i18n/label :t/until-you-turn-it-back-on)
|
||||
(today? parsed-time) (str hours-and-minutes " today")
|
||||
(tomorrow? parsed-time) (str hours-and-minutes " tomorrow")
|
||||
:else (str hours-and-minutes
|
||||
" "
|
||||
(i18n/label
|
||||
(keyword "t"
|
||||
(get int->weekday
|
||||
(t/day-of-week
|
||||
parsed-time))))
|
||||
" "
|
||||
(t/day parsed-time)
|
||||
" "
|
||||
(i18n/label
|
||||
(keyword "t"
|
||||
(get months
|
||||
(t/month parsed-time))))))]
|
||||
when-to-unmute))
|
||||
@@ -0,0 +1,83 @@
|
||||
(ns status-im2.common.muting.helpers-test
|
||||
(:require [cljs-time.coerce :as time-coerce]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.format :as t.format]
|
||||
[cljs.test :refer-macros [deftest testing is are]]
|
||||
[clojure.string :as string]
|
||||
[utils.datetime :as datetime]
|
||||
[status-im2.common.muting.helpers :as muting]))
|
||||
|
||||
(def mock-current-time-epoch 1655731506000)
|
||||
|
||||
(deftest format-mute-till-test
|
||||
(with-redefs [t/*ms-fn* (constantly mock-current-time-epoch)]
|
||||
(let [remove-msecs #(string/replace % #"\.\w*Z" "Z")
|
||||
time-str-to-obj #(t.format/parse (remove-msecs (time-coerce/to-string %)))
|
||||
curr-time (t/now)
|
||||
custom-HH-MM-formatter (t.format/formatter "HH:mm")
|
||||
custom-DD-formatter (t.format/formatter "DD")
|
||||
get-hh-mm #(t.format/unparse custom-HH-MM-formatter %)
|
||||
get-day #(t.format/unparse custom-DD-formatter %)
|
||||
get-week-day #(->> %
|
||||
t/day-of-week
|
||||
(get datetime/int->weekday))
|
||||
mock-today (t.format/unparse (t.format/formatters :date-time-no-ms) curr-time)
|
||||
in-n-days #(-> (time-str-to-obj mock-today)
|
||||
(t/plus (t/days %)))
|
||||
in-n-minutes #(-> (time-str-to-obj mock-today)
|
||||
(t/plus (t/minutes %)))
|
||||
in-n-hours #(-> (time-str-to-obj mock-today)
|
||||
(t/plus (t/hours %)))
|
||||
mock-tomorrow (in-n-days 1)
|
||||
mock-in-two-days (in-n-days 2)
|
||||
mock-in-three-days (in-n-days 3)
|
||||
mock-in-four-days (in-n-days 4)
|
||||
mock-in-five-days (in-n-days 5)
|
||||
mock-in-six-days (in-n-days 6)
|
||||
mock-in-15-minutes (in-n-minutes 15)
|
||||
mock-in-1-hour (in-n-hours 1)
|
||||
mock-in-8-hour (in-n-hours 8)
|
||||
get-month-day-int #(int (get-day %))
|
||||
today? (fn [mocked curr-time]
|
||||
(=
|
||||
(t.format/unparse (t.format/formatter "MM:DD") mocked)
|
||||
(t.format/unparse (t.format/formatter "MM:DD") curr-time)))
|
||||
tomorrow? (fn [mocked curr-time]
|
||||
(some #(= %
|
||||
(-
|
||||
(int (get-month-day-int mocked))
|
||||
(int (get-month-day-int curr-time))))
|
||||
[1 30 29 27]))
|
||||
form-full-date #(str (get-hh-mm %)
|
||||
" " (string/capitalize (get-week-day %))
|
||||
" " (get-month-day-int %)
|
||||
" " (string/capitalize (get datetime/months (t/month %))))
|
||||
today-date #(str (get-hh-mm %) " today")
|
||||
tomorrow-date #(str (get-hh-mm %) " tomorrow")
|
||||
write-date #(cond (today? % curr-time) (today-date %)
|
||||
(tomorrow? % curr-time) (tomorrow-date %)
|
||||
:else (form-full-date %))
|
||||
will-unmute-in-1-hour (remove-msecs (time-coerce/to-string mock-in-1-hour))
|
||||
will-unmute-in-8-hours (remove-msecs (time-coerce/to-string mock-in-8-hour))
|
||||
will-unmute-in-15-mins (remove-msecs (time-coerce/to-string mock-in-15-minutes))
|
||||
will-unmute-in-two-days (remove-msecs (time-coerce/to-string mock-in-two-days))
|
||||
will-unmute-tomorrow (remove-msecs (time-coerce/to-string mock-tomorrow))
|
||||
will-unmute-in-three-days (remove-msecs (time-coerce/to-string mock-in-three-days))
|
||||
will-unmute-in-four-days (remove-msecs (time-coerce/to-string mock-in-four-days))
|
||||
will-unmute-in-five-days (remove-msecs (time-coerce/to-string mock-in-five-days))
|
||||
will-unmute-in-six-days (remove-msecs (time-coerce/to-string mock-in-six-days))]
|
||||
(testing "Mute for minutes and hours"
|
||||
(are [arg expected] (= (muting/format-mute-till arg) expected)
|
||||
will-unmute-in-15-mins (write-date mock-in-15-minutes)
|
||||
will-unmute-in-1-hour (write-date mock-in-1-hour)
|
||||
will-unmute-in-8-hours (write-date mock-in-8-hour)))
|
||||
(testing "Weekdays"
|
||||
(are [arg expected] (= (muting/format-mute-till arg) expected)
|
||||
will-unmute-tomorrow (write-date mock-tomorrow)
|
||||
will-unmute-in-two-days (write-date mock-in-two-days)
|
||||
will-unmute-in-three-days (write-date mock-in-three-days)
|
||||
will-unmute-in-four-days (write-date mock-in-four-days)
|
||||
will-unmute-in-five-days (write-date mock-in-five-days)
|
||||
will-unmute-in-six-days (write-date mock-in-six-days)))
|
||||
(testing "Until the user turns it back on"
|
||||
(is (= "you turn it back on" (muting/format-mute-till datetime/go-default-time)))))))
|
||||
@@ -26,7 +26,6 @@
|
||||
(def snoopy-enabled? (enabled? (get-config :SNOOPY 0)))
|
||||
(def dev-build? (enabled? (get-config :DEV_BUILD 0)))
|
||||
(def max-message-delivery-attempts (js/parseInt (get-config :MAX_MESSAGE_DELIVERY_ATTEMPTS "6")))
|
||||
(def max-images-batch (js/parseInt (get-config :MAX_IMAGES_BATCH "1")))
|
||||
;; NOTE: only disabled in releases
|
||||
(def local-notifications? (enabled? (get-config :LOCAL_NOTIFICATIONS "1")))
|
||||
(def blank-preview? (enabled? (get-config :BLANK_PREVIEW "1")))
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
(def ^:const mute-for-8-hours-type 3)
|
||||
(def ^:const mute-for-1-week 4)
|
||||
(def ^:const mute-till-unmuted 5)
|
||||
(def ^:const un-muted 0)
|
||||
|
||||
(def ^:const activity-center-mark-all-as-read-undo-time-limit-ms 4000)
|
||||
(def ^:const activity-center-max-unread-count 99)
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
(ns status-im2.contexts.chat.camera.style
|
||||
(:require [quo2.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(def screen-container
|
||||
{:flex 1
|
||||
:background-color colors/black})
|
||||
|
||||
(def flash-container
|
||||
{:position :absolute
|
||||
:top 50
|
||||
:left 25})
|
||||
|
||||
(defn camera-window
|
||||
[width height top]
|
||||
{:width width
|
||||
:height height
|
||||
:top top})
|
||||
|
||||
(def zoom-button-container
|
||||
{:width 37
|
||||
:height 37
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(defn zoom-container
|
||||
[top insets]
|
||||
{:width 157
|
||||
:height 43
|
||||
:border-radius 100
|
||||
:position :absolute
|
||||
:background-color colors/black-opa-60
|
||||
:align-self :center
|
||||
:justify-content :space-around
|
||||
:align-items :center
|
||||
:flex-direction :row
|
||||
:bottom (+ top (:bottom insets) (when platform/android? (:top insets)) 18)})
|
||||
|
||||
(defn zoom-button
|
||||
[size]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:width size
|
||||
:height size}
|
||||
{:background-color colors/black-opa-30
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:border-radius 50}))
|
||||
|
||||
(defn bottom-area
|
||||
[top insets]
|
||||
{:left 20
|
||||
:right 20
|
||||
:position :absolute
|
||||
:height (+ top (when platform/android? (:top insets)))
|
||||
:bottom (:bottom insets)})
|
||||
|
||||
(def photo-text
|
||||
{:color colors/system-yellow
|
||||
:margin-top 18
|
||||
:font-size 14
|
||||
:align-self :center})
|
||||
|
||||
(def actions-container
|
||||
{:flex-direction :row
|
||||
:margin-top 20
|
||||
:align-items :center
|
||||
:justify-content :space-between})
|
||||
|
||||
(def outer-circle
|
||||
{:width 69
|
||||
:height 69
|
||||
:background-color colors/black
|
||||
:border-radius 69
|
||||
:border-width 6
|
||||
:border-color colors/white
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
(def inner-circle
|
||||
{:width 53
|
||||
:height 53
|
||||
:border-radius 53
|
||||
:background-color colors/white})
|
||||
|
||||
(defn confirmation-container
|
||||
[insets]
|
||||
{:position :absolute
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:background-color "#131313"
|
||||
:height (+ 69 (:bottom insets))
|
||||
:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:justify-content :space-between
|
||||
:padding-top 18})
|
||||
@@ -0,0 +1,101 @@
|
||||
(ns status-im2.contexts.chat.camera.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.camera-kit :as camera-kit]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.contexts.chat.camera.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- f-zoom-button
|
||||
[{:keys [value current-zoom]}]
|
||||
(let [selected? (= @current-zoom value)
|
||||
size (reanimated/use-shared-value (if selected? 37 25))]
|
||||
(rn/use-effect #(reanimated/animate size (if selected? 37 25)) [@current-zoom])
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(reset! current-zoom value)
|
||||
:style style/zoom-button-container
|
||||
:accessibility-label (str "zoom-" value)}
|
||||
[reanimated/view {:style (style/zoom-button size)}
|
||||
[quo/text
|
||||
{:size (if selected? :paragraph-2 :label)
|
||||
:weight :semi-bold
|
||||
:style {:color (if selected?
|
||||
colors/system-yellow
|
||||
colors/white)}}
|
||||
(str value (when selected? "x"))]]]))
|
||||
|
||||
(defn zoom-button
|
||||
[args]
|
||||
[:f> f-zoom-button args])
|
||||
|
||||
(defn snap-button
|
||||
[camera-ref uri]
|
||||
[rn/view
|
||||
{:style style/outer-circle
|
||||
:accessibility-label :snap}
|
||||
[rn/touchable-opacity
|
||||
{:on-press (fn []
|
||||
(camera-kit/capture @camera-ref #(reset! uri %)))
|
||||
:style style/inner-circle}]])
|
||||
|
||||
(defn camera-screen
|
||||
[]
|
||||
(let [camera-ref (atom nil)
|
||||
uri (reagent/atom nil)
|
||||
current-zoom (reagent/atom "1")]
|
||||
(fn []
|
||||
(let [window (rn/get-window)
|
||||
{:keys [width height]} window
|
||||
camera-window-height (* width 1.33)
|
||||
insets (safe-area/get-insets)
|
||||
top (/ (- height camera-window-height (:bottom insets)) 2)]
|
||||
[rn/view {:style style/screen-container}
|
||||
(when-not @uri
|
||||
[rn/view {:style style/flash-container}
|
||||
[quo/icon :i/flash-camera
|
||||
{:color colors/white
|
||||
:size 24}]])
|
||||
(if @uri
|
||||
[rn/image
|
||||
{:style (style/camera-window width camera-window-height top)
|
||||
:source {:uri @uri}}]
|
||||
[camera-kit/camera
|
||||
{:ref #(reset! camera-ref %)
|
||||
:style (style/camera-window width camera-window-height top)}])
|
||||
(when-not @uri
|
||||
[rn/view {:style (style/zoom-container top insets)}
|
||||
[zoom-button {:value "0.5" :current-zoom current-zoom}]
|
||||
[zoom-button {:value "1" :current-zoom current-zoom}]
|
||||
[zoom-button {:value "2" :current-zoom current-zoom}]
|
||||
[zoom-button {:value "3" :current-zoom current-zoom}]])
|
||||
(if @uri
|
||||
[rn/view {:style (style/confirmation-container insets)}
|
||||
[quo/text
|
||||
{:on-press #(reset! uri nil)
|
||||
:style {:font-size 17
|
||||
:color colors/white}}
|
||||
(i18n/label :t/retake)]
|
||||
[quo/text
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:photo-selector/camera-roll-pick {:uri @uri}])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:style {:font-size 17
|
||||
:color colors/white}}
|
||||
(i18n/label :t/use-photo)]]
|
||||
[rn/view {:style (style/bottom-area top insets)}
|
||||
[quo/text {:style style/photo-text} (i18n/label :t/PHOTO)]
|
||||
[rn/view {:style style/actions-container}
|
||||
[quo/text
|
||||
{:on-press #(rf/dispatch [:navigate-back])
|
||||
:style {:font-size 17
|
||||
:color colors/white}
|
||||
:accessibility-label :cancel}
|
||||
(i18n/label :t/cancel)]
|
||||
[snap-button camera-ref uri]
|
||||
[quo/icon :i/rotate-camera
|
||||
{:size 48 :color colors/white :accessibility-label :flip-camera}]]])]))))
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im2.contexts.chat.composer.actions.view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.permissions :as permissions]
|
||||
[react-native.platform :as platform]
|
||||
@@ -9,6 +10,7 @@
|
||||
[status-im2.common.alert.events :as alert]
|
||||
[status-im2.contexts.chat.composer.constants :as comp-constants]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[status-im2.common.device-permissions :as device-permissions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.composer.actions.style :as style]
|
||||
@@ -18,7 +20,7 @@
|
||||
[{:keys [sending-images? sending-links?]}
|
||||
{:keys [text-value focused? maximized?]}
|
||||
{:keys [height saved-height last-height opacity background-y container-opacity]}
|
||||
window-height]
|
||||
window-height edit]
|
||||
(reanimated/animate height comp-constants/input-height)
|
||||
(reanimated/set-shared-value saved-height comp-constants/input-height)
|
||||
(reanimated/set-shared-value last-height comp-constants/input-height)
|
||||
@@ -36,12 +38,13 @@
|
||||
(reset! text-value "")
|
||||
(reset! sending-links? false)
|
||||
(reset! sending-images? false)
|
||||
(messages.list/scroll-to-bottom))
|
||||
(when-not (some? edit)
|
||||
(messages.list/scroll-to-bottom)))
|
||||
|
||||
(defn f-send-button
|
||||
[props {:keys [text-value] :as state}
|
||||
animations window-height images?
|
||||
btn-opacity z-index]
|
||||
btn-opacity z-index edit]
|
||||
(rn/use-effect (fn []
|
||||
(if (or (seq @text-value) images?)
|
||||
(when (or (not= @z-index 1) (not= (reanimated/get-shared-value btn-opacity) 1))
|
||||
@@ -58,14 +61,14 @@
|
||||
{:icon true
|
||||
:size 32
|
||||
:accessibility-label :send-message-button
|
||||
:on-press #(send-message props state animations window-height)}
|
||||
:on-press #(send-message props state animations window-height edit)}
|
||||
:i/arrow-up]])
|
||||
|
||||
(defn send-button
|
||||
[props {:keys [text-value] :as state} animations window-height images?]
|
||||
[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))]
|
||||
[:f> f-send-button props state animations window-height images? btn-opacity z-index]))
|
||||
[:f> f-send-button props state animations window-height images? btn-opacity z-index edit]))
|
||||
|
||||
(defn disabled-audio-button
|
||||
[]
|
||||
@@ -147,16 +150,32 @@
|
||||
50)}]))
|
||||
:max-duration-ms constants/audio-max-duration-ms}]]))
|
||||
|
||||
(defn images-limit-toast
|
||||
[]
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :random-id
|
||||
:icon :info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:container-style {:top (when platform/ios? 20)}
|
||||
:text (i18n/label :t/only-6-images)}]))
|
||||
|
||||
|
||||
(defn go-to-camera
|
||||
[images-count]
|
||||
(device-permissions/camera #(if (>= images-count constants/max-album-photos)
|
||||
(images-limit-toast)
|
||||
(rf/dispatch [:navigate-to :camera-screen]))))
|
||||
|
||||
(defn camera-button
|
||||
[]
|
||||
[quo/button
|
||||
{:on-press #(js/alert "to be implemented")
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/camera])
|
||||
(let [images-count (count (vals (rf/sub [:chats/sending-image])))]
|
||||
[quo/button
|
||||
{:on-press #(go-to-camera images-count)
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/camera]))
|
||||
|
||||
(defn open-photo-selector
|
||||
[{:keys [input-ref]}
|
||||
@@ -215,7 +234,7 @@
|
||||
[image-button props animations insets]
|
||||
[reaction-button]
|
||||
[format-button]]
|
||||
[:f> send-button props state animations window-height images]
|
||||
[: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.
|
||||
|
||||
@@ -42,3 +42,5 @@
|
||||
(def ^:const unfurl-debounce-ms
|
||||
"Use a high threshold to prevent unnecessary rendering overhead."
|
||||
400)
|
||||
|
||||
(def ^:const mention-rerender-debounce-ms 500)
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
(when (and (empty? @text-value) (not= input-text nil))
|
||||
(reset! text-value input-text)
|
||||
(reset! content-height input-content-height)
|
||||
(reset! saved-cursor-position (count input-text)))
|
||||
(reset! saved-cursor-position (count input-text))
|
||||
(rf/dispatch [:mention/on-change-text @text-value]))
|
||||
(when input-maximized?
|
||||
(reset! maximized? true)))
|
||||
|
||||
@@ -109,7 +110,6 @@
|
||||
(let [edit-text (get-in edit [:content :text])]
|
||||
(when (and edit @input-ref)
|
||||
(.focus ^js @input-ref)
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text edit-text}))
|
||||
(reset! text-value edit-text)
|
||||
(reset! saved-cursor-position (count edit-text)))))
|
||||
[(:message-id edit)]))
|
||||
@@ -126,32 +126,12 @@
|
||||
(.focus ^js @input-ref)))
|
||||
[(:message-id reply)]))
|
||||
|
||||
(defn edit-mentions
|
||||
[{:keys [input-ref]} {:keys [text-value cursor-position]} {:keys [input-with-mentions]}]
|
||||
(rn/use-effect (fn []
|
||||
(let [input-text (reduce (fn [acc item]
|
||||
(str acc (second item)))
|
||||
""
|
||||
input-with-mentions)]
|
||||
(reset! text-value input-text)
|
||||
(reset! cursor-position (count input-text))
|
||||
(js/setTimeout #(when @input-ref
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:selection {:start (count input-text)
|
||||
:end (count
|
||||
input-text)}})))
|
||||
300)))
|
||||
[(some #(= :mention (first %)) (seq input-with-mentions))]))
|
||||
|
||||
(defn update-input-mention
|
||||
[{:keys [input-ref]}
|
||||
{:keys [text-value]}
|
||||
[{:keys [text-value]}
|
||||
{:keys [input-text]}]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when (and input-text (not= @text-value input-text))
|
||||
(when @input-ref
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text input-text})))
|
||||
(reset! text-value input-text)
|
||||
(rf/dispatch [:mention/on-change-text input-text])))
|
||||
[input-text]))
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
(ns status-im2.contexts.chat.composer.handlers
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.chat.composer.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||
[status-im2.contexts.chat.composer.selection :as selection]
|
||||
@@ -13,8 +11,8 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn focus
|
||||
[{:keys [input-ref] :as props}
|
||||
{:keys [text-value focused? lock-selection? saved-cursor-position gradient-z-index]}
|
||||
[props
|
||||
{:keys [focused? lock-selection? gradient-z-index]}
|
||||
{:keys [height saved-height last-height opacity background-y gradient-opacity container-opacity]
|
||||
:as animations}
|
||||
{:keys [max-height] :as dimensions}]
|
||||
@@ -30,9 +28,6 @@
|
||||
(reanimated/animate gradient-opacity 1)
|
||||
(reset! gradient-z-index 1))
|
||||
(js/setTimeout #(reset! lock-selection? false) 300)
|
||||
(when (and (not-empty @text-value) @input-ref)
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:selection {:start @saved-cursor-position :end @saved-cursor-position}})))
|
||||
(kb/handle-refocus-emoji-kb-ios props animations dimensions))
|
||||
|
||||
(defn blur
|
||||
@@ -119,23 +114,17 @@
|
||||
|
||||
(defn change-text
|
||||
[text
|
||||
{:keys [input-ref record-reset-fn]}
|
||||
{:keys [text-value cursor-position recording?]}]
|
||||
{:keys [record-reset-fn]}
|
||||
{:keys [text-value recording?]}]
|
||||
(debounce/debounce-and-dispatch [:link-preview/unfurl-urls text]
|
||||
constants/unfurl-debounce-ms)
|
||||
|
||||
(reset! text-value text)
|
||||
(reagent/next-tick #(when @input-ref
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:selection {:start @cursor-position
|
||||
:end @cursor-position}}))))
|
||||
(when @recording?
|
||||
(@record-reset-fn)
|
||||
(reset! recording? false))
|
||||
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
||||
(if (string/ends-with? text "@")
|
||||
(rf/dispatch [:mention/on-change-text text])
|
||||
(debounce/debounce-and-dispatch [:mention/on-change-text text] 300)))
|
||||
(rf/dispatch [:mention/on-change-text text]))
|
||||
|
||||
(defn selection-change
|
||||
[event
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im2.contexts.chat.composer.mentions.view
|
||||
(:require
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
@@ -10,23 +9,12 @@
|
||||
[status-im2.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im2.contexts.chat.composer.mentions.style :as style]))
|
||||
|
||||
(defn update-cursor
|
||||
[user {:keys [cursor-position input-ref]}]
|
||||
(when platform/android?
|
||||
(let [new-cursor-pos (+ (count (:primary-name user)) @cursor-position 1)]
|
||||
(reset! cursor-position new-cursor-pos)
|
||||
(reagent/next-tick #(when @input-ref
|
||||
(.setNativeProps ^js @input-ref
|
||||
(clj->js {:selection {:start new-cursor-pos
|
||||
:end
|
||||
new-cursor-pos}})))))))
|
||||
|
||||
(defn mention-item
|
||||
[user _ _ render-data]
|
||||
[user _ _ _]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:chat.ui/select-mention nil user])
|
||||
(update-cursor user render-data))}
|
||||
(rf/dispatch [:chat.ui/select-mention nil user]))}
|
||||
user])
|
||||
|
||||
(defn- f-view
|
||||
|
||||
@@ -125,3 +125,10 @@
|
||||
{:transform [{:translate-y translate-y}]
|
||||
:opacity opacity}
|
||||
{}))
|
||||
|
||||
(def mention
|
||||
{:color (colors/theme-colors colors/primary-50
|
||||
colors/primary-60)
|
||||
:background-color colors/primary-50-opa-10
|
||||
:selection-color :transparent
|
||||
:suppress-highlighting true})
|
||||
|
||||
@@ -23,7 +23,19 @@
|
||||
[status-im2.contexts.chat.composer.handlers :as handler]
|
||||
[status-im2.contexts.chat.composer.gradients.view :as gradients]
|
||||
[status-im2.contexts.chat.composer.selection :as selection]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as theme]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(defn styled-text-input-content
|
||||
[input-with-mentions]
|
||||
(reduce (fn
|
||||
[styled-text [chunk-type chunk-content]]
|
||||
(condp = chunk-type
|
||||
:text (conj styled-text chunk-content)
|
||||
:mention (conj styled-text
|
||||
[quo/text {:style style/mention :weight :medium} chunk-content])))
|
||||
[quo/text]
|
||||
input-with-mentions))
|
||||
|
||||
(defn sheet-component
|
||||
[{:keys [insets window-height blur-height opacity background-y]} props state]
|
||||
@@ -61,8 +73,7 @@
|
||||
subs)
|
||||
(effects/edit props state subs)
|
||||
(effects/reply props animations subs)
|
||||
(effects/update-input-mention props state subs)
|
||||
(effects/edit-mentions props state subs)
|
||||
(effects/update-input-mention state subs)
|
||||
(effects/link-previews props state animations subs)
|
||||
(effects/images props state animations subs)
|
||||
[:<>
|
||||
@@ -94,7 +105,6 @@
|
||||
: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 %
|
||||
@@ -115,7 +125,8 @@
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:style (style/input-text props state subs max-height)
|
||||
:max-length constants/max-text-size
|
||||
:accessibility-label :chat-message-input}]]
|
||||
:accessibility-label :chat-message-input}
|
||||
[styled-text-input-content (:input-with-mentions subs)]]]
|
||||
(when chat-screen-loaded?
|
||||
[:<>
|
||||
[gradients/view props state animations show-bottom-gradient?]
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
[status-im.utils.types :as types]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[utils.datetime :as datetime]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.async-storage.core :as async-storage]
|
||||
[status-im2.contexts.shell.jump-to.constants :as shell.constants]))
|
||||
[status-im2.contexts.shell.jump-to.constants :as shell.constants]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]))
|
||||
|
||||
(defn- get-chat
|
||||
[cofx chat-id]
|
||||
@@ -293,6 +293,12 @@
|
||||
(deactivate-chat chat-id)
|
||||
(offload-messages chat-id)))
|
||||
|
||||
(rf/defn unmute-chat-community
|
||||
{:events [:chat/unmute-chat-community]}
|
||||
[{:keys [db]} chat-id muted?]
|
||||
(let [{:keys [community-id]} (get-in db [:chats chat-id])]
|
||||
{:db (assoc-in db [:communities community-id :muted] muted?)}))
|
||||
|
||||
(rf/defn mute-chat-failed
|
||||
{:events [:chat/mute-failed]}
|
||||
[{:keys [db]} chat-id muted? error]
|
||||
@@ -303,6 +309,8 @@
|
||||
{:events [:chat/mute-successfully]}
|
||||
[{:keys [db]} chat-id muted-till mute-type muted? chat-type]
|
||||
(log/debug "muted chat successfully" chat-id " for" muted-till)
|
||||
(when-not muted?
|
||||
(rf/dispatch [:chat/unmute-chat-community chat-id muted?]))
|
||||
(let [time-string (fn [duration-kw unmute-time]
|
||||
(i18n/label duration-kw {:duration unmute-time}))
|
||||
not-community-chat? #(contains? #{constants/public-chat-type
|
||||
@@ -344,11 +352,11 @@
|
||||
:t/channel-unmuted-successfully))))]
|
||||
{:db (assoc-in db [:chats chat-id :muted-till] muted-till)
|
||||
:dispatch [:toasts/upsert
|
||||
{:icon :correct
|
||||
{:icon :i/correct
|
||||
:icon-color (colors/theme-colors colors/success-60
|
||||
colors/success-50)
|
||||
:text (mute-duration-text (when (some? muted-till)
|
||||
(str (datetime/format-mute-till muted-till))))}]}))
|
||||
(str (format-mute-till muted-till))))}]}))
|
||||
|
||||
(rf/defn mute-chat
|
||||
{:events [:chat.ui/mute]}
|
||||
@@ -361,7 +369,7 @@
|
||||
:params params
|
||||
:on-error #(rf/dispatch [:chat/mute-failed chat-id muted? %])
|
||||
:on-success #(rf/dispatch [:chat/mute-successfully chat-id % mute-type
|
||||
(not muted?) chat-type])}]}))
|
||||
muted? chat-type])}]}))
|
||||
|
||||
(rf/defn show-clear-history-confirmation
|
||||
{:events [:chat.ui/show-clear-history-confirmation]}
|
||||
|
||||
@@ -235,8 +235,9 @@
|
||||
(if-not muted
|
||||
(when show-unread-badge?
|
||||
[quo/info-count
|
||||
{:style {:top 16
|
||||
:right 16}}
|
||||
{:style {:top 16
|
||||
:right 16}
|
||||
:accessibility-label :new-message-counter}
|
||||
unviewed-messages-count])
|
||||
[icons/icon :i/muted
|
||||
{:color colors/neutral-40
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
uri
|
||||
#(rf/dispatch [:toasts/upsert
|
||||
{:id :random-id
|
||||
:icon :correct
|
||||
:icon :i/correct
|
||||
:icon-color colors/success-50
|
||||
:container-style {:bottom (when platform/android? 20)}
|
||||
:text (i18n/label :t/photo-saved)}])))}]]]))
|
||||
@@ -111,12 +111,15 @@
|
||||
:style {:color colors/neutral-40}} (when timestamp (datetime/to-short-str timestamp))]]]
|
||||
[rn/view {:style style/top-right-buttons}
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(share-image messages @index)
|
||||
:style (merge style/close-container {:margin-right 12})}
|
||||
{:active-opacity 1
|
||||
:accessibility-label :share-image
|
||||
:on-press #(share-image messages @index)
|
||||
:style (merge style/close-container {:margin-right 12})}
|
||||
[quo/icon :share {:size 20 :color colors/white}]]
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content (fn [] [drawer messages @index])}])
|
||||
:style style/close-container}
|
||||
{:active-opacity 1
|
||||
:accessibility-label :image-options
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [drawer messages @index])}])
|
||||
:style style/close-container}
|
||||
[quo/icon :options {:size 20 :color colors/white}]]]]))
|
||||
|
||||
@@ -15,19 +15,22 @@
|
||||
(defn mention-tag-wrapper
|
||||
[]
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
:align-items :center
|
||||
:height 22})
|
||||
|
||||
(def mention-tag
|
||||
{:background-color colors/primary-50-opa-10
|
||||
:padding-horizontal 3
|
||||
:border-radius 6
|
||||
:margin-bottom -3})
|
||||
:margin-bottom -3
|
||||
:height 22})
|
||||
|
||||
(def mention-tag-text
|
||||
{:color (colors/theme-colors colors/primary-50
|
||||
colors/primary-60)
|
||||
:selection-color :transparent
|
||||
:suppress-highlighting true})
|
||||
:suppress-highlighting true
|
||||
:line-height 21})
|
||||
|
||||
(defn code
|
||||
[]
|
||||
|
||||
@@ -63,7 +63,8 @@
|
||||
:style style/mention-tag}
|
||||
[quo/text
|
||||
{:weight :medium
|
||||
:style style/mention-tag-text}
|
||||
:style style/mention-tag-text
|
||||
:size :paragraph-1}
|
||||
(rf/sub [:messages/resolve-mention literal])]]])
|
||||
|
||||
:edited
|
||||
|
||||
@@ -30,12 +30,13 @@
|
||||
(def delivery-state-showing-time-ms 3000)
|
||||
|
||||
(defn avatar-container
|
||||
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions?]
|
||||
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions? show-user-info?]
|
||||
(if (or (and (seq (:response-to content))
|
||||
quoted-message)
|
||||
last-in-group?
|
||||
pinned-by
|
||||
(not show-reactions?))
|
||||
(not show-reactions?)
|
||||
show-user-info?)
|
||||
[avatar/avatar from :small]
|
||||
[rn/view {:padding-top 2 :width 32}]))
|
||||
|
||||
@@ -47,8 +48,13 @@
|
||||
quoted-message
|
||||
from
|
||||
timestamp]}
|
||||
show-reactions?]
|
||||
(when (or (and (seq response-to) quoted-message) last-in-group? pinned-by (not show-reactions?))
|
||||
show-reactions?
|
||||
show-user-info?]
|
||||
(when (or (and (seq response-to) quoted-message)
|
||||
last-in-group?
|
||||
pinned-by
|
||||
(not show-reactions?)
|
||||
show-user-info?)
|
||||
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
|
||||
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
|
||||
[quo/author
|
||||
@@ -84,7 +90,7 @@
|
||||
(defn user-message-content
|
||||
[]
|
||||
(let [show-delivery-state? (reagent/atom false)]
|
||||
(fn [{:keys [message-data context keyboard-shown? show-reactions?]}]
|
||||
(fn [{:keys [message-data context keyboard-shown? show-reactions? show-user-info?]}]
|
||||
(let [{:keys [content-type quoted-message content
|
||||
outgoing outgoing-status pinned-by]} message-data
|
||||
first-image (first (:album message-data))
|
||||
@@ -129,7 +135,7 @@
|
||||
[rn/view
|
||||
{:style {:padding-horizontal 4
|
||||
:flex-direction :row}}
|
||||
[avatar-container message-data show-reactions?]
|
||||
[avatar-container message-data show-reactions? show-user-info?]
|
||||
(into
|
||||
(if show-reactions?
|
||||
[rn/view]
|
||||
@@ -138,7 +144,7 @@
|
||||
:flex 1
|
||||
:max-height (when-not show-reactions?
|
||||
(* 0.4 height))}}
|
||||
[author message-data show-reactions?]
|
||||
[author message-data show-reactions? show-user-info?]
|
||||
(case content-type
|
||||
|
||||
constants/content-type-text
|
||||
@@ -184,7 +190,8 @@
|
||||
{:message-data message-data
|
||||
:context context
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:show-reactions? true}]])}]))
|
||||
:show-reactions? true
|
||||
:show-user-info? true}]])}]))
|
||||
|
||||
(defn message
|
||||
[{:keys [pinned-by mentioned content-type last-in-group? deleted? deleted-for-me?]
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
[[:toasts/close :delete-message-for-everyone]
|
||||
[:toasts/upsert
|
||||
{:id :delete-message-for-everyone
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:message-deleted-for-everyone-count toast-count
|
||||
:message-deleted-for-everyone-undos existing-undos
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
:dispatch-n [[:toasts/close :delete-message-for-me]
|
||||
[:toasts/upsert
|
||||
{:id :delete-message-for-me
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:message-deleted-for-me-count toast-count
|
||||
:message-deleted-for-me-undos existing-undos
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
(:require [react-native.cameraroll :as cameraroll]
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[react-native.permissions :as permissions]
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.utils.image-processing :as image-processing]
|
||||
[taoensso.timbre :as log]
|
||||
@@ -141,6 +141,6 @@
|
||||
[{:keys [db]} image chat-id]
|
||||
(let [current-chat-id (or chat-id (:current-chat-id db))
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (and (< (count images) config/max-images-batch)
|
||||
(when (and (< (count images) constants/max-album-photos)
|
||||
(not (some #(= (:uri image) (:uri %)) images)))
|
||||
{:camera-roll-image-selected [image current-chat-id]})))
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
[]
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :random-id
|
||||
:icon :info
|
||||
:icon :i/info
|
||||
:icon-color colors/danger-50-opa-40
|
||||
:container-style {:top (when platform/ios? 20)}
|
||||
:text (i18n/label :t/only-6-images)}]))
|
||||
@@ -56,11 +56,11 @@
|
||||
(when (and (not album?) (seq @selected))
|
||||
[rn/view {:style style/clear-container}
|
||||
[quo/button
|
||||
{:type :blurred
|
||||
{:type :grey
|
||||
:size 32
|
||||
:accessibility-label :clear
|
||||
:on-press #(reset! selected [])
|
||||
:blur-active? blur-active?}
|
||||
:background (when blur-active? :photo)}
|
||||
(i18n/label :t/clear)]]))
|
||||
|
||||
(defn remove-selected
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(ns status-im2.contexts.communities.actions.chat.view
|
||||
(:require [quo2.core :as quo]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.common.mute-chat-drawer.view :as mute-chat-drawer]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
@@ -12,11 +12,15 @@
|
||||
(rf/dispatch event))
|
||||
|
||||
(defn- mute-channel-action
|
||||
[chat-id chat-type]
|
||||
[chat-id chat-type muted?]
|
||||
(hide-sheet-and-dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[mute-chat-drawer/mute-chat-drawer chat-id
|
||||
:mute-chat-for-duration chat-type])}]))
|
||||
[mute-drawer/mute-drawer
|
||||
{:id chat-id
|
||||
:community? false
|
||||
:muted? (not muted?)
|
||||
:chat-type chat-type
|
||||
:accessibility-label :mute-community-title}])}]))
|
||||
|
||||
(defn- unmute-channel-action
|
||||
[chat-id]
|
||||
@@ -46,16 +50,16 @@
|
||||
|
||||
(defn- action-toggle-muted
|
||||
[id muted? muted-till chat-type]
|
||||
(let [muted (and muted? (some? muted-till))]
|
||||
(let [muted (and muted? (some? muted-till))
|
||||
time-string (fn [mute-title mute-duration]
|
||||
(i18n/label mute-title {:duration mute-duration}))]
|
||||
(cond-> {:icon :i/muted
|
||||
:accessibility-label :chat-toggle-muted
|
||||
:sub-label (when muted
|
||||
(str (i18n/label :t/muted-until)
|
||||
" "
|
||||
(datetime/format-mute-till muted-till)))
|
||||
:sub-label (when (and muted? (some? muted-till))
|
||||
(time-string :t/muted-until (format-mute-till muted-till)))
|
||||
:on-press (if muted?
|
||||
#(unmute-channel-action id)
|
||||
#(mute-channel-action id chat-type))
|
||||
#(mute-channel-action id chat-type muted?))
|
||||
:label (i18n/label (if muted
|
||||
:t/unmute-channel
|
||||
:t/mute-channel))}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
[quo2.core :as quo]
|
||||
[status-im2.contexts.communities.actions.see-rules.view :as see-rules]
|
||||
[status-im2.contexts.communities.actions.leave.view :as leave-menu]
|
||||
[status-im2.common.mute-drawer.view :as mute-options]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.contexts.communities.actions.token-gating.view :as token-gating]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
@@ -45,12 +48,26 @@
|
||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-in-community-pressed id])})
|
||||
|
||||
(defn mute-community
|
||||
[_ muted?]
|
||||
{:icon (if muted? :i/muted :i/activity-center)
|
||||
:accessibility-label (if muted? :unmute-community :mute-community)
|
||||
:label (i18n/label (if muted? :t/unmute-community :t/mute-community))
|
||||
:sub-label (when muted? (str "muted for 15 minutes"))
|
||||
:right-icon :i/chevron-right})
|
||||
[id muted? muted-till]
|
||||
(let [time-string (fn [mute-title mute-duration]
|
||||
(i18n/label mute-title {:duration mute-duration}))]
|
||||
{:icon (if muted? :i/muted :i/activity-center)
|
||||
:accessibility-label (if muted? :unmute-community :mute-community)
|
||||
:label (i18n/label (if muted? :t/unmute-community :t/mute-community))
|
||||
:sub-label (when (and muted? (some? muted-till))
|
||||
(time-string :t/muted-until (format-mute-till muted-till)))
|
||||
:right-icon :i/chevron-right
|
||||
:on-press (if muted?
|
||||
#(hide-sheet-and-dispatch [:community/set-muted id (not muted?)
|
||||
constants/un-muted])
|
||||
#(hide-sheet-and-dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[mute-options/mute-drawer
|
||||
{:id id
|
||||
:community? true
|
||||
:muted? (not muted?)
|
||||
:accessibility-label :mute-community-title}])}]))}))
|
||||
|
||||
(defn community-notification-settings
|
||||
[id]
|
||||
@@ -119,12 +136,12 @@
|
||||
(not-joined-options id token-gated?))
|
||||
|
||||
(defn joined-options
|
||||
[id token-gated? muted?]
|
||||
[id token-gated? muted? muted-till]
|
||||
[[(view-members id)
|
||||
(view-rules id)
|
||||
(when token-gated? (view-token-gating id))
|
||||
(mark-as-read id)
|
||||
(mute-community id muted?)
|
||||
(mute-community id muted? muted-till)
|
||||
(community-notification-settings id)
|
||||
(invite-contacts id)
|
||||
(show-qr id)
|
||||
@@ -132,12 +149,12 @@
|
||||
[(assoc (leave-community id) :add-divider? true)]])
|
||||
|
||||
(defn owner-options
|
||||
[id token-gated? muted?]
|
||||
[id token-gated? muted? muted-till]
|
||||
[[(view-members id)
|
||||
(view-rules id)
|
||||
(when token-gated? (view-token-gating id))
|
||||
(mark-as-read id)
|
||||
(mute-community id muted?)
|
||||
(mute-community id muted? muted-till)
|
||||
(community-notification-settings id)
|
||||
(invite-contacts id)
|
||||
(show-qr id)
|
||||
@@ -146,11 +163,11 @@
|
||||
(defn get-context-drawers
|
||||
[{:keys [id]}]
|
||||
(let [{:keys [token-permissions admin joined
|
||||
muted banList]} (rf/sub [:communities/community id])
|
||||
request-id (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
muted banList muted-till]} (rf/sub [:communities/community id])
|
||||
request-id (rf/sub [:communities/my-pending-request-to-join id])]
|
||||
(cond
|
||||
admin (owner-options id token-permissions muted)
|
||||
joined (joined-options id token-permissions muted)
|
||||
admin (owner-options id token-permissions muted muted-till)
|
||||
joined (joined-options id token-permissions muted muted-till)
|
||||
request-id (join-request-sent-options id token-permissions request-id)
|
||||
banList (banned-options id token-permissions)
|
||||
:else (not-joined-options id token-permissions))))
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
cover {:uri (get-in (:images item) [:banner :uri])}]
|
||||
(if (= view-type :card-view)
|
||||
[quo/community-card-view-item (assoc item :width width :cover cover)
|
||||
#(rf/dispatch [:navigate-to :community-overview (:id item)])]
|
||||
#(rf/dispatch [:communities/navigate-to-community (:id item)])]
|
||||
[quo/community-list-item
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:communities/load-category-states (:id item)])
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:navigate-to :community-overview (:id item)]))
|
||||
(rf/dispatch [:communities/navigate-to-community (:id item)]))
|
||||
:on-long-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
@@ -141,12 +141,12 @@
|
||||
(merge community
|
||||
(get mock-community-item-data :data)
|
||||
{:cover cover})
|
||||
#(rf/dispatch [:navigate-to :community-overview (:id community)])]
|
||||
#(rf/dispatch [:communities/navigate-to-community (:id community)])]
|
||||
[quo/community-list-item
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:communities/load-category-states (:id community)])
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:navigate-to :community-overview (:id community)]))
|
||||
(rf/dispatch [:communities/navigate-to-community (:id community)]))
|
||||
:on-long-press #(js/alert "TODO: to be implemented")}
|
||||
(merge community
|
||||
(get mock-community-item-data :data))])]))
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
{:content (fn []
|
||||
[options/community-options-bottom-sheet id])
|
||||
:selected-item (fn []
|
||||
[quo/communities-membership-list-item {} item])}])}
|
||||
[quo/communities-membership-list-item {} true item])}])}
|
||||
false
|
||||
item]))
|
||||
|
||||
(def tabs-data
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
(defn token-gates
|
||||
[{:keys [id]}]
|
||||
(rf/dispatch [:communities/check-permissions-to-join-community id])
|
||||
(fn [{:keys [id community-color]}]
|
||||
(fn [{:keys [id color]}]
|
||||
(let [{:keys [can-request-access?
|
||||
number-of-hold-tokens tokens]} (rf/sub [:community/token-gated-overview id])]
|
||||
[rn/view {:style (style/token-gated-container)}
|
||||
@@ -162,16 +162,16 @@
|
||||
{:tokens tokens
|
||||
:padding? true}]
|
||||
[quo/button
|
||||
{:on-press #(join-gated-community id)
|
||||
:accessibility-label :join-community-button
|
||||
:override-background-color community-color
|
||||
:style {:margin-horizontal 12 :margin-top 12 :margin-bottom 12}
|
||||
:disabled (not can-request-access?)
|
||||
:before (if can-request-access? :i/unlocked :i/locked)}
|
||||
{:on-press #(join-gated-community id)
|
||||
:accessibility-label :join-community-button
|
||||
:customization-color color
|
||||
:style {:margin-horizontal 12 :margin-top 12 :margin-bottom 12}
|
||||
:disabled (not can-request-access?)
|
||||
:before (if can-request-access? :i/unlocked :i/locked)}
|
||||
(i18n/label :t/join-open-community)]])))
|
||||
|
||||
(defn join-community
|
||||
[{:keys [joined can-join? community-color permissions token-permissions] :as community}
|
||||
[{:keys [joined can-join? color permissions token-permissions] :as community}
|
||||
pending?]
|
||||
(let [access-type (get-access-type (:access permissions))
|
||||
unknown-access? (= access-type :unknown-access)
|
||||
@@ -183,10 +183,10 @@
|
||||
(if token-permissions
|
||||
[token-gates community]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:open-modal :community-requests-to-join community])
|
||||
:accessibility-label :show-request-to-join-screen-button
|
||||
:override-background-color community-color
|
||||
:before :i/communities}
|
||||
{:on-press #(rf/dispatch [:open-modal :community-requests-to-join community])
|
||||
:accessibility-label :show-request-to-join-screen-button
|
||||
:customization-color color
|
||||
:before :i/communities}
|
||||
(request-to-join-text is-open?)]))
|
||||
|
||||
(when (and (not (or joined pending? token-permissions)) (not (or is-open? node-offline?)))
|
||||
|
||||
@@ -4,16 +4,18 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn navigation-bar
|
||||
[{:keys [top right-section-buttons disable-back-button?]}]
|
||||
[rn/view
|
||||
{:style {:height 56
|
||||
:margin-top top}}
|
||||
[quo/page-nav
|
||||
{:align-mid? true
|
||||
:mid-section {:type :text-only :main-text ""}
|
||||
:left-section {:type :blur-bg
|
||||
:icon :i/arrow-left
|
||||
:icon-override-theme :dark
|
||||
:on-press (when-not disable-back-button?
|
||||
#(rf/dispatch [:navigate-back]))}
|
||||
:right-section-buttons right-section-buttons}]])
|
||||
[{:keys [top right-section-buttons disable-back-button? stack-id]}]
|
||||
(let [back-event (if stack-id [:navigate-back-within-stack stack-id] [:navigate-back])]
|
||||
[rn/view
|
||||
{:style {:height 56
|
||||
:margin-top top}}
|
||||
[quo/page-nav
|
||||
{:align-mid? true
|
||||
:mid-section {:type :text-only :main-text ""}
|
||||
:left-section {:type :blur-bg
|
||||
:icon :i/arrow-left
|
||||
:icon-override-theme :dark
|
||||
:on-press (fn []
|
||||
(when-not disable-back-button?
|
||||
(rf/dispatch back-event)))}
|
||||
:right-section-buttons right-section-buttons}]]))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns status-im2.contexts.onboarding.common.overlay.style
|
||||
(:require [react-native.reanimated :as reanimated]
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn blur-container
|
||||
[opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:opacity opacity}
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0}))
|
||||
|
||||
(def blur-style
|
||||
{:flex 1
|
||||
:background-color colors/neutral-80-opa-80-blur})
|
||||
@@ -0,0 +1,72 @@
|
||||
(ns status-im2.contexts.onboarding.common.overlay.view
|
||||
(:require [react-native.reanimated :as reanimated]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.onboarding.common.overlay.style :as style]
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
(def max-blur-amount 30)
|
||||
|
||||
(defonce timer-interval (atom nil))
|
||||
(defonce blur-dismiss-fn-atom (atom nil))
|
||||
(defonce blur-show-fn-atom (atom nil))
|
||||
|
||||
(defn blur-show
|
||||
[opacity blur-amount]
|
||||
(reanimated/animate opacity
|
||||
1
|
||||
(/ constants/onboarding-modal-animation-duration 2))
|
||||
(js/clearInterval @timer-interval)
|
||||
(reset! timer-interval
|
||||
(js/setInterval
|
||||
(fn []
|
||||
(if (< @blur-amount max-blur-amount)
|
||||
(swap! blur-amount + 1)
|
||||
(js/clearInterval @timer-interval)))
|
||||
(/ constants/onboarding-modal-animation-duration
|
||||
max-blur-amount
|
||||
2))))
|
||||
|
||||
(defn blur-dismiss
|
||||
[opacity blur-amount]
|
||||
(reanimated/animate-delay opacity
|
||||
0
|
||||
(/ constants/onboarding-modal-animation-duration 2)
|
||||
(/ constants/onboarding-modal-animation-duration 2))
|
||||
(reset! timer-interval
|
||||
(js/setInterval
|
||||
(fn []
|
||||
(if (> @blur-amount 0)
|
||||
(swap! blur-amount - 1)
|
||||
(js/clearInterval @timer-interval)))
|
||||
(/ constants/onboarding-modal-animation-duration
|
||||
max-blur-amount
|
||||
2))))
|
||||
|
||||
(defn f-view
|
||||
[blur-amount]
|
||||
(let [opacity (reanimated/use-shared-value 0)
|
||||
blur-show-fn #(blur-show opacity blur-amount)
|
||||
blur-dismiss-fn #(blur-dismiss opacity blur-amount)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(reset! blur-show-fn-atom blur-show-fn)
|
||||
(reset! blur-dismiss-fn-atom blur-dismiss-fn)
|
||||
(fn []
|
||||
(reset! blur-show-fn-atom nil)
|
||||
(reset! blur-dismiss-fn-atom nil))))
|
||||
[reanimated/view
|
||||
{:pointer-events :none
|
||||
:style (style/blur-container opacity)}
|
||||
[blur/view
|
||||
{:blur-amount @blur-amount
|
||||
:blur-radius 25
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:style style/blur-style}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [blur-amount (reagent/atom 0)]
|
||||
[:f> f-view blur-amount]))
|
||||
@@ -2,11 +2,9 @@
|
||||
(:require
|
||||
[oops.core :refer [ocall]]
|
||||
[quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
|
||||
[status-im2.contexts.onboarding.create-password.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -177,11 +175,11 @@
|
||||
|
||||
[rn/view {:style style/button-container}
|
||||
[quo/button
|
||||
{:disabled (not meet-requirements?)
|
||||
:override-background-color (colors/custom-color user-color 60)
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding-2/password-set
|
||||
(security/mask-data @password)])}
|
||||
{:disabled (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding-2/password-set
|
||||
(security/mask-data @password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]]]))))
|
||||
|
||||
(defn create-password-doc
|
||||
@@ -211,14 +209,14 @@
|
||||
{:content create-password-doc
|
||||
:shell? true}]))]
|
||||
[:<>
|
||||
[background/view true]
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press rn/dismiss-keyboard!
|
||||
:accessible false}
|
||||
[rn/view {:style style/flex-fill}
|
||||
[rn/keyboard-avoiding-view {:style style/flex-fill}
|
||||
[navigation-bar/navigation-bar
|
||||
{:top top
|
||||
{:stack-id :new-to-status
|
||||
:top top
|
||||
:right-section-buttons [{:type :blur-bg
|
||||
:icon :i/info
|
||||
:icon-override-theme :dark
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.onboarding.common.navigation-bar.view :as navigation-bar]
|
||||
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||
[status-im2.contexts.onboarding.select-photo.method-menu.view :as method-menu]
|
||||
[utils.re-frame :as rf]
|
||||
[oops.core :as oops]
|
||||
@@ -99,7 +98,9 @@
|
||||
name-too-short? :default
|
||||
:else :success)]
|
||||
[rn/view {:style style/page-container}
|
||||
[navigation-bar/navigation-bar {:top navigation-bar-top}]
|
||||
[navigation-bar/navigation-bar
|
||||
{:stack-id :new-to-status
|
||||
:top navigation-bar-top}]
|
||||
[rn/scroll-view
|
||||
{:content-container-style {:flexGrow 1}}
|
||||
[rn/view {:style style/page-container}
|
||||
@@ -122,7 +123,8 @@
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[method-menu/view on-change-profile-pic])}]))
|
||||
[method-menu/view on-change-profile-pic])
|
||||
:theme :dark}]))
|
||||
:image-picker-props {:profile-picture (when @profile-pic {:uri @profile-pic})
|
||||
:full-name (if (seq @full-name)
|
||||
@full-name
|
||||
@@ -160,16 +162,16 @@
|
||||
:pointer-events :box-none}
|
||||
[button-container @keyboard-shown?
|
||||
[quo/button
|
||||
{:accessibility-label :submit-create-profile-button
|
||||
:type :primary
|
||||
:override-background-color (colors/custom-color @custom-color 60)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:onboarding-2/profile-data-set
|
||||
{:image-path @profile-pic
|
||||
:display-name @full-name
|
||||
:color @custom-color}]))
|
||||
:style style/continue-button
|
||||
:disabled (or (not valid-name?) (not (seq @full-name)))}
|
||||
{:accessibility-label :submit-create-profile-button
|
||||
:type :primary
|
||||
:customization-color @custom-color
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:onboarding-2/profile-data-set
|
||||
{:image-path @profile-pic
|
||||
:display-name @full-name
|
||||
:color @custom-color}]))
|
||||
:style style/continue-button
|
||||
:disabled (or (not valid-name?) (not (seq @full-name)))}
|
||||
(i18n/label :t/continue)]]]])
|
||||
(finally
|
||||
(oops/ocall show-listener "remove")
|
||||
@@ -180,7 +182,6 @@
|
||||
(let [{:keys [top]} (safe-area/get-insets)
|
||||
onboarding-profile-data (rf/sub [:onboarding-2/profile])]
|
||||
[:<>
|
||||
[background/view true]
|
||||
[:f> f-page
|
||||
{:navigation-bar-top top
|
||||
:onboarding-profile-data onboarding-profile-data}]]))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im2.contexts.onboarding.enable-biometrics.view
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.contexts.onboarding.enable-biometrics.style :as style]
|
||||
@@ -9,7 +8,6 @@
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.common.parallax.view :as parallax]
|
||||
[status-im2.contexts.onboarding.common.background.view :as background]
|
||||
[status-im2.common.parallax.whitelist :as whitelist]
|
||||
[status-im2.common.biometric.events :as biometric]))
|
||||
|
||||
@@ -29,16 +27,17 @@
|
||||
profile-color (:color (rf/sub [:onboarding-2/profile]))]
|
||||
[rn/view {:style (style/buttons insets)}
|
||||
[quo/button
|
||||
{:accessibility-label :enable-biometrics-button
|
||||
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
|
||||
:before :i/face-id
|
||||
:override-background-color (colors/custom-color profile-color 50)}
|
||||
{:accessibility-label :enable-biometrics-button
|
||||
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
|
||||
:before :i/face-id
|
||||
:customization-color profile-color}
|
||||
(i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})]
|
||||
[quo/button
|
||||
{:accessibility-label :maybe-later-button
|
||||
:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
|
||||
:override-background-color colors/white-opa-5
|
||||
:style {:margin-top 12}}
|
||||
{:accessibility-label :maybe-later-button
|
||||
:background :blur
|
||||
:type :grey
|
||||
:on-press #(rf/dispatch [:onboarding-2/create-account-and-login])
|
||||
:style {:margin-top 12}}
|
||||
(i18n/label :t/maybe-later)]]))
|
||||
|
||||
(defn enable-biometrics-parallax
|
||||
@@ -69,7 +68,6 @@
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[background/view true]
|
||||
(if whitelist/whitelisted?
|
||||
[enable-biometrics-parallax]
|
||||
[enable-biometrics-simple])
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
(defn page-container
|
||||
[insets]
|
||||
{:flex 1
|
||||
:padding-top (:top insets)
|
||||
:background-color colors/neutral-80-opa-80-blur})
|
||||
{:flex 1
|
||||
:padding-top (:top insets)})
|
||||
|
||||
(def page-illustration
|
||||
{:flex 1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user