Compare commits

..
20 Commits
Author SHA1 Message Date
Ibrahem Khalil 841da88a80 Merge branch 'develop' into 15834 2023-06-13 15:16:22 +03:00
Yevheniia Berdnyk 6f920afcf7 e2e: Fixes for jump-to 2023-06-13 06:24:21 +03:00
Parvesh Monu f38c85546f fix App crashes when pressing on community link (#16019) 2023-06-12 22:39:22 +05:30
Icaro Motta 204c8996a3 Implement dummy action drawers for community chats (#16227)
Implements the skeleton for all community channel drawer actions. This commit is
not concerned with the actual implementation of the actions, since that would
grow the scope a bit too much.

Partially implements https://github.com/status-im/status-mobile/issues/16178

Notes: I also updated the actions drawer component to accept a text aligned to
the right (this will be necessary to display the number of pinned messages in
the action drawer). In the Design System, the text is always hidden, and that's
my best guess as to why we didn't implement it. I talked to designers, and they
won't update the Design System Drawer action component
https://www.figma.com/file/WQZcp6S0EnzxdTL4taoKDv/Design-System-for-Mobile?type=design&node-id=1931-31188&t=hOK17fADEXTlnXPY-0)
for now, but we agreed the reference in Figma > Communities for Mobile
https://www.figma.com/file/h9wo4GipgZURbqqr1vShFN/Communities-for-Mobile?type=design&node-id=5483-193285&t=vOTiuhxD87zhmK2T-0)
is good enough.
2023-06-12 12:02:47 -03:00
Volodymyr Kozieiev a5c41612a0 Information about patching 3rd parties (#16249) 2023-06-12 13:17:48 +01:00
Ibrahem Khalil a1d9f45f2f [16137] Disable text description in lightbox for now (#16169) 2023-06-12 11:14:22 +03:00
frank 78d6db5bf0 chore: align changes to RequestAllHistoricMessagesWithRetries (#16244) 2023-06-12 15:22:04 +08:00
Ibrahem 171b816c96 Bump statusgo 2023-06-10 16:36:27 +03:00
Mohamed Javid 9376da6c5c Prevent overflowing of chat name and message preview in the Chat List (#16210)
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-06-09 21:36:38 +05:30
Brian Sztamfater d5c7f0261e fix: fixes error message on login page
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-06-09 16:45:05 +01:00
Omar Basem 9c1d73ffcf fix: top bar ios (#16234)
* fix: top bar overlapped by composer
2023-06-09 18:47:52 +04:00
Omar Basem ab44dce27b fix: bottom sheet padding (#16216)
* fix: bottom sheet padding
2023-06-09 17:03:00 +04:00
Rahul Pratap 573115c22e Update progress on swiping carousel. (#16154)
* Update progress on swiping carousel.

* Fixed feedbacks.
2023-06-09 17:53:06 +05:30
Omar Basem 83b35f0439 fix: shell button position in chat screen (#16190)
* fix: shell button position
2023-06-09 15:18:59 +04:00
Mohamed Javid 2df1b46975 [iOS] Perform preflight check for local network permission (#16150)
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-06-09 15:55:15 +05:30
Parvesh Monu 9b52bba95d fix hole view usage for create profile picture (#16001) 2023-06-09 14:15:26 +05:30
Ibrahem Khalil a5f1028e67 [16082] Adjust height between messages to match designs (#16170) 2023-06-09 11:11:19 +04:00
Jamie Caprani 51ccd9fdcb chore: remove mock data from syncing (#16132) 2023-06-08 10:10:51 -07:00
Alexander 1594ff47f5 Layout updates/fixes for pinned messages bar (#16179)
* Blur under the pinned message bar

* Updated styles

* Code style update

* Style updates

* Updated z-index for composer mentions/suggestions

* Fixes for colors

* Positioning fix rollback

* Small code style update

* Formatting fix
2023-06-08 17:48:12 +01:00
Mohamed Javid c59de7dbf8 [Fix] Navigation to message reaction (#16218)
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-06-08 21:47:10 +05:30
82 changed files with 1250 additions and 806 deletions
+2
View File
@@ -20,6 +20,8 @@
[Debugging](debugging.md)
[Patching](patching.md)
## Testing
+13
View File
@@ -0,0 +1,13 @@
# Patching
## Libraries
If 3rd party library has an issue and fix is not yet released (or we can't switch to a new release), we use forks. Fix should be commited to the fork, tagged and referenced from package.json.
Example: [`react-native-hole-view`](https://github.com/status-im/react-native-hole-view#refs/tags/v2.1.1-status)
## React Native
When patch need to be applied to React Native itself Status does patching with Nix instead of doing it nodejs-way.
Patches should be added to [this file](https://github.com/status-im/status-mobile/blob/develop/nix/deps/nodejs-patched/default.nix).
Example: [patching `react-native/Yoga` to build app with XCode 14.3](https://github.com/status-im/status-mobile/pull/15589)
@@ -304,6 +304,14 @@ RCT_EXPORT_METHOD(hashMessage:(NSString *)message
callback(@[result]);
}
RCT_EXPORT_METHOD(localPairingPreflightOutboundCheck:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"LocalPairingPreflightOutboundCheck() method called");
#endif
NSString *result = StatusgoLocalPairingPreflightOutboundCheck();
callback(@[result]);
}
RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)configJSON
callback:(RCTResponseSenderBlock)callback) {
+7
View File
@@ -248,6 +248,13 @@
(log/debug "[native-module] hash-message")
(.hashMessage ^js (status) message callback))
(defn local-pairing-preflight-outbound-check
"Checks whether the device has allows connecting to the local server"
[callback]
(log/info "[native-module] Performing local pairing preflight check")
(when platform/ios?
(.localPairingPreflightOutboundCheck ^js (status) callback)))
(defn get-connection-string-for-bootstrapping-another-device
"Generates connection string form status-go for the purpose of local pairing on the sender end"
[config-json callback]
@@ -4,7 +4,7 @@
(def container
{:height 40
:background-color colors/primary-50-opa-20
:background-color (colors/custom-color :blue 50 20)
:flex-direction :row
:align-items :center
:padding-right 22
+1 -1
View File
@@ -27,4 +27,4 @@
[rn/view
{:accessibility-label :pins-count
:style style/counter}
(when (> pins-count 1) [counter/counter {:type :secondary} pins-count])]]))
[counter/counter {:type :secondary} pins-count]]]))
+6 -9
View File
@@ -26,8 +26,9 @@
value]
(let [type (or type :default)
text-color (or override-text-color
(if (or (= (theme/get-theme) :dark)
(= type :default))
(if (or
(= (theme/get-theme) :dark)
(= type :default))
colors/white
colors/neutral-100))
value (utils.number/parse-int value)
@@ -51,20 +52,16 @@
style)
(= type :outline)
(merge {:border-width 1
:border-color (colors/get-color :yin-yang (theme/get-theme))})
:border-color (get-color type)})
(not= type :outline)
(assoc :background-color
(or override-bg-color
(colors/get-color :yin-yang (theme/get-theme))))
(get-color type)))
(> value max-value)
(assoc :padding-left 0.5))}
[text/text
{:weight :medium
:size :label
:style {:color (colors/get-secondary-color
:yin-yang
(theme/get-theme)
colors/white)}}
label]]))
:style {:color text-color}} label]]))
@@ -50,8 +50,23 @@
:label "a sample label"
:right-icon :i/friend
:accessibility-label :first-element}]]])
(h/is-truthy (h/get-by-label-text "right-icon-for-action"))
(h/is-truthy (h/query-by-label-text "left-icon-for-action")))
(h/is-truthy (h/query-by-label-text :right-icon-for-action))
(h/is-truthy (h/query-by-label-text :left-icon-for-action)))
(h/test "renders right text besides icon when non-nil"
(h/render [action-drawer/action-drawer
[[{:icon :i/friend
:label "a sample label"
:right-text "20+"
:right-icon :i/friend}]]])
(h/is-truthy (h/query-by-label-text :right-text-for-action)))
(h/test "does not render right text when not present"
(h/render [action-drawer/action-drawer
[[{:icon :i/friend
:label "a sample label"
:right-icon :i/friend}]]])
(h/is-null (h/query-by-label-text :right-text-for-action)))
(h/test "renders a divider when the add-divider? prop is true"
(h/render [action-drawer/action-drawer
@@ -34,8 +34,17 @@
{:flex 1
:justify-content :center})
(def right-side-container
{:flex-direction :row
:align-items :center})
(def right-icon
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20})
(defn right-text
[override-theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
:margin-right 12})
@@ -11,7 +11,7 @@
colors/danger-60
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)))
(defn divider
(defn- divider
[]
[rn/view
{:style (style/divider)
@@ -29,6 +29,7 @@
label
sub-label
right-icon
right-text
danger?
disabled?
on-press
@@ -70,14 +71,22 @@
:style {:color
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)}}
sub-label])]
(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}]])]]]))
(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}]])])]]]))
(defn action-drawer
[sections]
@@ -5,7 +5,8 @@
(h/describe "Profile Input"
(h/test "renders user avatar with placeholder name if no value is specified"
(h/render [profile-input/profile-input
{:placeholder "Your Name"}])
{:placeholder "Your Name"
:image-picker-props {:full-name "Your Name"}}])
(-> (js/expect (h/get-by-text "YN"))
(.toBeTruthy)))
@@ -6,7 +6,6 @@
[quo2.components.inputs.title-input.view :as title-input]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.hole-view :as hole-view]))
(defn profile-input
@@ -15,49 +14,42 @@
on-press
title-input-props
image-picker-props]}]
(let [full-name (:full-name image-picker-props)]
[rn/view
{:style (style/container customization-color)}
[rn/view
(if platform/ios?
[hole-view/hole-view
{:holes [{:x 33
:y 24
:width 24
:height 24
:borderRadius 12}]}
[user-avatar/user-avatar
(assoc image-picker-props
:customization-color customization-color
:full-name (if (seq full-name)
full-name
placeholder)
:status-indicator? false
:size :medium)]]
[user-avatar/user-avatar
(assoc image-picker-props
:customization-color customization-color
:full-name (if (seq full-name)
full-name
placeholder)
:status-indicator? false
:size :medium)])
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
:override-theme :dark
: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]]
[rn/view {:style style/input-container}
[title-input/title-input
(merge title-input-props
{:blur? true
:override-theme :dark
:placeholder placeholder
:customization-color customization-color})]]]))
[rn/view
{:style (style/container customization-color)}
[rn/view
[hole-view/hole-view
;; Force re-render hole view when props are changed
;; https://github.com/status-im/status-mobile/issues/15577
{:key (hash
(if (:profile-picture image-picker-props)
(:profile-picture image-picker-props)
image-picker-props))
:holes [{:x 33
:y 24
:width 24
:height 24
:borderRadius 12}]}
[user-avatar/user-avatar
(assoc image-picker-props
:static? true
:status-indicator? false
:size :medium)]]
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
:override-theme :dark
: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]]
[rn/view {:style style/input-container}
[title-input/title-input
(merge title-input-props
{:blur? true
:override-theme :dark
:placeholder placeholder
:customization-color customization-color})]]])
+61 -54
View File
@@ -8,58 +8,65 @@
[react-native.core :as rn]
[quo2.components.common.unread-grey-dot.view :refer [unread-grey-dot]]))
(def ^:private custom-props
[:name :locked? :mentions-count :unread-messages?
:muted? :is-active-channel? :emoji :channel-color])
(defn list-item
[{:keys [name locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color on-press]
:or {channel-color colors/primary-50}}]
[rn/touchable-opacity {:on-press on-press}
[rn/view
{:style (merge {:height 48
:display :flex
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
(when is-active-channel?
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
[rn/view
{:display :flex
:flex-direction :row
:justify-content :flex-start
:align-items :center
:accessible true
:accessibility-label :chat-name-text}
[channel-avatar/channel-avatar
{:big? true
:locked? locked?
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
:emoji emoji}]
[quo2.text/text
{:style (merge {:margin-left 12}
(when (and (not locked?) muted?)
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
:weight :medium
:size :paragraph-1} (str "# " name)]]
[rn/view
{:style {:height 20
:justify-content :center}}
(when (and (not locked?)
muted?)
[quo2.icons/icon :i/muted
{:size 20
:no-color true}])
(when (and (not locked?)
(not muted?)
(pos? (int mentions-count)))
[rn/view
{:style {:margin-right 2
:margin-top 2}}
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
(when (and (not locked?)
(not muted?)
(not (pos? (int mentions-count)))
unread-messages?)
[unread-grey-dot :unviewed-messages-public])]]])
[{:keys [locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color]
:or {channel-color colors/primary-50}
:as props}]
(let [standard-props (apply dissoc props custom-props)
name-text (:name props)]
[rn/touchable-opacity standard-props
[rn/view
{:style (merge {:height 48
:display :flex
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
(when is-active-channel?
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
[rn/view
{:display :flex
:flex-direction :row
:justify-content :flex-start
:align-items :center
:accessible true
:accessibility-label :chat-name-text}
[channel-avatar/channel-avatar
{:big? true
:locked? locked?
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
:emoji emoji}]
[quo2.text/text
{:style (merge {:margin-left 12}
(when (and (not locked?) muted?)
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
:weight :medium
:size :paragraph-1} (str "# " name-text)]]
[rn/view
{:style {:height 20
:justify-content :center}}
(when (and (not locked?)
muted?)
[quo2.icons/icon :i/muted
{:size 20
:no-color true}])
(when (and (not locked?)
(not muted?)
(pos? (int mentions-count)))
[rn/view
{:style {:margin-right 2
:margin-top 2}}
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
(when (and (not locked?)
(not muted?)
(not (pos? (int mentions-count)))
unread-messages?)
[unread-grey-dot :unviewed-messages-public])]]]))
@@ -0,0 +1,58 @@
(ns quo2.components.settings.settings-list.component-spec
(:require [quo2.components.settings.settings-list.view :as settings-list]
[test-helpers.component :as h]))
(h/describe "Settings list tests"
(h/test "Default render of Setting list component"
(h/render [settings-list/settings-list {:accessibility-label "test"}])
(h/is-truthy (h/get-by-label-text :test)))
(h/test "It renders a title"
(h/render [settings-list/settings-list {:title "test"}])
(h/is-truthy (h/get-by-text "test")))
(h/test "its gets passed an on press event"
(let [event (h/mock-fn)]
(h/render [settings-list/settings-list
{:title "test"
:on-press event}])
(h/fire-event :press (h/get-by-text "test"))
(h/was-called event)))
(h/test "on change event gets fired for toggle"
(let [on-change (h/mock-fn)]
(h/render [settings-list/settings-list
{:title "test"
:toggle-props {:on-change on-change}}])
(h/fire-event :press (h/get-by-label-text :toggle-off))
(h/was-called on-change)))
(h/test "It renders a badge"
(h/render [settings-list/settings-list {:badge? true}])
(h/is-truthy (h/get-by-label-text :setting-list-badge)))
(h/test "It renders a status tag component"
(h/render [settings-list/settings-list
{:status-tag-props
{:size :small
:status {:type :positive}
:label "test tag"}}])
(h/is-truthy (h/get-by-text "test tag")))
(h/test "on press event gets fired for button"
(let [event (h/mock-fn)]
(h/render [settings-list/settings-list
{:button-props {:title "test button"
:on-press event}}])
(h/fire-event :press (h/get-by-text "test button"))
(h/was-called event)))
(h/test "It renders a list of community icons"
(h/render [settings-list/settings-list
{:communities-props {:data
[{:source "1"
:accessibility-label :community-1}
{:source "2"
:accessibility-label :community-2}]}}])
(h/is-truthy (h/get-by-label-text :community-1))
(h/is-truthy (h/get-by-label-text :community-2))))
@@ -5,42 +5,51 @@
{:flex 1})
(defn title
[]
[override-theme]
{:color (colors/theme-colors
colors/neutral-100
colors/white)})
colors/white
override-theme)})
(def icon
{:margin-right 12})
{:margin-right 12
:align-self :flex-start})
(def item-container
{:justify-content :space-between
:height 48
:flex-direction :row
:align-items :center
:padding-horizontal 12
:padding-vertical 13})
(def inner-container
{:flex-direction :row
:align-items :center})
(defn dot
[]
[override-theme]
{:width 15
:height 15
:border-radius 8
:margin-right 14.5
:background-color (colors/theme-colors (colors/custom-color :blue 50)
(colors/custom-color :blue 60))})
(colors/custom-color :blue 60)
override-theme)})
(defn community-icon
[index]
[index override-theme]
{:width 24
:height 24
:border-width 1
:border-color (colors/theme-colors colors/white colors/black)
:border-color (colors/theme-colors colors/white colors/black override-theme)
:border-radius 12
:position :absolute
:top "-50%"
:right (* 20 index)})
(def communities-container
{:flex 1
:margin-right 12})
{:flex 1
:justify-content :center
:align-content :center
:margin-right 12})
(def tag-container
{:margin-top 8})
@@ -4,30 +4,36 @@
[quo2.components.selectors.selectors.view :as selectors]
[quo2.components.buttons.button :as button]
[quo2.components.markdown.text :as text]
[quo2.components.tags.status-tags :as status-tag]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(defn settings-title
[title]
[title status-tag-props override-theme]
[rn/view
{:style style/title-container}
[text/text
{:accessibility-label :setting-item-name-text
:ellipsize-mode :tail
:style (style/title)
:number-of-lines 1
:weight :medium
:size :paragraph-1}
title]])
(when title
[text/text
{:accessibility-label :setting-item-name-text
:ellipsize-mode :tail
:style (style/title override-theme)
:override-theme override-theme
:number-of-lines 1
:weight :medium
:size :paragraph-1}
title])
(when status-tag-props
[rn/view {:style style/tag-container}
[status-tag/status-tag
status-tag-props]])])
(defn browser-context-icon
[]
[rn/view
[icons/icon :browser-context
{:container-style style/icon
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}]])
(defn left-icon-comp
[icon]
[rn/view {:style style/icon}
[icons/icon icon
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}]])
(def chevron-icon
[rn/view
@@ -43,22 +49,28 @@
{:checked? checked?
:on-change (fn [new-value] (on-change new-value))}])
(def badge-icon
(defn badge-icon
[override-theme]
[rn/view
{:style (style/dot)}])
{:accessible :true
:accessibility-label :setting-list-badge
:style (style/dot override-theme)}])
(defn right-button
[{:keys [title
on-press]}]
on-press]}
override-theme]
[button/button
{:type :outline
:on-press on-press
:size 24}
{:type :outline
:override-theme override-theme
:on-press on-press
:size 24}
title])
(defn communities-icons
[{:keys [data
icon-style]}]
icon-style]}
override-theme]
(let [communities-count (dec (count data))]
[rn/view
{:style style/communities-container}
@@ -70,7 +82,8 @@
{:uri source}
source)
:accessibility-label accessibility-label
:style (merge (style/community-icon (- communities-count index)) icon-style)}])
:style (merge (style/community-icon (- communities-count index) override-theme)
icon-style)}])
data)]))
(defn settings-list
@@ -78,7 +91,7 @@
- `title` String to show in the center of the component, right to the icon and left to optional gadgets.
- `on-press` Callback called when the component is pressed.
- `accessibility-label` String to use as accessibility-label for VoiceOver.
- `left-icon` Symbol to indicate icon type on the left side of the component.
- `left-icon` icon keyword for icon on left.
- `chevron?` Boolean to show/hide chevron at the right border of the component.
- `toggle-prop` Map with the following keys:
`checked?` Boolean value to set check or unchecked toggle.
@@ -89,7 +102,11 @@
`on-press` Callback called when button is pressed.
- `communities-props` Map with the following keys:
`data` Array of maps containg source of the community asset.
- `style` Styles map to be merge with default container styles."
- `style` Styles map to be merge with default container styles.
- `overide-theme` :dark or :light
- `status-tag-props see the spec for status-tag component
"
[{:keys [title
on-press
accessibility-label
@@ -99,21 +116,22 @@
badge?
button-props
communities-props
container-style]}]
container-style
override-theme
status-tag-props]}]
[rn/touchable-without-feedback
{:on-press on-press
:accessibility-label accessibility-label}
[rn/view
{:style (merge style/item-container container-style)}
(case left-icon
;; TODO: Add Icon Avatar on next variants development
:browser-context (browser-context-icon)
nil)
[settings-title title]
(when toggle-props
(toggle-button toggle-props))
(when badge? badge-icon)
(when button-props
(right-button button-props))
(when communities-props (communities-icons communities-props))
(when chevron? chevron-icon)]])
[rn/view {:style style/inner-container}
(when left-icon
[left-icon-comp left-icon])
[settings-title title status-tag-props override-theme]
(when toggle-props
[toggle-button toggle-props])
(when badge? [badge-icon override-theme])
(when button-props
[right-button button-props override-theme])
(when communities-props (communities-icons communities-props override-theme))
(when chevron? chevron-icon)]]])
@@ -2,14 +2,16 @@
(:require
[quo2.foundations.colors :as colors]))
(def title-container
{:justify-content :center
:margin-top 12
:padding-horizontal 20})
(defn title-container
[container-style]
(merge
{:justify-content :center
:padding-horizontal 20}
container-style))
(def title-text
{:color colors/white})
(def subtitle-text
{:color colors/white
:margin-bottom 8})
{:color colors/white
:margin-top 8})
@@ -5,11 +5,12 @@
[react-native.core :as rn]))
(defn title
[{:keys [title
[{:keys [container-style
title
title-accessibility-label
subtitle
subtitle-accessibility-label]}]
[rn/view {:style style/title-container}
[rn/view {:style (style/title-container container-style)}
[text/text
{:accessibility-label title-accessibility-label
:weight :semi-bold
+1
View File
@@ -32,5 +32,6 @@
[quo2.components.selectors.filter.component-spec]
[quo2.components.selectors.reactions.component-spec]
[quo2.components.selectors.selectors.component-spec]
[quo2.components.settings.settings-list.component-spec]
[quo2.components.share.share-qr-code.component-spec]
[quo2.components.tags.--tests--.status-tags-component-spec]))
+38 -105
View File
@@ -186,111 +186,44 @@
;; Colors for customizing profiles and communities themes
(def customization
{:community-color {:main-color {50 "#7140FD"
60 "#5A33CA"}
}
:primary {50 primary-50 ;; User can also use primary color as customisation color
60 primary-60}
:purple {50 "#7140FD"
60 "#5A33CA"}
:indigo {50 "#496289"
60 "#3D5273"}
:turquoise {50 "#2A799B"
60 "#22617C"}
:blue {50 "#2A4AF5"
60 "#223BC4"}
:green {50 "#5BCC95"
60 "#4CAB7D"}
:yellow {50 "#F6B03C"
60 "#C58D30"}
:orange {50 "#FF7D46"
60 "#CC6438"}
:red {50 "#F46666"
60 "#CD5656"}
:pink {50 "#F66F8F"
60 "#C55972"}
:brown {50 "#99604D"
60 "#805141"}
:sky {50 "#1992D7"
60 "#1475AC"}
:army {50 "#216266"
60 "#1A4E52"}
:magenta {50 "#EC266C"
60 "#BD1E56"}
:copper {50 "#CB6256"
60 "#A24E45"}
:camel {50 "#C78F67"
60 "#9F7252"}
:yin {50 "#09101C"
60 "#1D232E"}
:yang {50 "#FFFFFF"
60 "#EBEBEB"}
:beige {50 "#CAAE93"
60 "#AA927C"}})
;; TODO: rename
(def customization-colors-map
{:primary {:primary-color {:light primary-50 :dark primary-60}
:secondary-color nil}
:purple {:primary-color {:light "#7140FD" :dark "#5A33CA"}
:secondary-color nil}
:indigo {:primary-color {:light "#496289" :dark "#3D5273"}
:secondary-color nil}
:turquoise {:primary-color {:light "#2A799B" :dark "#22617C"}
:secondary-color nil}
:blue {:primary-color {:light "#2A4AF5" :dark "#223BC4"}
:secondary-color nil}
:green {:primary-color {:light "#5BCC95" :dark "#4CAB7D"}
:secondary-color nil}
:yellow {:primary-color {:light "#F6B03C" :dark "#C58D30"}
:secondary-color nil}
:orange {:primary-color {:light "#FF7D46" :dark "#CC6438"}
:secondary-color nil}
:red {:primary-color {:light "#F46666" :dark "#CD5656"}
:secondary-color nil}
:pink {:primary-color {:light "#F66F8F" :dark "#C55972"}
:secondary-color nil}
:brown {:primary-color {:light "#99604D" :dark "#805141"}
:secondary-color nil}
:sky {:primary-color {:light "#1992D7" :dark "#1475AC"}
:secondary-color nil}
:army {:primary-color {:light "#216266" :dark "#1A4E52"}
:secondary-color nil}
:magenta {:primary-color {:light "#EC266C" :dark "#BD1E56"}
:secondary-color nil}
:copper {:primary-color {:light "#CB6256" :dark "#A24E45"}
:secondary-color nil}
:camel {:primary-color {:light "#C78F67" :dark "#9F7252"}
:secondary-color nil}
:beige {:primary-color {:light "#CAAE93" :dark "#AA927C"}
:secondary-color nil}
;;
:yin-yang {:primary-color {:light "#09101C" :dark "#EBEBEB"}
:secondary-color {:light "#FFFFFF" :dark neutral-100}}
;;
#_#_:purple {:light {:main "#7140FD" :secondary nil}
:dark {:main "#5A33CA" :secondary nil}}
#_#_:yin-yang {:light {:main "#09101C"
:dark "#1D232E"}
:dark {:main "#FFFFFF"
:dark "#EBEBEB"}}
})
(defn get-color [color-kw theme]
(get-in customization-colors-map [color-kw :primary-color theme]))
(defn get-secondary-color [color-kw theme default-value]
(if-let [secondary-color (get-in customization-colors-map
[color-kw
:secondary-color
theme])]
secondary-color
default-value))
{:primary {50 primary-50 ;; User can also use primary color as customisation color
60 primary-60}
:purple {50 "#7140FD"
60 "#5A33CA"}
:indigo {50 "#496289"
60 "#3D5273"}
:turquoise {50 "#2A799B"
60 "#22617C"}
:blue {50 "#2A4AF5"
60 "#223BC4"}
:green {50 "#5BCC95"
60 "#4CAB7D"}
:yellow {50 "#F6B03C"
60 "#C58D30"}
:orange {50 "#FF7D46"
60 "#CC6438"}
:red {50 "#F46666"
60 "#CD5656"}
:pink {50 "#F66F8F"
60 "#C55972"}
:brown {50 "#99604D"
60 "#805141"}
:sky {50 "#1992D7"
60 "#1475AC"}
:army {50 "#216266"
60 "#1A4E52"}
:magenta {50 "#EC266C"
60 "#BD1E56"}
:copper {50 "#CB6256"
60 "#A24E45"}
:camel {50 "#C78F67"
60 "#9F7252"}
:yin {50 "#09101C"
60 "#1D232E"}
:yang {50 "#FFFFFF"
60 "#EBEBEB"}
:beige {50 "#CAAE93"
60 "#AA927C"}})
(def colors-map
(merge {:danger {50 danger-50
+9 -12
View File
@@ -104,7 +104,6 @@
:emoji-id emoji-id
:from from})
(defn- format-response
[response]
(->> (transforms/js->clj response)
@@ -113,24 +112,22 @@
(rf/defn save-emoji-reaction-details
{:events [:chat/save-emoji-reaction-details]}
[{:keys [db]} message-reactions long-pressed-emoji]
{:db (assoc db
:chat/reactions-authors
{:reaction-authors-list message-reactions
:selected-reaction long-pressed-emoji})})
[{:keys [db]} reaction-authors]
{:db (assoc db :chat/reactions-authors reaction-authors)})
(rf/defn clear-emoji-reaction-details
{:events [:chat/clear-emoji-reaction-author-details]}
[{:keys [db]} message-reactions]
{:db (update db dissoc :chat/reactions-authors)})
[{:keys [db]}]
{:db (dissoc db :chat/reactions-authors)})
(rf/defn emoji-reactions-by-message-id
{:events [:chat.ui/emoji-reactions-by-message-id]}
[{:keys [db]} {:keys [message-id long-pressed-emoji]}]
{:json-rpc/call [{:method "wakuext_emojiReactionsByChatIDMessageID"
[{:keys [db]} {:keys [message-id on-success]}]
{:db (dissoc db :chat/reactions-authors)
:json-rpc/call [{:method "wakuext_emojiReactionsByChatIDMessageID"
:params [(:current-chat-id db) message-id]
:js-response true
:on-error #(log/error "failed to fetch emoji reaction by message-id: "
{:message-id message-id :error %})
:on-success #(rf/dispatch [:chat/save-emoji-reaction-details
(format-response %) long-pressed-emoji])}]})
:on-success #(when on-success
(on-success (format-response %)))}]})
+1 -1
View File
@@ -126,7 +126,7 @@
(not (:mailserver/current-request db)))
{:db (assoc db :mailserver/current-request true)
:json-rpc/call [{:method "wakuext_requestAllHistoricMessagesWithRetries"
:params []
:params [false]
:js-response true
:on-success #(do
(log/info "fetched historical messages")
+19 -9
View File
@@ -10,7 +10,8 @@
[utils.re-frame :as rf]
[status-im2.contexts.chat.messages.link-preview.events :as link-preview]
[taoensso.timbre :as log]
[status-im2.constants :as constants]))
[status-im2.constants :as constants]
[quo2.foundations.colors :as colors]))
(rf/defn status-node-started
[{db :db :as cofx} {:keys [error]}]
@@ -55,7 +56,7 @@
:peers-count (count (:peers peer-stats)))}))
(rf/defn handle-local-pairing-signals
[{:keys [db] :as cofx} {:keys [type action data] :as event}]
[{:keys [db] :as cofx} {:keys [type action data error] :as event}]
(log/info "local pairing signal received"
{:event event})
(let [{:keys [account password]} data
@@ -78,7 +79,7 @@
(and (some? account) (some? password)))
multiaccount-data (when received-account?
(merge account {:password password}))
navigate-to-syncing-devices? (and connection-success? receiver?)
navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?)
user-in-syncing-devices-screen? (= (:view-id db) :syncing-progress)]
(merge {:db (cond-> db
connection-success?
@@ -92,12 +93,21 @@
completed-pairing?
(assoc-in [:syncing :pairing-status] :completed))}
(when (and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch [:navigate-to :syncing-progress]})
(when (and completed-pairing? sender?)
{:dispatch [:syncing/clear-states]})
(when (and completed-pairing? receiver?)
{:dispatch [:multiaccounts.login/local-paired-user]}))))
(cond
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch [:navigate-to :syncing-progress]}
(and completed-pairing? sender?)
{:dispatch [:syncing/clear-states]}
(and completed-pairing? receiver?)
{:dispatch [:multiaccounts.login/local-paired-user]}
(and error-on-pairing? (some? error))
{:dispatch [:toasts/upsert
{:icon :i/alert
:icon-color colors/danger-50
:text error}]}))))
(rf/defn process
{:events [:signals/signal-received]}
@@ -84,16 +84,15 @@
(rf/defn handle-navigation-to-desktop-community-from-mobile
{:events [:handle-navigation-to-desktop-community-from-mobile]}
[{:keys [db]} cofx deserialized-key]
(navigation/navigate-to cofx :community {:community-id deserialized-key}))
[cofx deserialized-key]
(navigation/navigate-to cofx :community-overview deserialized-key))
(rf/defn handle-desktop-community
[cofx {:keys [community-id]}]
(native-module/deserialize-and-compress-key
community-id
(fn [deserialized-key]
(rf/dispatch [:handle-navigation-to-desktop-community-from-mobile cofx (str deserialized-key)]))))
(rf/dispatch [:handle-navigation-to-desktop-community-from-mobile (str deserialized-key)]))))
(rf/defn handle-community-chat
[cofx {:keys [chat-id]}]
@@ -1,4 +1,4 @@
(ns status-im2.common.bottom-sheet.styles
(ns status-im2.common.bottom-sheet.style
(:require [quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[status-im.utils.platform :as platform]))
@@ -25,7 +25,7 @@
:border-top-right-radius 20
:overflow (when shell? :hidden)
:flex 1
:padding-bottom (or padding-bottom-override (max 20 bottom))
:padding-bottom (or padding-bottom-override (+ bottom 8))
:background-color (if shell?
:transparent
(colors/theme-colors colors/white colors/neutral-90 override-theme))})
+9 -9
View File
@@ -3,7 +3,7 @@
[react-native.core :as rn]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[status-im2.common.bottom-sheet.styles :as styles]
[status-im2.common.bottom-sheet.style :as style]
[react-native.gesture :as gesture]
[oops.core :as oops]
[react-native.hooks :as hooks]
@@ -80,20 +80,20 @@
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
(styles/sheet insets
window-height
override-theme
padding-bottom-override
shell?))
(style/sheet insets
window-height
override-theme
padding-bottom-override
shell?))
:on-layout #(reset! sheet-height (oops/oget % "nativeEvent" "layout" "height"))}
(when shell? [blur/ios-view {:style styles/shell-bg}])
(when shell? [blur/ios-view {:style style/shell-bg}])
(when selected-item
[rn/view
[rn/view {:style (styles/selected-item override-theme window-height @sheet-height insets)}
[rn/view {:style (style/selected-item override-theme window-height @sheet-height insets)}
[selected-item]]])
;; handle
[rn/view {:style (styles/handle override-theme)}]
[rn/view {:style (style/handle override-theme)}]
;; content
[content]]]]))))
+12 -8
View File
@@ -1,12 +1,13 @@
(ns status-im2.common.home.actions.view
(:require [utils.i18n :as i18n]
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
[status-im2.common.confirmation-drawer.view :as confirmation-drawer]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[status-im2.contexts.contacts.drawers.nickname-drawer.view :as nickname-drawer]
[clojure.string :as string]
[quo2.foundations.colors :as colors]))
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- entry
[{:keys [icon label on-press danger? sub-label chevron? add-divider? accessibility-label]}]
@@ -462,12 +463,15 @@
(remove-from-group-entry contact chat-id))])]]))
(defn chat-actions
[{:keys [chat-type] :as item} inside-chat?]
(case chat-type
[{:keys [chat-type] :as chat} inside-chat?]
(condp = chat-type
constants/one-to-one-chat-type
[one-to-one-actions item inside-chat?]
[one-to-one-actions chat inside-chat?]
constants/private-group-chat-type
[private-group-chat-actions item inside-chat?]))
[private-group-chat-actions chat inside-chat?]
constants/community-chat-type
[chat-actions/actions chat inside-chat?]
nil))
(defn group-details-actions
[{:keys [admins] :as group}]
@@ -6,3 +6,7 @@
(when content
[rn/view {:border-color :red :border-width 1}
content]))
(defn alert
[]
(js/alert "Feature not implemented."))
-29
View File
@@ -1,29 +0,0 @@
(ns status-im2.common.syncing.style
(:require [quo2.foundations.colors :as colors]))
(def device-container
{:padding-top 12
:padding-horizontal 12
:padding-bottom 16
:border-color colors/white-opa-5
:border-radius 16
:border-width 1
:margin-bottom 24})
(def device-container-orientation
{:flex-direction :row})
(def icon-container
{:height 20
:margin-right 12})
(def tag-container
{:margin-top 8})
(def render-device-status
{:background-color colors/success-60
:align-self :center
:width 8
:height 8
:border-radius 4
:margin-right 6})
-51
View File
@@ -1,51 +0,0 @@
(ns status-im2.common.syncing.view
[:require
[quo2.core :as quo]
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.common.not-implemented :as not-implemented]
[status-im2.common.syncing.style :as style]])
;; TODO replace with section list component
;; https://github.com/status-im/status-mobile/issues/15665
(defn view
[{:keys [name
this-device?
device-type]}]
[rn/view {:style style/device-container}
[rn/view {:style style/device-container-orientation}
[rn/view {:style style/icon-container}
[quo/icon
(if (= device-type :mobile) :i/mobile :i/desktop)
{:color colors/white}]]
[rn/view
[quo/text
{:accessibility-label :device-name
:weight :medium
:size :paragraph-1
:style {:color colors/white}}
name]
(when this-device?
[not-implemented/not-implemented
[quo/text
{:accessibility-label :next-back-up
:size :paragraph-2
:style {:color colors/white-opa-40}}
"Next backup in 04:36:12"]])
(when this-device?
[rn/view {:style style/tag-container}
[quo/status-tag
{:size :small
:status {:type :positive}
:no-icon? true
:label (i18n/label :t/this-device)
:override-theme :dark}]])
(when-not this-device?
[rn/view {:style {:flex-direction :row}}
[rn/view style/render-device-status]
[quo/text
{:accessibility-label :next-back-up
:size :paragraph-2
:style {:color colors/white-opa-40}}
(i18n/label :t/online-now)]])]]])
+2
View File
@@ -331,3 +331,5 @@
(def ^:const auth-method-biometric "biometric")
(def ^:const auth-method-biometric-prepare "biometric-prepare")
(def ^:const auth-method-none "none")
(def ^:const image-description-in-lightbox? false)
@@ -109,3 +109,19 @@
:blur-radius (if platform/ios? 20 10)
:blur-type (colors/theme-colors :light :dark)
:blur-amount 20})
(defn shell-container
[bottom translate-y]
(reanimated/apply-animations-to-style
{:bottom bottom ; we use height of the input directly as bottom position
:transform [{:translate-y translate-y}]}
{:position :absolute
:left 0
:right 0}))
(defn shell-button
[translate-y opacity]
(reanimated/apply-animations-to-style
{:transform [{:translate-y translate-y}]
:opacity opacity}
{}))
@@ -26,34 +26,35 @@
[:f> f-blur-view layout-height focused?])
(defn- f-shell-button
[{:keys [maximized?]} {:keys [height]} {:keys [images link-previews? reply edit]}]
[{:keys [maximized? focused?]} {:keys [height]} {:keys [reply edit]}]
(let [insets (safe-area/get-insets)
extra-height (utils/calc-top-content-height reply edit)
translate-y (reanimated/use-shared-value
(utils/calc-shell-neg-y insets maximized? extra-height))]
neg-y (utils/calc-shell-neg-y insets maximized? extra-height)
y-container (reanimated/use-shared-value neg-y)
hide-shell? (or @focused? @messages.list/show-floating-scroll-down-button)
y-shell (reanimated/use-shared-value (if hide-shell? 35 0))
opacity (reanimated/use-shared-value (if hide-shell? 0 1))]
(rn/use-effect
(fn []
(let [extra-height (utils/calc-top-content-height reply edit)]
(reanimated/animate translate-y
(utils/calc-shell-neg-y insets maximized? extra-height))))
[@maximized? images link-previews? reply edit])
(reanimated/animate opacity (if hide-shell? 0 1))
(reanimated/animate y-shell (if hide-shell? 35 0)))
[@focused? @messages.list/show-floating-scroll-down-button])
(rn/use-effect #(reanimated/animate y-container neg-y) [reply edit])
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:bottom height ; we use height of the input directly as bottom position
:transform [{:translate-y translate-y}]} ; translate down when maximized
{:position :absolute
:left 0
:right 0})}
{:style (style/shell-container height y-container)}
[reanimated/view
{:style (style/shell-button y-shell opacity)}
[quo/floating-shell-button
{:jump-to
{:on-press (fn []
(rf/dispatch [:chat/close true])
(rf/dispatch [:shell/navigate-to-jump-to]))
:label (i18n/label :t/jump-to)
:style {:align-self :center}}} {}]]
[quo/floating-shell-button
(merge {:jump-to
{:on-press (fn []
(rf/dispatch [:chat/close true])
(rf/dispatch [:shell/navigate-to-jump-to]))
:label (i18n/label :t/jump-to)
:style {:align-self :center}}}
(when @messages.list/show-floating-scroll-down-button
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}}))
{}]]))
(when @messages.list/show-floating-scroll-down-button
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}})
{:bottom 24}]]))
(defn shell-button
[state animations subs]
@@ -4,6 +4,7 @@
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[utils.i18n :as i18n]
@@ -131,7 +132,7 @@
:background-y background-y}
props (utils/init-props)
state (utils/init-state)]
[rn/view
[rn/view (when platform/ios? {:style {:z-index 1}})
[reanimated/view {:style (style/background opacity background-y window-height)}]
[sub-view/blur-view blur-height (:focused? state)]
[:f> sheet-component extra-params props state]]))
@@ -152,10 +152,9 @@
(preview-text-from-content group-chat primary-name message)))]
[quo/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50
colors/neutral-40)
:flex 1
:margin-right 20}
:style {:color (colors/theme-colors colors/neutral-50
colors/neutral-40)
:flex 1}
:number-of-lines 1
:ellipsize-mode :tail
:accessibility-label :chat-message-text}
@@ -179,10 +178,15 @@
(defn name-view
[display-name contact timestamp]
[rn/view {:style {:flex-direction :row}}
[rn/view
{:style {:flex 1
:flex-direction :row}}
[quo/text
{:weight :semi-bold
:accessibility-label :chat-name-text}
:accessibility-label :chat-name-text
:style {:flex-shrink 1}
:number-of-lines 1
:ellipsize-mode :tail}
display-name]
[verified-or-contact-icon contact]
[quo/text
@@ -209,11 +213,12 @@
[{:keys [chat-id group-chat color name unviewed-messages-count
timestamp last-message muted]
:as item}]
(let [display-name (if group-chat
name
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id])))
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))]
(let [display-name (if group-chat
name
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id])))
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
show-unread-badge? (and (not muted) (> unviewed-messages-count 0))]
[rn/touchable-opacity
{:style (style/container)
:on-press (open-chat chat-id)
@@ -224,10 +229,14 @@
:chat-id chat-id
:full-name display-name
:color color}]
[rn/view {:style {:margin-left 8}}
[rn/view
{:style {:flex 1
:margin-left 8
:margin-right (if show-unread-badge? 36 0)}}
[name-view display-name contact timestamp]
[last-message-preview group-chat last-message]]
(when-not muted
(when (> unviewed-messages-count 0)
[quo/info-count {:style {:top 16}}
unviewed-messages-count]))]))
(when show-unread-badge?
[quo/info-count
{:style {:top 16
:right 16}}
unviewed-messages-count])]))
@@ -6,7 +6,8 @@
[status-im2.contexts.chat.lightbox.style :as style]
[utils.re-frame :as rf]
[status-im2.contexts.chat.lightbox.animations :as anim]
[status-im2.contexts.chat.lightbox.constants :as c]))
[status-im2.contexts.chat.lightbox.constants :as c]
[status-im2.constants :as constants]))
(defn get-small-item-layout
[_ index]
@@ -56,7 +57,8 @@
:start {:x 0 :y 1}
:end {:x 0 :y 0}
:style (style/gradient-container insets animations derived)}
[rn/text {:style style/text-style} text]
(when constants/image-description-in-lightbox?
[rn/text {:style style/text-style} text])
[rn/flat-list
{:ref #(reset! (:small-list-ref props) %)
:key-fn :message-id
@@ -2,7 +2,7 @@
(:require [quo2.foundations.colors :as colors]))
(def system-message-default-size 36)
(def system-message-radius (/ system-message-default-size 2))
(def system-message-margin-right 8)
(def pin-indicator-container
{:margin-top 4
@@ -26,7 +26,7 @@
(def system-message-inner-container
{:width system-message-default-size
:height system-message-default-size
:margin-right system-message-radius
:margin-right system-message-margin-right
:border-radius system-message-default-size
:justify-content :center
:align-items :center
@@ -17,25 +17,23 @@
:emoji-id emoji-id}])))
(defn- on-long-press
[message-id emoji-id]
[message-id emoji-id user-message-content reactions]
(rf/dispatch [:chat.ui/emoji-reactions-by-message-id
{:message-id message-id
:long-pressed-emoji emoji-id}]))
(defn show-authors-sheet
[user-message-content reactions]
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch
[:show-bottom-sheet
{:on-close (fn []
(rf/dispatch
[:chat/clear-emoji-reaction-author-details]))
:content (fn []
[drawers/reaction-authors
(map :emoji-id reactions)])
:selected-item (fn []
user-message-content)
:padding-bottom-override 0}]))
{:message-id message-id
:on-success (fn [response]
(rf/dispatch [:chat/save-emoji-reaction-details
{:reaction-authors-list response
:selected-reaction emoji-id}])
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:show-bottom-sheet
{:on-close (fn []
(rf/dispatch
[:chat/clear-emoji-reaction-author-details]))
:content (fn []
[drawers/reaction-authors reactions])
:selected-item (fn []
user-message-content)
:padding-bottom-override 0}]))}]))
(defn message-reactions-row
[{:keys [message-id chat-id]} user-message-content]
@@ -55,11 +53,10 @@
:neutral? own
:clicks quantity
:on-press #(on-press own message-id emoji-id emoji-reaction-id)
:on-long-press (fn []
(on-long-press message-id
emoji-id)
(show-authors-sheet user-message-content
reactions))
:on-long-press #(on-long-press message-id
emoji-id
user-message-content
(map :emoji-id reactions))
:accessibility-label (str "emoji-reaction-" emoji-id)}]])
[quo/add-reaction
{:on-press (fn []
@@ -112,7 +112,7 @@
(js/setTimeout #(reset! show-delivery-state? false)
delivery-state-showing-time-ms))))
:on-long-press #(on-long-press message-data context keyboard-shown?)}
[rn/view {:style {:padding-vertical 8}}
[rn/view {:style {:padding-vertical 4}}
(when (and (seq response-to) quoted-message)
[reply/quoted-message quoted-message])
[rn/view
@@ -291,10 +291,9 @@
colors/neutral-95))}
:inverted true
:on-layout (fn [e]
(when platform/android?
;; FIXME: this is due to Android not triggering the initial
;; scrollTo event
(scroll-to-offset 1))
;; FIXME: this is due to Android not triggering the initial
;; scrollTo event
(scroll-to-offset 1)
(let [layout-height (oops/oget e "nativeEvent.layout.height")]
(reset! messages-view-height layout-height)))
:scroll-enabled (not recording?)}]]))
@@ -326,7 +325,7 @@
:keyboard-shown? keyboard-shown}]
(when footer-comp
(footer-comp {:insets insets}))]))
[footer-comp {:insets insets}])]))
(defn messages-list
[props]
@@ -76,19 +76,6 @@
:opacity opacity-animation})
header))
(def pinned-banner
{:position :absolute
:left 0
:right 0
:top navigation-bar-height})
(defn animated-pinned-banner
[enabled? animation]
(reanimated/apply-animations-to-style
(when enabled?
{:opacity animation})
pinned-banner))
(def header-content-container
{:flex-direction :row
:align-items :center
@@ -4,8 +4,8 @@
[re-frame.db]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.platform :as platform]
[status-im2.contexts.chat.messages.navigation.style :as style]
[status-im2.contexts.chat.messages.pin.banner.view :as pin.banner]
[status-im2.constants :as constants]
@@ -38,7 +38,7 @@
(+ style/navigation-bar-height 100)]
[0 1]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
:extrapolateRight "extend"})
translate-animation (reanimated/interpolate scroll-y
[(+ style/navigation-bar-height 25)
(+ style/navigation-bar-height 100)]
@@ -97,20 +97,21 @@
:size :paragraph-2
:style (style/header-online)}
(i18n/label :t/online)])]]]
(when (not= chat-type constants/community-chat-type)
[rn/touchable-opacity
{:active-opacity 1
:style (style/button-container {:margin-right 20})
:accessibility-label :options-button
:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [actions/chat-actions chat true])}]))}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]])]
[rn/touchable-opacity
{:active-opacity 1
:style (style/button-container {:margin-right 20})
:accessibility-label :options-button
:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [actions/chat-actions chat true])}]))}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]]
[reanimated/view
{:style (style/animated-pinned-banner all-loaded? banner-opacity-animation)}
[pin.banner/banner chat-id]]]]))
[pin.banner/banner
{:chat-id chat-id
:opacity-animation banner-opacity-animation
:all-loaded? all-loaded?
:top-offset style/navigation-bar-height}]]]))
(defn navigation-view
[props]
@@ -0,0 +1,41 @@
(ns status-im2.contexts.chat.messages.pin.banner.style
(:require
[quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]))
(defonce ^:const pinned-banner-height 40)
(defn blur-container-style
[top-offset opacity-animation enabled?]
(reanimated/apply-animations-to-style
{:opacity opacity-animation}
{:position :absolute
:display (if enabled? :flex :none)
:top top-offset
:left 0
:right 0
:bottom 0
:height pinned-banner-height
:overflow :hidden}))
(defn blur-view-style
[]
{:style {:flex 1}
:blur-radius (if platform/ios? 20 10)
:blur-type (colors/theme-colors :light :dark)
:blur-amount 20})
(defn pinned-banner
[top-offset]
{:position :absolute
:left 0
:right 0
:top top-offset})
(defn animated-pinned-banner
[top-offset enabled? animation]
(reanimated/apply-animations-to-style
(when enabled?
{:opacity animation})
(pinned-banner top-offset)))
@@ -1,9 +1,13 @@
(ns status-im2.contexts.chat.messages.pin.banner.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]
[status-im2.constants :as constants]))
[status-im2.contexts.chat.messages.pin.banner.style :as style]
[status-im2.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn message-text
[{:keys [content-type] :as message}]
@@ -12,8 +16,17 @@
:else
(get-in message [:content :parsed-text])))
(defn banner
[chat-id]
(defn f-blur-view
[top-offset opacity-animation enabled?]
[reanimated/view {:style (style/blur-container-style top-offset opacity-animation enabled?)}
[blur/view (style/blur-view-style)]])
(defn blur-view
[top-offset opacity-animation enabled?]
[:f> f-blur-view top-offset opacity-animation enabled?])
(defn f-banner
[{:keys [chat-id opacity-animation all-loaded? top-offset]}]
(let [pinned-message (rf/sub [:chats/last-pinned-message chat-id])
latest-pin-text (message-text pinned-message)
{:keys [deleted? deleted-for-me?]} pinned-message
@@ -28,11 +41,17 @@
(:content-type pinned-message))
(resolver/resolve-message latest-pin-text)
:else latest-pin-text)]
[quo/banner
{:latest-pin-text latest-pin-text
:pins-count pins-count
:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]))}]))
[rn/view
[blur-view top-offset opacity-animation (> pins-count 0)]
[reanimated/view {:style (style/animated-pinned-banner top-offset all-loaded? opacity-animation)}
[quo/banner
{:latest-pin-text latest-pin-text
:pins-count pins-count
:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]))}]]]))
(defn banner
[props]
[:f> f-banner props])
@@ -34,10 +34,9 @@
:header-comp (fn [{:keys [scroll-y]}]
[messages.navigation/navigation-view {:scroll-y scroll-y}])
:footer-comp (fn [{:keys [insets]}]
[rn/view
(if-not able-to-send-message?
[contact-requests.bottom-drawer/view chat-id contact-request-state group-chat]
[:f> composer/composer insets])])}]))
(if-not able-to-send-message?
[contact-requests.bottom-drawer/view chat-id contact-request-state group-chat]
[:f> composer/composer insets]))}]))
(defn chat
[]
@@ -0,0 +1,116 @@
(ns status-im2.contexts.communities.actions.chat.view
(:require [quo2.core :as quo]
[status-im2.common.not-implemented :as not-implemented]
[utils.i18n :as i18n]))
(defn- action-view-members-and-details
[]
{:icon :i/members
:accessibility-label :chat-view-members-and-details
:label (i18n/label :t/view-channel-members-and-details)
:on-press not-implemented/alert})
(defn- action-token-requirements
[]
{:icon :i/token
:right-icon :i/chevron-right
:accessibility-label :chat-view-token-requirements
:on-press not-implemented/alert
:label (i18n/label :t/view-token-gating)})
(defn- action-mark-as-read
[]
{:icon :i/mark-as-read
:right-icon :i/chevron-right
:accessibility-label :chat-mark-as-read
:on-press not-implemented/alert
:label (i18n/label :t/mute-channel)})
(defn- action-toggle-muted
[]
{:icon :i/muted
:right-icon :i/chevron-right
:accessibility-label :chat-toggle-muted
:on-press not-implemented/alert
:label (i18n/label :t/mute-channel)})
(defn- action-notification-settings
[]
{:icon :i/notifications
:right-icon :i/chevron-right
:accessibility-label :chat-notification-settings
:on-press not-implemented/alert
:label (i18n/label :t/notification-settings)
:sub-label (i18n/label :t/only-mentions)})
(defn- action-pinned-messages
[]
{:icon :i/pin
:right-icon :i/chevron-right
:accessibility-label :chat-pinned-messages
:on-press not-implemented/alert
:label (i18n/label :t/pinned-messages)})
(defn- action-fetch-messages
[]
{:icon :i/download
:right-icon :i/chevron-right
:accessibility-label :chat-fetch-messages
:on-press not-implemented/alert
:label (i18n/label :t/fetch-messages)})
(defn- action-invite-people
[]
{:icon :i/add-user
:accessibility-label :chat-invite-people
:on-press not-implemented/alert
:label (i18n/label :t/invite-people-from-contacts)})
(defn- action-qr-code
[]
{:icon :i/qr-code
:accessibility-label :chat-show-qr-code
:on-press not-implemented/alert
:label (i18n/label :t/show-qr)})
(defn- action-share
[]
{:icon :i/share
:accessibility-label :chat-share
:on-press not-implemented/alert
:label (i18n/label :t/share-channel)})
(defn actions
[{:keys [locked?]} inside-chat?]
(cond
locked?
[quo/action-drawer
[[(action-invite-people)
(action-token-requirements)
(action-qr-code)
(action-share)]]]
(and (not inside-chat?) (not locked?))
[quo/action-drawer
[[(action-view-members-and-details)
(action-mark-as-read)
(action-toggle-muted)
(action-notification-settings)
(action-pinned-messages)
(action-invite-people)
(action-qr-code)
(action-share)]]]
(and inside-chat? (not locked?))
[quo/action-drawer
[[(action-view-members-and-details)
(action-token-requirements)
(action-mark-as-read)
(action-toggle-muted)
(action-notification-settings)
(action-fetch-messages)
(action-invite-people)
(action-qr-code)
(action-share)]]]
:else nil))
@@ -1,4 +1,3 @@
(ns status-im2.contexts.communities.actions.community-options.component-spec
(:require [re-frame.core :as re-frame]
[test-helpers.component :as h]
@@ -24,7 +23,7 @@
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :community-notification-settings))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
@@ -50,7 +49,7 @@
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :community-notification-settings))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
@@ -73,7 +72,7 @@
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :community-notification-settings))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
@@ -95,7 +94,7 @@
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :community-notification-settings))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
@@ -56,7 +56,7 @@
[id]
{:icon :i/notifications
:accessibility-label :community-notification-settings
:label (i18n/label :t/community-notification-settings)
:label (i18n/label :t/notification-settings)
:on-press #(js/alert (str "implement action" id))
:right-icon :i/chevron-right})
@@ -1,19 +1,20 @@
(ns status-im2.contexts.communities.overview.view
(:require [utils.i18n :as i18n]
[oops.core :as oops]
(:require [oops.core :as oops]
[quo2.components.navigation.floating-shell-button :as floating-shell-button]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im2.constants :as constants]
[status-im2.common.scroll-page.view :as scroll-page]
[status-im2.contexts.communities.overview.style :as style]
[status-im2.contexts.communities.actions.community-options.view :as options]
[quo2.components.navigation.floating-shell-button :as floating-shell-button]
[status-im2.contexts.communities.overview.utils :as utils]
[status-im2.common.home.actions.view :as actions]
[status-im2.common.password-authentication.view :as password-authentication]
[status-im2.common.scroll-page.view :as scroll-page]
[status-im2.constants :as constants]
[status-im2.contexts.communities.actions.community-options.view :as options]
[status-im2.contexts.communities.overview.style :as style]
[status-im2.contexts.communities.overview.utils :as utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn preview-user-list
@@ -54,37 +55,41 @@
(int (Math/ceil (layout-y %))))
(into #{} (map (comp :name second) channels-list)))
:style {:margin-top 20 :flex 1}}
(map
(fn [[category-id {:keys [chats name collapsed?]}]]
[rn/view
{:flex 1
:key category-id
;; on-layout fires only when the component re-renders, so
;; in case the category hasn't changed, it will not be fired
:on-layout #(on-category-layout name (int (layout-y %)))}
(when-not (= constants/empty-category-id category-id)
[quo/divider-label
{:label name
:on-press #(collapse-category
community-id
category-id
collapsed?)
:chevron-icon (if collapsed? :main-icons/chevron-right :main-icons/chevron-down)
:padding-bottom (if collapsed? 7 0)
:chevron-position :left}])
(when-not collapsed?
[rn/view
{:margin-left 8
:margin-top 10
:margin-bottom 8}
(map (fn [channel]
[rn/view
{:key (:id channel)
:margin-top 4}
[quo/channel-list-item channel]])
chats)])])
channels-list)])
(for [[category-id {:keys [chats name collapsed?]}] channels-list]
[rn/view
{:flex 1
:key category-id
;; on-layout fires only when the component re-renders, so
;; in case the category hasn't changed, it will not be fired
:on-layout #(on-category-layout name (int (layout-y %)))}
(when-not (= constants/empty-category-id category-id)
[quo/divider-label
{:label name
:on-press #(collapse-category
community-id
category-id
collapsed?)
:chevron-icon (if collapsed? :main-icons/chevron-right :main-icons/chevron-down)
:padding-bottom (if collapsed? 7 0)
:chevron-position :left}])
(when-not collapsed?
[rn/view
{:style {:margin-left 8
:margin-top 10
:margin-bottom 8}}
(for [chat chats
:let [chat (assoc chat :chat-type constants/community-chat-type)]]
[rn/view
{:key (:id chat)
:style {:margin-top 4}}
[quo/channel-list-item
(assoc chat
:on-long-press
(fn []
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [actions/chat-actions chat false])
:selected-item (fn []
[quo/channel-list-item chat])}])))]])])])])
(defn request-to-join-text
[is-open?]
@@ -19,9 +19,10 @@
:justify-content :space-between
:margin-top 20})
(def nickname-container
(defn nickname-container
[insets]
{:margin-horizontal 20
:margin-bottom (when platform/ios? 20)})
:margin-bottom (when platform/ios? (max (:bottom insets) 20))})
(defn nickname-description
[]
@@ -4,6 +4,7 @@
[quo2.components.icon :as icons]
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.contacts.drawers.nickname-drawer.style :as style]
[utils.i18n :as i18n]
@@ -28,11 +29,12 @@
(let [{:keys [primary-name nickname public-key]} contact
entered-nickname (reagent/atom (or nickname ""))
photo-path (when-not (empty? (:images contact))
(rf/sub [:chats/photo-path public-key]))]
(rf/sub [:chats/photo-path public-key]))
insets (safe-area/get-insets)]
(fn [{:keys [title description accessibility-label
close-button-text]}]
[rn/view
{:style style/nickname-container
{:style (style/nickname-container insets)
:accessibility-label accessibility-label}
[quo/text
{:weight :semi-bold
@@ -31,7 +31,7 @@
:source (resources/get-image :onboarding-illustration)}])
(defonce progress (atom nil))
(defonce paused (atom nil))
(defonce paused? (atom nil))
(defn store-screen-height
[evt]
@@ -60,14 +60,14 @@
animate? (not dark-overlay?)
window-width (rf/sub [:dimensions/window-width])]
(when animate?
(carousel.animation/use-initialize-animation progress paused animate?))
(carousel.animation/use-initialize-animation progress paused? animate?))
(rn/use-effect
(fn []
(reanimated/set-shared-value @paused (not= view-id :intro))
(reanimated/set-shared-value @paused? (not= view-id :intro))
(fn []
(when (= view-id :generating-keys)
(carousel.animation/cleanup-animation progress paused))))
(carousel.animation/cleanup-animation progress paused?))))
[view-id])
[rn/view
@@ -76,8 +76,10 @@
[carousel/view
{:animate? animate?
:progress progress
:paused? paused?
:header-text header-text
:header-background true
:swipeable? true
:background [background-image (* 4 window-width)]}]
(when dark-overlay?
[blur/view
@@ -2,34 +2,76 @@
(:require
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[utils.worklets.onboarding-carousel :as worklets.onboarding-carousel]))
[utils.worklets.onboarding-carousel :as worklets.onboarding-carousel]
[react-native.gesture :as gesture]
[oops.core :as oops]))
(def ^:const progress-bar-animation-delay 300)
(def ^:const progress-bar-animation-duration 4000)
(def ^:const initial-division-quotient 5)
(def ^:const progress-threshold 25)
(def ^:const drag-limit 100)
(defn slide-animation
[progress-percentage & [delay duration]]
[progress-percentage & [duration]]
(reanimated/with-delay
(or delay progress-bar-animation-delay)
progress-bar-animation-delay
(reanimated/with-timing
progress-percentage
(js-obj "duration" (or duration progress-bar-animation-duration)
"easing" (:linear reanimated/easings)))))
(defn calculate-remainder
[dividend divisor]
(if (and (pos-int? dividend) (zero? (mod dividend divisor)))
divisor
(mod dividend divisor)))
(defn animation-value
[q index]
(let [next-quotient (+ q index)
dividend (if (>= next-quotient initial-division-quotient)
(* (- next-quotient initial-division-quotient) progress-threshold)
(* next-quotient progress-threshold))]
(calculate-remainder dividend drag-limit)))
(defn animate-progress-value
[value]
(if (zero? value) (slide-animation value 0) (slide-animation value)))
(defn animate-progress
[progress paused]
(reanimated/set-shared-value
progress
(reanimated/with-pause
(reanimated/with-repeat
(reanimated/with-sequence
(slide-animation 25)
(slide-animation 50)
(slide-animation 75)
(slide-animation 100)
(slide-animation 0 300 0))
-1)
paused)))
[progress paused next-progress]
(let [q (quot next-progress 25)]
(reanimated/set-shared-value
progress
(reanimated/with-pause
(reanimated/with-repeat
(reanimated/with-sequence
(animate-progress-value (animation-value q 1))
(animate-progress-value (animation-value q 2))
(animate-progress-value (animation-value q 3))
(animate-progress-value (animation-value q 4))
(animate-progress-value (calculate-remainder next-progress drag-limit)))
-1)
paused))))
(defn get-next-progress
[progress]
(let [current-progress (reanimated/get-shared-value @progress)]
(if (>= current-progress drag-limit)
drag-limit
(-> (quot current-progress progress-threshold)
(+ 1)
(* progress-threshold)))))
(defn get-previous-progress
[progress]
(let [current-progress (reanimated/get-shared-value @progress)]
(if (< current-progress progress-threshold)
0
(-> (quot current-progress progress-threshold)
(- 1)
(* progress-threshold)))))
(defn use-initialize-animation
[progress paused animate?]
@@ -37,7 +79,7 @@
(reset! paused (reanimated/use-shared-value false))
(rn/use-effect
(fn []
(animate-progress @progress @paused))
(animate-progress @progress @paused 0))
[animate?]))
(defn cleanup-animation
@@ -46,6 +88,26 @@
(reanimated/cancel-animation @progress)
(reanimated/cancel-animation @paused)))
(defn update-progress
[progress paused new-progress]
(reanimated/set-shared-value @progress new-progress)
(animate-progress @progress @paused new-progress))
(defn drag-gesture
[progress paused]
(->
(gesture/gesture-pan)
(gesture/enabled true)
(gesture/max-pointers 1)
(gesture/on-finalize
(fn [event]
(let [next? (< (oops/oget event "translationX") (- drag-limit))
previous? (> (oops/oget event "translationX") drag-limit)]
(when next?
(update-progress progress paused (get-next-progress progress)))
(when previous?
(update-progress progress paused (get-previous-progress progress))))))))
(defn carousel-left-position
[window-width animate? progress]
(if animate?
@@ -5,7 +5,8 @@
[react-native.navigation :as navigation]
[react-native.reanimated :as reanimated]
[status-im2.contexts.onboarding.common.carousel.style :as style]
[status-im2.contexts.onboarding.common.carousel.animation :as animation]))
[status-im2.contexts.onboarding.common.carousel.animation :as animation]
[react-native.gesture :as gesture]))
(defn header-text-view
[index window-width header-text]
@@ -49,23 +50,25 @@
:progress-bar-width progress-bar-width}]]))
(defn f-view
[{:keys [animate? progress header-text background header-background]}]
[{:keys [animate? progress paused? header-text background header-background swipeable?]}]
(let [window-width (rf/sub [:dimensions/window-width])
status-bar-height (:status-bar-height @navigation/constants)
progress-bar-width (- window-width 40)
carousel-left (animation/carousel-left-position window-width animate? progress)
container-view (if animate? reanimated/view rn/view)]
[:<>
[container-view {:style (style/carousel-container carousel-left animate?)}
(for [index (range 2)]
^{:key index}
[content-view
{:window-width window-width
:status-bar-height status-bar-height
:index index
:header-text header-text
:header-background header-background}
(when background background)])]
[gesture/gesture-detector
{:gesture (when swipeable? (animation/drag-gesture progress paused?))}
[container-view {:style (style/carousel-container carousel-left animate?)}
(for [index (range 2)]
^{:key index}
[content-view
{:window-width window-width
:status-bar-height status-bar-height
:index index
:header-text header-text
:header-background header-background}
(when background background)])]]
[rn/view
{:style (style/progress-bar-container
progress-bar-width
@@ -79,4 +82,3 @@
:progress progress}]]]))
(defn view [props] [:f> f-view props])
@@ -106,8 +106,11 @@
:content
(fn []
[method-menu/view on-change-profile-pic])}]))
:image-picker-props {:profile-picture @profile-pic
:full-name @full-name}
:image-picker-props {:profile-picture (when @profile-pic {:uri @profile-pic})
:full-name (if (seq @full-name)
@full-name
(i18n/label :t/your-name))
:customization-color @custom-color}
:title-input-props {:default-value @full-name
:auto-focus true
:max-length c/profile-name-max-length
@@ -21,4 +21,4 @@
(defn buttons
[insets]
{:margin default-margin
:margin-bottom (+ default-margin (:bottom insets))})
:margin-bottom (+ 14 (:bottom insets))})
@@ -12,7 +12,8 @@
(defn page-title
[]
[quo/title
{:title (i18n/label :t/enable-biometrics)
{:container-style {:margin-top 12}
:title (i18n/label :t/enable-biometrics)
:title-accessibility-label :enable-biometrics-title
:subtitle (i18n/label :t/use-biometrics)
:subtitle-accessibility-label :enable-biometrics-sub-title}])
@@ -22,4 +22,4 @@
(defn buttons
[insets]
{:margin default-margin
:margin-bottom (+ default-margin (:bottom insets))})
:margin-bottom (+ 14 (:bottom insets))})
@@ -16,7 +16,8 @@
(defn page-title
[]
[quo/title
{:title (i18n/label :t/intro-wizard-title6)
{:container-style {:margin-top 12}
:title (i18n/label :t/intro-wizard-title6)
:title-accessibility-label :notifications-title
:subtitle (i18n/label :t/enable-notifications-sub-title)
:subtitle-accessibility-label :notifications-sub-title}])
@@ -23,16 +23,16 @@
(defn f-view
[]
(let [progress (atom nil)
paused (atom nil)
paused? (atom nil)
{:keys [emoji-hash display-name compressed-key
public-key]} (rf/sub [:multiaccount])
{:keys [color]} (rf/sub [:onboarding-2/profile])
photo-path (rf/sub [:chats/photo-path public-key])
emoji-string (string/join emoji-hash)]
(carousel.animation/use-initialize-animation progress paused true)
(carousel.animation/use-initialize-animation progress paused? true)
(rn/use-effect
(fn []
(carousel.animation/cleanup-animation progress paused))
(carousel.animation/cleanup-animation progress paused?))
[])
[:<>
[background/view true]
@@ -40,6 +40,8 @@
[carousel/view
{:animate? true
:progress progress
:paused? paused?
:swipeable? false
:header-text header-text}]
[rn/view {:style style/content-container}
[quo/profile-card
@@ -12,7 +12,8 @@
[utils.security.core :as security]
[utils.transforms :as types]
[quo2.foundations.colors :as colors]
[react-native.safe-area :as safe-area]))
[react-native.safe-area :as safe-area]
[clojure.string :as string]))
(defn login-multiaccount
[]
@@ -178,7 +179,12 @@
(let [{:keys [key-uid name customization-color error
processing password]} (rf/sub [:multiaccounts/login])
sign-in-enabled? (rf/sub [:sign-in-enabled?])
profile-picture (rf/sub [:multiaccounts/login-profiles-picture key-uid])]
profile-picture (rf/sub [:multiaccounts/login-profiles-picture key-uid])
error (if (and (some? error)
(or (= error "file is not a database")
(string/starts-with? error "failed to set ")))
(i18n/label :t/wrong-password)
error)]
[rn/keyboard-avoiding-view
{:style style/login-container
:keyboardVerticalOffset (- (safe-area/get-bottom))}
@@ -19,7 +19,8 @@
(defn page-title
[pairing-progress?]
[quo/title
{:title (i18n/label (if pairing-progress?
{:container-style {:margin-top 56}
:title (i18n/label (if pairing-progress?
:t/sync-devices-title
:t/sync-devices-error-title))
:subtitle (i18n/label (if pairing-progress?
@@ -1,22 +1,24 @@
(ns status-im2.contexts.onboarding.syncing.results.style
(:require [quo2.foundations.colors :as colors]))
(def page-container
(defn page-container
[top]
{:flex 1
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:padding-top top
:padding-bottom 20
:background-color colors/neutral-80-opa-80-blur})
(def current-device
{:flex 1})
{:margin-bottom 19})
(def device-list
{:flex 1
:margin-top 24
:margin-top 12
:padding-horizontal 20})
(def continue-button
@@ -3,9 +3,10 @@
[utils.i18n :as i18n]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[utils.re-frame :as rf]
[status-im2.contexts.onboarding.syncing.results.style :as style]
[status-im2.common.syncing.view :as device]
[status-im2.contexts.syncing.device.view :as device]
[status-im2.contexts.onboarding.common.background.view :as background]))
(defn page-title
@@ -21,23 +22,25 @@
[rn/view {:style style/current-device}
[device/view
(merge installation
{:this-device? true})]
[quo/text
{:accessibility-label :sync-with-sub-title
:weight :regular
:size :paragraph-1
:style {:color colors/white}}
(i18n/label :t/sync-with)]])
{:this-device? true})]])
(defn devices-list
[]
(let [installations (rf/sub [:pairing/enabled-installations])]
(let [installations (rf/sub [:pairing/enabled-installations])
this-device (first installations)
other-devices (rest installations)]
[rn/view {:style style/device-list}
[current-device this-device]
[quo/text
{:accessibility-label :synced-with-sub-title
:weight :regular
:size :paragraph-2
:style {:color colors/white-opa-40}}
(i18n/label :t/synced-with)]
[rn/flat-list
{:data (rest installations)
{:data other-devices
:shows-vertical-scroll-indicator false
:key-fn :installation-id
:header [current-device (first installations)]
:render-fn device/view}]]))
(defn continue-button
@@ -52,9 +55,13 @@
(defn view
[]
[rn/view {:style style/page-container}
[background/view true]
[quo/page-nav]
[page-title]
[devices-list]
[continue-button]])
(let [top (safe-area/get-top)]
[rn/view {:style (style/page-container top)}
[background/view true]
[rn/view
{:style {:margin-top 56
:margin-bottom 26
:flex 1}}
[page-title]
[devices-list]
[continue-button]]]))
@@ -22,4 +22,4 @@
(defn buttons
[insets]
{:margin default-margin
:margin-bottom (+ default-margin (:bottom insets))})
:margin-bottom (+ 14 (:bottom insets))})
@@ -15,7 +15,8 @@
[]
(let [new-account? (rf/sub [:onboarding-2/new-account?])]
[quo/title
{:title (i18n/label (if new-account?
{:container-style {:margin-top 12}
:title (i18n/label (if new-account?
:t/welcome-to-web3
:t/welcome-back))
:title-accessibility-label :welcome-title
@@ -15,44 +15,59 @@
:type :boolean}
{:label "Show red options?"
:key :show-red-options?
:type :boolean}])
:type :boolean}
{:label "Override theme"
:key :override-theme
:type :select
:options [{:key :dark :value "Dark"}
{:key :light :value "Light"}
{:key nil :value "System"}]}])
(def options-with-consequences
[{:icon :i/delete
:danger? true
:label "Clear history"
:add-divider? true
:on-press #(js/alert "clear history")}])
(defn options-with-consequences
[override-theme]
[{:icon :i/delete
:danger? true
:label "Clear history"
:override-theme override-theme
:add-divider? true
:on-press #(js/alert "clear history")}])
(defn render-action-sheet
[state]
[rn/view
{:height 300
:background-color (colors/theme-colors colors/white colors/neutral-95)}
[quo/action-drawer
(cond->
[[{:icon :i/friend
:label "View channel members and details"
:on-press #(js/alert "View channel members and details")}
{:icon :i/communities
:label "Mark as read"
:disabled? (:mark-as-read-disabled? @state)
:on-press #(js/alert "Mark as read")}
{:icon :i/muted
:label (if (:muted? @state) "Unmute channel" "Mute channel")
:on-press #(js/alert (if (:muted? @state) "Unmute channel" "Mute channel"))
:right-icon :i/chevron-right
:sub-label (when (:muted? @state) "Muted for 15 min")}
{:icon :i/scan
:on-press #(js/alert "Fetch messages")
:right-icon :i/chevron-right
:label "Fetch messages"}
{:icon :i/add-user
:on-press #(js/alert "Share link to the channel")
:label "Share link to the channel"}]]
(let [override-theme (:override-theme @state)]
[rn/view
{:height 300
:background-color (colors/theme-colors colors/white colors/neutral-95)}
[quo/action-drawer
(cond->
[[{:icon :i/friend
:label "View channel members and details"
:override-theme override-theme
:on-press #(js/alert "View channel members and details")}
{:icon :i/communities
:label "Mark as read"
:override-theme override-theme
:disabled? (:mark-as-read-disabled? @state)
:on-press #(js/alert "Mark as read")}
{:icon :i/muted
:label (if (:muted? @state) "Unmute channel" "Mute channel")
:override-theme override-theme
:on-press #(js/alert (if (:muted? @state) "Unmute channel" "Mute channel"))
:right-icon :i/chevron-right
:sub-label (when (:muted? @state) "Muted for 15 min")}
{:icon :i/scan
:on-press #(js/alert "Fetch messages")
:override-theme override-theme
:right-icon :i/chevron-right
:right-text "3"
:label "Fetch messages"}
{:icon :i/add-user
:override-theme override-theme
:on-press #(js/alert "Share link to the channel")
:label "Share link to the channel"}]]
(:show-red-options? @state)
(conj options-with-consequences))]])
(:show-red-options? @state)
(conj (options-with-consequences override-theme)))]]))
(defn cool-preview
[]
@@ -23,10 +23,12 @@
:type :boolean}
{:label "Button"
:key :button-props
:type :boolean
}])
:type :boolean}
{:label "Status Tag"
:key :status-tag-props
:type :boolean}])
(defn get-mock-data
(defn get-props
[data]
(when (:toggle-props data) (js/console.warn data))
(merge
@@ -41,7 +43,13 @@
{:data
[{:source (resources/mock-images :rarible)}
{:source (resources/mock-images :decentraland)}
{:source (resources/mock-images :coinbase)}]})}))
{:source (resources/mock-images :coinbase)}]})
:status-tag-props (when (:status-tag-props data)
{:size :small
:status {:type :positive}
:no-icon? true
:label "example"
:override-theme :dark})}))
(defn cool-preview
[]
@@ -56,9 +64,9 @@
[preview/customizer state descriptor]
[rn/view
{:padding-vertical 100
:padding-horizontal 40
:padding-horizontal 20
:align-items :center}
[quo/settings-list (get-mock-data @state)]]])))
[quo/settings-list (get-props @state)]]])))
(defn preview-settings-list
[]
@@ -0,0 +1,11 @@
(ns status-im2.contexts.syncing.device.style
(:require [quo2.foundations.colors :as colors]))
(def device-container
{:padding-top 12
:padding-horizontal 12
:padding-bottom 16
:border-color colors/white-opa-5
:border-radius 16
:border-width 1
:margin-top 12})
@@ -0,0 +1,34 @@
(ns status-im2.contexts.syncing.device.view
[:require
[quo2.core :as quo]
[utils.i18n :as i18n]
[status-im2.contexts.syncing.device.style :as style]])
(defn view
[{:keys [name
this-device?
device-type
enabled?
show-button?]}]
(let [paired? (and (not this-device?) enabled?)
unpaired? (not enabled?)]
[quo/settings-list
(cond->
{:container-style style/device-container
:title name
:override-theme :dark
:left-icon (if (= device-type :mobile) :i/mobile :i/desktop)}
(and show-button? unpaired?) (assoc :button-props
{:title (i18n/label :t/pair)
:on-press #(js/alert "feature not added yet")})
(and show-button? paired?) (assoc
:button-props
{:title (i18n/label :t/unpair)
:on-press #(js/alert "feature not added yet")})
this-device? (assoc
:status-tag-props
{:size :small
:status {:type :positive}
:no-icon? true
:label (i18n/label :t/this-device)
:override-theme :dark}))]))
+20 -6
View File
@@ -1,14 +1,15 @@
(ns status-im2.contexts.syncing.events
(:require [native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.data-store.settings :as data-store.settings]
[status-im.node.core :as node]
[status-im.utils.platform :as utils.platform]
[status-im2.config :as config]
[status-im2.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]
[utils.security.core :as security]
[status-im2.config :as config]
[status-im.node.core :as node]
[re-frame.core :as re-frame]
[status-im.data-store.settings :as data-store.settings]
[status-im.utils.platform :as utils.platform]
[status-im2.constants :as constants]))
[utils.transforms :as transforms]))
(rf/defn local-pairing-update-role
{:events [:syncing/update-role]}
@@ -31,6 +32,19 @@
:custom-bootnodes-enabled? false}}]
(node/get-multiaccount-node-config db)))
(rf/defn preflight-outbound-check-for-local-pairing
{:events [:syncing/preflight-outbound-check]}
[_ set-checks-passed]
(let [callback
(fn [raw-response]
(log/info "Local pairing preflight check"
{:response raw-response
:event :syncing/preflight-outbound-check})
(let [^js response-js (transforms/json->js raw-response)
error (transforms/js->clj (.-error response-js))]
(set-checks-passed (empty? error))))]
(native-module/local-pairing-preflight-outbound-check callback)))
(rf/defn initiate-local-pairing-with-connection-string
{:events [:syncing/input-connection-string-for-bootstrapping]
:interceptors [(re-frame/inject-cofx :random-guid-generator)]}
@@ -13,10 +13,35 @@
[status-im2.contexts.syncing.scan-sync-code.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[status-im2.contexts.syncing.utils :as sync-utils]))
[status-im2.contexts.syncing.utils :as sync-utils]
[status-im.utils.platform :as platform]))
;; Android allow local network access by default. So, we need this check on iOS only.
(defonce preflight-check-passed? (reagent/atom (if platform/ios? false true)))
(defonce camera-permission-granted? (reagent/atom false))
(defn request-camera-permission
[]
(rf/dispatch
[:request-permissions
{:permissions [:camera]
:on-allowed #(reset! camera-permission-granted? true)
:on-denied #(rf/dispatch
[:toasts/upsert
{:icon :i/info
:icon-color colors/danger-50
:override-theme :light
:text (i18n/label :t/camera-permission-denied)}])}]))
(defn perform-preflight-check
"Performing the check for the first time
will trigger local network access permission in iOS.
This permission is required for local pairing
https://github.com/status-im/status-mobile/issues/16135"
[]
(rf/dispatch [:syncing/preflight-outbound-check #(reset! preflight-check-passed? %)]))
(defn- header
[active-tab read-qr-once? title]
[:<>
@@ -59,27 +84,49 @@
(reset! active-tab id)
(reset! read-qr-once? false))}]]])
(defn- camera-permission-view
[request-camera-permission]
[rn/view {:style style/camera-permission-container}
[quo/text
{:size :paragraph-1
:weight :medium
:style style/enable-camera-access-header}
(i18n/label :t/enable-access-to-camera)]
[quo/text
{:size :paragraph-2
:weight :regular
:style style/enable-camera-access-sub-text}
(i18n/label :t/to-scan-a-qr-enable-your-camera)]
[quo/button
{:before :i/camera
:type :primary
:size 32
:accessibility-label :request-camera-permission
:override-theme :dark
:on-press request-camera-permission}
(i18n/label :t/enable-camera)]])
(defn get-labels-and-on-press-method
[]
(if @camera-permission-granted?
{:title-label-key :t/enable-access-to-local-network
:description-label-key :t/to-pair-with-your-other-device-in-the-network
:button-icon :i/world
:button-label :t/enable-network-access
:accessibility-label :perform-preflight-check
:on-press perform-preflight-check}
{:title-label-key :t/enable-access-to-camera
:description-label-key :t/to-scan-a-qr-enable-your-camera
:button-icon :i/camera
:button-label :t/enable-camera
:accessibility-label :request-camera-permission
:on-press request-camera-permission}))
(defn- camera-and-local-network-access-permission-view
[]
(let [{:keys [title-label-key
description-label-key
button-icon
button-label
accessibility-label
on-press]} (get-labels-and-on-press-method)]
[rn/view {:style style/camera-permission-container}
[quo/text
{:size :paragraph-1
:weight :medium
:style style/enable-camera-access-header}
(i18n/label title-label-key)]
[quo/text
{:size :paragraph-2
:weight :regular
:style style/enable-camera-access-sub-text}
(i18n/label description-label-key)]
[quo/button
{:before button-icon
:type :primary
:size 32
:accessibility-label accessibility-label
:override-theme :dark
:on-press on-press}
(i18n/label button-label)]]))
(defn- qr-scan-hole-area
[qr-view-finder]
@@ -117,14 +164,16 @@
(i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]]]))
(defn- scan-qr-code-tab
[qr-view-finder request-camera-permission]
[qr-view-finder]
[:<>
[rn/view {:style style/scan-qr-code-container}]
(when (empty? @qr-view-finder)
[qr-scan-hole-area qr-view-finder])
(if (and @camera-permission-granted? (boolean (not-empty @qr-view-finder)))
(if (and @preflight-check-passed?
@camera-permission-granted?
(boolean (not-empty @qr-view-finder)))
[viewfinder @qr-view-finder]
[camera-permission-view request-camera-permission])])
[camera-and-local-network-access-permission-view])])
(defn- enter-sync-code-tab
[]
@@ -185,21 +234,9 @@
(defn f-view
[{:keys [title show-bottom-view? background]}]
(let [insets (safe-area/get-insets)
active-tab (reagent/atom 1)
qr-view-finder (reagent/atom {})
request-camera-permission (fn []
(rf/dispatch
[:request-permissions
{:permissions [:camera]
:on-allowed #(reset! camera-permission-granted? true)
:on-denied #(rf/dispatch
[:toasts/upsert
{:icon :i/info
:icon-color colors/danger-50
:override-theme :light
:text (i18n/label
:t/camera-permission-denied)}])}]))]
(let [insets (safe-area/get-insets)
active-tab (reagent/atom 1)
qr-view-finder (reagent/atom {})]
(fn []
(let [camera-ref (atom nil)
read-qr-once? (atom false)
@@ -215,7 +252,9 @@
3000)
(check-qr-code-data data)))
scan-qr-code-tab? (= @active-tab 1)
show-camera? (and scan-qr-code-tab? @camera-permission-granted?)
show-camera? (and scan-qr-code-tab?
@camera-permission-granted?
@preflight-check-passed?)
show-holes? (and show-camera?
(boolean (not-empty @qr-view-finder)))]
(rn/use-effect
@@ -230,7 +269,7 @@
[rn/view {:style (style/root-container (:top insets))}
[header active-tab read-qr-once? title]
(case @active-tab
1 [scan-qr-code-tab qr-view-finder request-camera-permission]
1 [scan-qr-code-tab qr-view-finder]
2 [enter-sync-code-tab]
nil)
[rn/view {:style style/flex-spacer}]
@@ -7,39 +7,19 @@
(def page-container
{:flex 1
:justify-content :flex-start
:margin-horizontal 20})
(def title-container
{:flex-direction :row
:align-items :center
:justify-content :space-between
:margin-bottom 24})
(def devices-container
{:flex 1})
(def device-container
{:display :flex
:padding-top 12
:padding-horizontal 12
:padding-bottom 16
:flex-direction :row
:border-color colors/white-opa-5
:border-radius 16
:border-width 1
:height 100
:margin-top 24})
(def device-details
{:height 200})
:margin-top 12
:margin-bottom 12})
(def navigation-bar
{:height 56})
(def icon-container
{:height 20
:margin-right 12})
(def tag-container
{:margin-top 8})
(def subtitle
{:margin-top 20
:color colors/white-opa-40})
@@ -4,10 +4,9 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[status-im2.contexts.syncing.syncing-devices-list.style :as style]
[status-im2.common.syncing.view :as device]
[status-im2.contexts.syncing.device.view :as device]
[utils.re-frame :as rf]))
;;TODO remove mock data (#https://github.com/status-im/status-mobile/issues/15142)
(defn navigation-bar
[]
[rn/view {:style style/navigation-bar}
@@ -21,21 +20,48 @@
(defn view
[]
[rn/view {:style style/container-main}
[navigation-bar]
[rn/view {:style style/page-container}
[rn/view {:style style/title-container}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}} (i18n/label :t/syncing)]
[quo/button
{:size 32
:icon true
:on-press #(rf/dispatch [:navigate-to :settings-setup-syncing])}
:i/add]]
[rn/view {:style style/devices-container}
[device/view
{:name "iPhone 11"
:this-device? true
:device-type :mobile}]]]])
(let [devices (rf/sub [:pairing/installations])
devices-with-button (map #(assoc % :show-button? true) devices)
user-device (first devices-with-button)
other-devices (rest devices-with-button)
{:keys [paired-devices unpaired-devices]} (group-by
#(if (:enabled? %) :paired-devices :unpaired-devices)
other-devices)]
[rn/view {:style style/container-main}
[navigation-bar]
[rn/view {:style style/page-container}
[rn/view {:style style/title-container}
[quo/text
{:size :heading-1
:weight :semi-bold
:style {:color colors/white}}
(i18n/label :t/syncing)]
[quo/button
{:size 32
:icon true
:on-press #(rf/dispatch [:navigate-to :settings-setup-syncing])}
:i/add]]
[device/view (merge user-device {:this-device? true})]
(when (seq paired-devices)
[rn/view
[quo/text
{:size :paragraph-2
:weight :medium
:style style/subtitle}
(i18n/label :t/paired-with-this-device)]
[rn/flat-list
{:key-fn str
:render-fn device/view
:data paired-devices}]])
(when (seq unpaired-devices)
[rn/view
[quo/text
{:size :paragraph-2
:weight :medium
:style style/subtitle}
(i18n/label :t/not-paired-with-this-device)]
[rn/flat-list
{:key-fn str
:render-fn device/view
:data unpaired-devices}]])]]))
+1 -6
View File
@@ -69,17 +69,12 @@
(when js/goog.DEBUG
[reloader/reload-view])]))))
; Designs require bottom inset to be bigger than safe area, otherwise it is too close to the bottom
(defn bottom-sheet-insets
[]
(assoc (safe-area/get-insets) :bottom 55))
(def bottom-sheet
(reagent/reactify-component
(fn []
(let [{:keys [sheets hide?]} (rf/sub [:bottom-sheet])
sheet (last sheets)
insets (bottom-sheet-insets)]
insets (safe-area/get-insets)]
^{:key (str "sheet" @reloader/cnt)}
[:<>
[inactive]
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.156.1",
"commit-sha1": "9e0a12cb32bf8921ba7b5c923f743bb7119fab96",
"src-sha256": "0yx8dcxrig1qkna7kfqpjh5ry33ybdmqh31x42jg4wlb9nm2jnw8"
"version": "v0.157.2",
"commit-sha1": "47711c4f15d0ebb4665cc121f17184b183f4d2df",
"src-sha256": "1w0marsyq8gk2dv4qi4xxplgm67iw6sif7n551jdypbl01i1s17w"
}
+1 -1
View File
@@ -370,7 +370,7 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
'%s_geth%s.log' % (test_suite_data.current_test.name, str(self.drivers[driver].number)))
geth_contents.append(self.pull_geth(self.drivers[driver]))
except (WebDriverException, AttributeError, RemoteDisconnected):
except (WebDriverException, AttributeError, RemoteDisconnected, ProtocolError):
pass
finally:
try:
@@ -1148,8 +1148,10 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@marks.testrail_id(702733)
def test_1_1_chat_text_message_delete_push_disappear(self):
self.chat_2.jump_to_card_by_text(self.username_1)
self.chat_1.jump_to_card_by_text(self.username_2)
if not self.chat_2.chat_message_input.is_element_displayed():
self.chat_2.jump_to_card_by_text(self.username_1)
if not self.chat_1.chat_message_input.is_element_displayed():
self.chat_1.jump_to_card_by_text(self.username_2)
self.device_2.just_fyi("Verify Device1 can not edit and delete received message from Device2")
message_after_edit_1_1 = 'smth I should edit'
@@ -454,9 +454,9 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
(", ".join(sent_time_variants), timestamp))
self.channel_1.verify_message_is_under_today_text(message, self.errors)
new_message = "new message"
self.channel_1.send_message(message)
self.channel_1.send_message(new_message)
self.channel_2.verify_message_is_under_today_text(new_message, self.errors, 60)
if self.channel_2.chat_element_by_text(message).username.text != self.username_1:
if self.channel_2.chat_element_by_text(new_message).username.text != self.username_1:
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
self.errors.verify_no_errors()
@@ -542,7 +542,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.chat_message_input.send_keys(message_text)
self.channel_2.send_message_button.click()
chat_element_1 = self.channel_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(sec=60) or chat_element_1.replied_message_text != 'Image':
if not chat_element_1.is_element_displayed(sec=60) or chat_element_1.replied_message_text != image_description:
self.errors.append('Reply message was not received by the sender')
self.errors.verify_no_errors()
@@ -566,7 +566,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.chat_message_input.send_keys(message_text)
self.channel_2.send_message_button.click()
chat_element_1 = self.channel_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(sec=60) or chat_element_1.replied_message_text != 'Image':
if not chat_element_1.is_element_displayed(sec=60) or chat_element_1.replied_message_text != image_description:
self.errors.append('Reply message was not received by the sender')
self.errors.verify_no_errors()
@@ -760,8 +760,13 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
@marks.testrail_id(703086)
def test_community_mark_all_messages_as_read(self):
self.channel_1.jump_to_communities_home()
self.home_2.jump_to_card_by_text('# %s' % self.channel_name)
self.channel_1.click_system_back_button_until_element_is_shown()
self.home_1.communities_tab.click()
if not self.channel_2.chat_message_input.is_element_displayed():
self.channel_2.click_system_back_button_until_element_is_shown()
self.home_2.communities_tab.click()
self.home_2.get_chat(self.community_name, community=True).click()
self.community_2.get_channel(self.channel_name).click()
self.channel_2.send_message(self.text_message)
community_1_element = self.community_1.get_chat(self.community_name)
if not community_1_element.new_messages_public_chat.is_element_displayed(90):
+4 -1
View File
@@ -369,7 +369,7 @@ class BaseView(object):
def hide_keyboard_if_shown(self):
if self.driver.is_keyboard_shown():
self.driver.hide_keyboard()
self.click_system_back_button()
def click_system_back_button(self, times=1):
self.driver.info('Click system back button')
@@ -598,14 +598,17 @@ class BaseView(object):
sign_in_view.sign_in(password)
def jump_to_messages_home(self):
self.hide_keyboard_if_shown()
self.jump_to_button.click()
self.chats_tab.click_until_presence_of_element(self.jump_to_button)
def jump_to_communities_home(self):
self.hide_keyboard_if_shown()
self.jump_to_button.click()
self.communities_tab.click_until_presence_of_element(self.jump_to_button)
def jump_to_card_by_text(self, text: str):
self.hide_keyboard_if_shown()
self.jump_to_button.click()
self.element_by_text(text).click()
+1 -1
View File
@@ -1167,7 +1167,7 @@ class ChatView(BaseView):
self.allow_button.click_if_shown()
[self.get_image_by_index(i).click() for i in indexes]
self.images_confirm_selection_button.click()
self.chat_message_input.set_value(description)
self.chat_message_input.send_keys(description)
self.send_message_button.click()
@staticmethod
+15 -6
View File
@@ -1033,6 +1033,7 @@
"not-applicable": "Not applicable for unsigned transactions",
"not-keycard-text": "The card you used is not a Keycard. You need to purchase a Keycard to use it",
"not-keycard-title": "Not a Keycard",
"not-paired-with-this-device": "Not paired with this device",
"notifications": "Notifications",
"local-notifications": "Local notifications",
"local-notifications-subtitle": "Enable background service",
@@ -1040,7 +1041,7 @@
"remote-notifications-subtitle": "Enable google push notifications",
"show-notifications": "Show notifications",
"notification-settings": "Notifications",
"community-notification-settings": "Notification settings",
"notification-settings": "Notification settings",
"notifications-servers": "Notification servers",
"notifications-preferences": "Notification preferences",
"notifications-switch": "Show notifications",
@@ -1083,7 +1084,8 @@
"outgoing": "Outgoing",
"outgoing-transaction": "Outgoing transaction",
"own-your-crypto": "Own your crypto",
"pair": "Pair devices",
"pair": "Pair",
"pair-devices": "Pair devices",
"pair-card": "Pair to this device",
"pair-code": "Pair code",
"pair-code-explanation": "Pairs card to a different device (up to 5) to unlock keys and sign transactions with the same Keycard",
@@ -1091,6 +1093,7 @@
"pair-this-device": "Advertise device",
"pair-this-device-description": "Pair your devices to sync contacts and chats between them",
"paired-devices": "Paired devices",
"paired-with-this-device": "Paired with this device",
"pairing": "Pairing",
"pairing-card": "Pairing card",
"pairing-code-placeholder": "Pairing code...",
@@ -1251,6 +1254,7 @@
"settings": "Settings",
"share": "Share",
"shared": "Shared",
"share-channel": "Share channel",
"share-address": "Share address",
"share-chat": "Share chat",
"share-contact-code": "Share my chat key",
@@ -1419,6 +1423,7 @@
"unique-identifiers": "Unique profile identifiers",
"unknown-status-go-error": "Unknown status-go error",
"unlock": "Unlock",
"unpair": "Unpair",
"unpair-card": "Unpair card",
"unpair-card-confirmation": "This operation will unpair card from current device. Requires 6-digit passcode authorization. Do you want to proceed?",
"unpaired-keycard-text": "The Keycard you tapped is not associated with this phone",
@@ -1443,6 +1448,7 @@
"view-gitcoin": "View in Gitcoin",
"view-members": "View members",
"view-profile": "View profile",
"view-channel-members-and-details": "View channel member and details",
"view-details": "View Details",
"view-signing": "View signing phrase",
"view-superrare": "View in SuperRare",
@@ -2088,6 +2094,9 @@
"synchronise-your-data-across-your-devices": "Synchronise your data across your devices",
"scan-sync-qr-code": "Scan QR code",
"enter-sync-code": "Enter sync code",
"enable-access-to-local-network": "Enable access to local network",
"to-pair-with-your-other-device-in-the-network": "To pair with your other device in the network",
"enable-network-access": "Enable network access",
"enable-access-to-camera": "Enable access to camera",
"link-preview-loading-message": "Generating preview",
"to-scan-a-qr-enable-your-camera": "To scan a QR, enable your camera",
@@ -2175,16 +2184,16 @@
"user-deleted-a-message": "{{user}} deleted a message",
"link-to-profile": "Link to profile",
"emoji-hash": "Emoji Hash",
"emoji-hash-copied":"Emojihash copied to clipboard",
"link-to-profile-copied":"Link to Profile copied to clipboard",
"emoji-hash-copied": "Emojihash copied to clipboard",
"link-to-profile-copied": "Link to Profile copied to clipboard",
"sync-devices-result-sub-title": "Your devices are now in sync",
"sync-devices-title": "Syncing devices...",
"sync-devices-sub-title": "Please keep both devices switched on and connected to the internet until sync is complete",
"sync-devices-error-title": "Oops, somethings wrong",
"sync-devices-error-sub-title":"Make sure both devices are powered on and connected to the internet.",
"sync-devices-error-sub-title": "Make sure both devices are powered on and connected to the internet.",
"sync-devices-complete-title": "Device sync complete!",
"sync-devices-complete-sub-title": "Your devices are now in sync",
"sync-with": "Synced with",
"synced-with": "Synced with",
"you-eligible-to-join": "Youre eligible to join",
"you-not-eligible-to-join": "Youre not eligible to join",
"you-hold-number-of-hold-tokens-of-these": "You hold {{number-of-hold-tokens}} of these:",