diff --git a/.prettierrc.js b/.prettierrc.js index 23fee66cf1..701869e460 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,6 +1,7 @@ module.exports = { bracketSpacing: false, - jsxBracketSameLine: true, + bracketSameLine: true, singleQuote: true, trailingComma: 'all', - }; \ No newline at end of file + tabWidth: 4, +}; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index fa134b6ecc..df45d1dc77 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -640,7 +640,7 @@ SPEC CHECKSUMS: FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e Folly: b73c3869541e86821df3c387eb0af5f65addfab4 - glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db + glog: 64a900d72fb14cd1b2cdf3b717a5555ceb889d49 HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352 Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8 libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c diff --git a/resources/images/icons/message-gap-info12@2x.png b/resources/images/icons/message-gap-info12@2x.png new file mode 100644 index 0000000000..21bb6d544f Binary files /dev/null and b/resources/images/icons/message-gap-info12@2x.png differ diff --git a/resources/images/icons/message-gap-info12@3x.png b/resources/images/icons/message-gap-info12@3x.png new file mode 100644 index 0000000000..88373e558e Binary files /dev/null and b/resources/images/icons/message-gap-info12@3x.png differ diff --git a/resources/images/ui/message-gap-circle-bg-dark@2x.png b/resources/images/ui/message-gap-circle-bg-dark@2x.png new file mode 100644 index 0000000000..5912ef9bfc Binary files /dev/null and b/resources/images/ui/message-gap-circle-bg-dark@2x.png differ diff --git a/resources/images/ui/message-gap-circle-bg-dark@3x.png b/resources/images/ui/message-gap-circle-bg-dark@3x.png new file mode 100644 index 0000000000..fef2d8f0f0 Binary files /dev/null and b/resources/images/ui/message-gap-circle-bg-dark@3x.png differ diff --git a/resources/images/ui/message-gap-circle-bg-light@2x.png b/resources/images/ui/message-gap-circle-bg-light@2x.png new file mode 100644 index 0000000000..1d0e919437 Binary files /dev/null and b/resources/images/ui/message-gap-circle-bg-light@2x.png differ diff --git a/resources/images/ui/message-gap-circle-bg-light@3x.png b/resources/images/ui/message-gap-circle-bg-light@3x.png new file mode 100644 index 0000000000..4920191385 Binary files /dev/null and b/resources/images/ui/message-gap-circle-bg-light@3x.png differ diff --git a/resources/images/ui/message-gap-hborder-dark@2x.png b/resources/images/ui/message-gap-hborder-dark@2x.png new file mode 100644 index 0000000000..987875372f Binary files /dev/null and b/resources/images/ui/message-gap-hborder-dark@2x.png differ diff --git a/resources/images/ui/message-gap-hborder-dark@3x.png b/resources/images/ui/message-gap-hborder-dark@3x.png new file mode 100644 index 0000000000..f2d4ce3318 Binary files /dev/null and b/resources/images/ui/message-gap-hborder-dark@3x.png differ diff --git a/resources/images/ui/message-gap-hborder-light@2x.png b/resources/images/ui/message-gap-hborder-light@2x.png new file mode 100644 index 0000000000..9793be9871 Binary files /dev/null and b/resources/images/ui/message-gap-hborder-light@2x.png differ diff --git a/resources/images/ui/message-gap-hborder-light@3x.png b/resources/images/ui/message-gap-hborder-light@3x.png new file mode 100644 index 0000000000..4f02fa4092 Binary files /dev/null and b/resources/images/ui/message-gap-hborder-light@3x.png differ diff --git a/resources/images/ui/message-gap-vborder-light@2x.png b/resources/images/ui/message-gap-vborder-light@2x.png new file mode 100644 index 0000000000..c564acbbbc Binary files /dev/null and b/resources/images/ui/message-gap-vborder-light@2x.png differ diff --git a/resources/images/ui/message-gap-vborder-light@3x.png b/resources/images/ui/message-gap-vborder-light@3x.png new file mode 100644 index 0000000000..bb5cdef1db Binary files /dev/null and b/resources/images/ui/message-gap-vborder-light@3x.png differ diff --git a/src/quo2/components/messages_gap.cljs b/src/quo2/components/messages_gap.cljs new file mode 100644 index 0000000000..03b5d77d5f --- /dev/null +++ b/src/quo2/components/messages_gap.cljs @@ -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]]))) diff --git a/src/quo2/screens/main.cljs b/src/quo2/screens/main.cljs index 7468eb7f45..e729b33565 100644 --- a/src/quo2/screens/main.cljs +++ b/src/quo2/screens/main.cljs @@ -1,28 +1,29 @@ (ns quo2.screens.main - (:require [quo.react-native :as rn] - [quo.theme :as theme] + (:require [quo.components.safe-area :as safe-area] + [quo.core :as quo] [quo.design-system.colors :as colors] - [re-frame.core :as re-frame] - [quo2.screens.button :as button] - [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] + [quo.react-native :as rn] + [quo.theme :as theme] [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.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.segmented :as segmented] [quo2.screens.info-message :as info-message] [quo2.screens.information-box :as information-box] - [quo.components.safe-area :as safe-area] + [quo2.screens.messages-gap :as messages-gap] [quo2.screens.permission-tag :as permission-tag] - [quo2.screens.community-card-view :as community-card] - [quo2.screens.filter-tags :as filter-tags] - [quo.core :as quo])) + [quo2.screens.segmented :as segmented] + [quo2.screens.status-tags :as status-tags] + [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 :insets {:top false} @@ -42,6 +43,9 @@ {:name :quo2-status-tags :insets {:top false} :component status-tags/preview-status-tags} + {:name :quo2-messages-gap + :insets {:top false} + :component messages-gap/preview-messages-gap} {:name :quo2-context-tags :insets {:top false} :component context-tags/preview-context-tags} diff --git a/src/quo2/screens/messages_gap.cljs b/src/quo2/screens/messages_gap.cljs new file mode 100644 index 0000000000..9f87c7ad38 --- /dev/null +++ b/src/quo2/screens/messages_gap.cljs @@ -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}]]) diff --git a/translations/en.json b/translations/en.json index 9ab5558121..6ff9d2ed98 100644 --- a/translations/en.json +++ b/translations/en.json @@ -11,6 +11,7 @@ "account-color": "Account color", "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-gap-warning": "Some messages might be missing", "accept-new-chats-from": "Accept new chats from", "account-name": "Account name", "account-settings": "Account settings", @@ -547,7 +548,7 @@ "migration-successful": "Migration successful", "migration-successful-text": "Account succesfully migrated to Keycard", "skip": "Skip", - "password-placeholder":"Password...", + "password-placeholder": "Password...", "confirm-password-placeholder": "Confirm your password...", "enter-pin": "Enter 6-digit passcode", "enter-puk-code": "Enter PUK code", @@ -613,7 +614,7 @@ "group-chat-members-count": "{{selected}}/{{max}} members", "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", - "leave-chat":"Leave chat", + "leave-chat": "Leave chat", "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.", "group-chat-all-contacts-invited": "All your contacts are already in the group", @@ -1005,7 +1006,7 @@ "paired-devices": "Paired devices", "pairing": "Pairing", "pairing-card": "Pairing card", - "pairing-code-placeholder":"Pairing code...", + "pairing-code-placeholder": "Pairing code...", "pairing-code_error1": "Pairing codes don't match.", "confirm-pairing-code-placeholder": "Confirm your pairing code...", "pairing-go-to-installation": "Go to pairing settings", @@ -1434,10 +1435,10 @@ "give-permissions-camera": "Give permission\nto access camera", "photos": "Photos", "image": "Image", - "sign-anyway" : "Sign anyway", - "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.", - "set-custom-fee" : "Set custom fee", + "sign-anyway": "Sign anyway", + "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.", + "set-custom-fee": "Set custom fee", "not-enough-snt": "Not enough SNT", "add-new-contact": "Add new contact", "you-dont-have-contacts": "You don’t have any contacts yet.", @@ -1457,10 +1458,10 @@ "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-see-sticker": "Update to latest version to see a nice sticker here!", - "webview-camera-permission-requests" : "Webview camera permission requests", - "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-camera-request-blocked" : "camera requests blocked. To enable camera requests go to Settings", + "webview-camera-permission-requests": "Webview camera permission requests", + "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-camera-request-blocked": "camera requests blocked. To enable camera requests go to Settings", "nickname": "Nickname", "add-nickname": "Add a nickname (optional)", "nickname-description": "Nicknames help you identify others in Status.\nOnly you can see the nicknames you’ve added", @@ -1505,11 +1506,11 @@ "statuses-descr": "Share what’s on your mind and stay updated with your contacts", "new-status": "New status", "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", - "previewing-may-share-metadata" : "Previewing links from these websites may share your metadata with their owners", - "websites" : "Websites", - "enable-all" : "Enable all", - "disable-all" : "Disable all", + "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", + "websites": "Websites", + "enable-all": "Enable 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.", "dont-ask": "Don't ask me again", "enable-link-previews": "Enable link previews in chat?", @@ -1517,7 +1518,7 @@ "external-storage-denied": "Access to external storage is denied", "timeline": "Timeline", "main-account": "Main account", - "ethereum-address":"Ethereum address", + "ethereum-address": "Ethereum address", "default-assets": "Default ERC20 and ERC721", "increase-gas": "Increase Gas", "cancelling": "Cancelling", @@ -1719,7 +1720,7 @@ "minimum-received": "Minimum received", "powered-by-paraswap": "Powered by Paraswap", "priority": "Priority", - "switch-to-simple-interface":"Switch to simple interface", + "switch-to-simple-interface": "Switch to simple interface", "transaction-fee": "Transaction fee", "swap-details": "Swap details", "slippage": "Slippage",