feat: add messages gap component (#13860)

This commit is contained in:
yqrashawn 2022-09-05 15:58:35 +08:00 committed by GitHub
parent 6fa1729384
commit bf346147e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 221 additions and 38 deletions

View File

@ -1,6 +1,7 @@
module.exports = { module.exports = {
bracketSpacing: false, bracketSpacing: false,
jsxBracketSameLine: true, bracketSameLine: true,
singleQuote: true, singleQuote: true,
trailingComma: 'all', trailingComma: 'all',
}; tabWidth: 4,
};

View File

@ -640,7 +640,7 @@ SPEC CHECKSUMS:
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
Folly: b73c3869541e86821df3c387eb0af5f65addfab4 Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db glog: 64a900d72fb14cd1b2cdf3b717a5555ceb889d49
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352 HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8 Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,148 @@
(ns quo2.components.messages-gap
(:require
[oops.core :refer [oget]]
[quo.react-native :as rn]
[quo.theme :as theme]
[quo2.components.icon :as icon]
[quo2.components.text :as text]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.react :refer [pressable-class]]
[status-im.utils.handlers :refer [>evt]]))
;;; helpers
(def themes
{:light {:icon colors/neutral-40
:time colors/neutral-50
:background colors/neutral-5}
:dark {:icon colors/neutral-60
:time colors/neutral-40
:background colors/neutral-95}})
(defn get-color [key]
(get-in themes [(theme/get-theme) key]))
(def ui-images
{:light {:horizontal (js/require "../resources/images/ui/message-gap-hborder-light.png")
:vertical (js/require "../resources/images/ui/message-gap-vborder-light.png")
:circles (js/require "../resources/images/ui/message-gap-circle-bg-light.png")}
:dark {:horizontal (js/require "../resources/images/ui/message-gap-hborder-dark.png")
:circles (js/require "../resources/images/ui/message-gap-circle-bg-dark.png")}})
(defn get-image [key]
(get-in ui-images [(theme/get-theme) key]))
;;; components
;;;; borders
(defn hborder [{:keys [type style]}]
[rn/image {:source (get-image :horizontal)
:resize-mode :repeat
:style (merge {:position :absolute
:left 0
:padding-horizontal 4
:overflow :hidden
:width "110%"
:height 8
:margin-left -4}
(if (= type :top)
{:top 0}
{:transform [{:rotateZ "180deg"}]
:bottom 0})
style)}])
(defn vborder [type body-height]
(let [height @body-height
img (get-image :vertical)]
(when (and img height)
[rn/image {:source img
:resize-mode :repeat
:style (merge
{:position :absolute
:top 4
:height (- height 8)
:width 4}
(if (= type :left)
{:left 0}
{:transform [{:rotate "180deg"}]
:right 0}))}])))
;;;; others
(defn circle []
[rn/view
{:width 8
:height 8
:border-width 1
:margin 4
:flex 0
:border-color (get-color :icon)
:border-radius 50}])
(defn timestamp [str]
[text/text {:size :label
:style {:text-transform :none
:color (get-color :time)}} str])
(defn info-button [on-press]
[pressable-class
{:on-press on-press}
[icon/icon "message-gap-info" {:size 12 :no-color true :container-style {:padding 4}}]])
;;;; left/right
(defn left []
[rn/view {:flex 0
:padding-left 11.5
:margin-right 20.5
:align-items :center
:justify-content :space-between}
[circle]
[rn/image {:style {:flex 1} :source (get-image :circles) :resize-mode :repeat}]
[circle]])
(defn right [timestamp-far timestamp-near chat-id gap-ids on-info-button-pressed]
[rn/view {:flex 1}
[rn/view
{:flex-direction :row
:align-items :center
:justify-content :space-between
:margin-right 2}
[timestamp timestamp-far]
(when on-info-button-pressed [info-button on-info-button-pressed])]
[pressable-class
{:style {:flex 1 :margin-top 16 :margin-bottom 20}
:on-press #(when (and chat-id gap-ids)
(>evt [:chat.ui/fill-gaps chat-id gap-ids]))}
[text/text
(i18n/label :messages-gap-warning)]]
[timestamp timestamp-near]])
;;; main
(defn messages-gap
"if `gap-ids` and `chat-id` are provided, press the main text area to fetch messages
if `on-info-button-pressed` fn is provided, the info button will show up and is pressable"
[{:keys [timestamp-far
timestamp-near
gap-ids
chat-id
on-info-button-pressed
style]}]
(let [body-height (reagent/atom nil)]
(fn []
[rn/view
{:on-layout #(reset! body-height (oget % "nativeEvent.layout.height"))
:overflow :hidden}
[hborder {:type :top}]
[hborder {:type :bottom}]
[rn/view (merge {:width "100%"
:background-color (get-color :background)
:flex-direction :row
:padding 20
:margin-vertical 4}
style)
[left]
[right timestamp-far timestamp-near chat-id gap-ids on-info-button-pressed]]
[vborder :left body-height]
[vborder :right body-height]])))

View File

@ -1,28 +1,29 @@
(ns quo2.screens.main (ns quo2.screens.main
(:require [quo.react-native :as rn] (:require [quo.components.safe-area :as safe-area]
[quo.theme :as theme] [quo.core :as quo]
[quo.design-system.colors :as colors] [quo.design-system.colors :as colors]
[re-frame.core :as re-frame] [quo.react-native :as rn]
[quo2.screens.button :as button] [quo.theme :as theme]
[quo2.screens.token-overview :as token-overview]
[quo2.screens.text :as text]
[quo2.screens.tabs :as tabs]
[quo2.screens.status-tags :as status-tags]
[quo2.screens.context-tags :as context-tags]
[quo2.screens.group-avatar :as group-avatar]
[quo2.screens.activity-logs :as activity-logs] [quo2.screens.activity-logs :as activity-logs]
[quo2.screens.token-tag :as token-tag] [quo2.screens.button :as button]
[quo2.screens.community-card-view :as community-card]
[quo2.screens.context-tags :as context-tags]
[quo2.screens.counter :as counter] [quo2.screens.counter :as counter]
[quo2.screens.wallet-user-avatar :as wallet-user-avatar] [quo2.screens.filter-tags :as filter-tags]
[quo2.screens.group-avatar :as group-avatar]
[quo2.screens.icon-avatar :as icon-avatar] [quo2.screens.icon-avatar :as icon-avatar]
[quo2.screens.segmented :as segmented]
[quo2.screens.info-message :as info-message] [quo2.screens.info-message :as info-message]
[quo2.screens.information-box :as information-box] [quo2.screens.information-box :as information-box]
[quo.components.safe-area :as safe-area] [quo2.screens.messages-gap :as messages-gap]
[quo2.screens.permission-tag :as permission-tag] [quo2.screens.permission-tag :as permission-tag]
[quo2.screens.community-card-view :as community-card] [quo2.screens.segmented :as segmented]
[quo2.screens.filter-tags :as filter-tags] [quo2.screens.status-tags :as status-tags]
[quo.core :as quo])) [quo2.screens.tabs :as tabs]
[quo2.screens.text :as text]
[quo2.screens.token-overview :as token-overview]
[quo2.screens.token-tag :as token-tag]
[quo2.screens.wallet-user-avatar :as wallet-user-avatar]
[re-frame.core :as re-frame]))
(def screens [{:name :quo2-texts (def screens [{:name :quo2-texts
:insets {:top false} :insets {:top false}
@ -42,6 +43,9 @@
{:name :quo2-status-tags {:name :quo2-status-tags
:insets {:top false} :insets {:top false}
:component status-tags/preview-status-tags} :component status-tags/preview-status-tags}
{:name :quo2-messages-gap
:insets {:top false}
:component messages-gap/preview-messages-gap}
{:name :quo2-context-tags {:name :quo2-context-tags
:insets {:top false} :insets {:top false}
:component context-tags/preview-context-tags} :component context-tags/preview-context-tags}

View File

@ -0,0 +1,29 @@
(ns quo2.screens.messages-gap
(:require
[quo.previews.preview :as preview]
[quo.react-native :as rn]
[quo2.components.messages-gap :as quo2]
[reagent.core :as reagent]))
(def descriptor [{:label "Timestamp Far"
:key :timestamp-far
:type :text}
{:label "Timestamp Near"
:key :timestamp-near
:type :text}])
(defn preview []
(let [state (reagent/atom {:timestamp-far "Jan 8 · 09:12" :timestamp-near "Mar 8 · 22:42" :on-info-button-pressed identity})]
(fn []
[rn/view {:margin-bottom 50}
[rn/view {:padding 16}
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 60
:align-items :center}
[quo2/messages-gap @state]]])))
(defn preview-messages-gap []
[rn/view {:flex 1}
[rn/flat-list {:flex 1
:header [preview]
:key-fn str}]])

View File

@ -11,6 +11,7 @@
"account-color": "Account color", "account-color": "Account color",
"anyone": "Anyone", "anyone": "Anyone",
"messages-from-contacts-only-subtitle": "Only people you added as contacts can start a new chat with you or invite you to a group", "messages-from-contacts-only-subtitle": "Only people you added as contacts can start a new chat with you or invite you to a group",
"messages-gap-warning": "Some messages might be missing",
"accept-new-chats-from": "Accept new chats from", "accept-new-chats-from": "Accept new chats from",
"account-name": "Account name", "account-name": "Account name",
"account-settings": "Account settings", "account-settings": "Account settings",
@ -547,7 +548,7 @@
"migration-successful": "Migration successful", "migration-successful": "Migration successful",
"migration-successful-text": "Account succesfully migrated to Keycard", "migration-successful-text": "Account succesfully migrated to Keycard",
"skip": "Skip", "skip": "Skip",
"password-placeholder":"Password...", "password-placeholder": "Password...",
"confirm-password-placeholder": "Confirm your password...", "confirm-password-placeholder": "Confirm your password...",
"enter-pin": "Enter 6-digit passcode", "enter-pin": "Enter 6-digit passcode",
"enter-puk-code": "Enter PUK code", "enter-puk-code": "Enter PUK code",
@ -613,7 +614,7 @@
"group-chat-members-count": "{{selected}}/{{max}} members", "group-chat-members-count": "{{selected}}/{{max}} members",
"group-chat-name-changed": "**{{member}}** changed the group's name to **{{name}}**", "group-chat-name-changed": "**{{member}}** changed the group's name to **{{name}}**",
"group-chat-no-contacts": "You don't have any contacts yet.\nInvite your friends to start chatting", "group-chat-no-contacts": "You don't have any contacts yet.\nInvite your friends to start chatting",
"leave-chat":"Leave chat", "leave-chat": "Leave chat",
"leave-confirmation": "Leave {{chat-name}}", "leave-confirmation": "Leave {{chat-name}}",
"leave-chat-confirmation": "Chat history will be removed from your device. After rejoining you won't be able to retrieve any of your history.", "leave-chat-confirmation": "Chat history will be removed from your device. After rejoining you won't be able to retrieve any of your history.",
"group-chat-all-contacts-invited": "All your contacts are already in the group", "group-chat-all-contacts-invited": "All your contacts are already in the group",
@ -1005,7 +1006,7 @@
"paired-devices": "Paired devices", "paired-devices": "Paired devices",
"pairing": "Pairing", "pairing": "Pairing",
"pairing-card": "Pairing card", "pairing-card": "Pairing card",
"pairing-code-placeholder":"Pairing code...", "pairing-code-placeholder": "Pairing code...",
"pairing-code_error1": "Pairing codes don't match.", "pairing-code_error1": "Pairing codes don't match.",
"confirm-pairing-code-placeholder": "Confirm your pairing code...", "confirm-pairing-code-placeholder": "Confirm your pairing code...",
"pairing-go-to-installation": "Go to pairing settings", "pairing-go-to-installation": "Go to pairing settings",
@ -1434,10 +1435,10 @@
"give-permissions-camera": "Give permission\nto access camera", "give-permissions-camera": "Give permission\nto access camera",
"photos": "Photos", "photos": "Photos",
"image": "Image", "image": "Image",
"sign-anyway" : "Sign anyway", "sign-anyway": "Sign anyway",
"tx-fail-description1" : "This transaction is likely to fail. Sign at your own risk using custom network fee.", "tx-fail-description1": "This transaction is likely to fail. Sign at your own risk using custom network fee.",
"tx-fail-description2" : "This transaction is likely to fail. Set a custom network fee to sign at your own risk.", "tx-fail-description2": "This transaction is likely to fail. Set a custom network fee to sign at your own risk.",
"set-custom-fee" : "Set custom fee", "set-custom-fee": "Set custom fee",
"not-enough-snt": "Not enough SNT", "not-enough-snt": "Not enough SNT",
"add-new-contact": "Add new contact", "add-new-contact": "Add new contact",
"you-dont-have-contacts": "You dont have any contacts yet.", "you-dont-have-contacts": "You dont have any contacts yet.",
@ -1457,10 +1458,10 @@
"update-to-see-image": "Update to latest version to see a nice image here!", "update-to-see-image": "Update to latest version to see a nice image here!",
"update-to-listen-audio": "Update to latest version to listen to an audio message here!", "update-to-listen-audio": "Update to latest version to listen to an audio message here!",
"update-to-see-sticker": "Update to latest version to see a nice sticker here!", "update-to-see-sticker": "Update to latest version to see a nice sticker here!",
"webview-camera-permission-requests" : "Webview camera permission requests", "webview-camera-permission-requests": "Webview camera permission requests",
"webview-camera-permission-requests-subtitle" : "When enabled, websites and dapps can ask to use your camera", "webview-camera-permission-requests-subtitle": "When enabled, websites and dapps can ask to use your camera",
"page-would-like-to-use-camera" : "would like to use your camera", "page-would-like-to-use-camera": "would like to use your camera",
"page-camera-request-blocked" : "camera requests blocked. To enable camera requests go to Settings", "page-camera-request-blocked": "camera requests blocked. To enable camera requests go to Settings",
"nickname": "Nickname", "nickname": "Nickname",
"add-nickname": "Add a nickname (optional)", "add-nickname": "Add a nickname (optional)",
"nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames youve added", "nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames youve added",
@ -1505,11 +1506,11 @@
"statuses-descr": "Share whats on your mind and stay updated with your contacts", "statuses-descr": "Share whats on your mind and stay updated with your contacts",
"new-status": "New status", "new-status": "New status",
"chat-link-previews": "Chat link previews", "chat-link-previews": "Chat link previews",
"you-can-choose-preview-websites" : "You can choose which of the following websites can preview link of descriptions and pictures in chats", "you-can-choose-preview-websites": "You can choose which of the following websites can preview link of descriptions and pictures in chats",
"previewing-may-share-metadata" : "Previewing links from these websites may share your metadata with their owners", "previewing-may-share-metadata": "Previewing links from these websites may share your metadata with their owners",
"websites" : "Websites", "websites": "Websites",
"enable-all" : "Enable all", "enable-all": "Enable all",
"disable-all" : "Disable all", "disable-all": "Disable all",
"warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.", "warning-sending-to-contract-descr": "The address you entered is a smart contract, sending funds to this address may result in loss of funds. To interact with a DApp, open the DApp in the Status DApp Browser.",
"dont-ask": "Don't ask me again", "dont-ask": "Don't ask me again",
"enable-link-previews": "Enable link previews in chat?", "enable-link-previews": "Enable link previews in chat?",
@ -1517,7 +1518,7 @@
"external-storage-denied": "Access to external storage is denied", "external-storage-denied": "Access to external storage is denied",
"timeline": "Timeline", "timeline": "Timeline",
"main-account": "Main account", "main-account": "Main account",
"ethereum-address":"Ethereum address", "ethereum-address": "Ethereum address",
"default-assets": "Default ERC20 and ERC721", "default-assets": "Default ERC20 and ERC721",
"increase-gas": "Increase Gas", "increase-gas": "Increase Gas",
"cancelling": "Cancelling", "cancelling": "Cancelling",
@ -1719,7 +1720,7 @@
"minimum-received": "Minimum received", "minimum-received": "Minimum received",
"powered-by-paraswap": "Powered by Paraswap", "powered-by-paraswap": "Powered by Paraswap",
"priority": "Priority", "priority": "Priority",
"switch-to-simple-interface":"Switch to simple interface", "switch-to-simple-interface": "Switch to simple interface",
"transaction-fee": "Transaction fee", "transaction-fee": "Transaction fee",
"swap-details": "Swap details", "swap-details": "Swap details",
"slippage": "Slippage", "slippage": "Slippage",