Compare commits

...
Author SHA1 Message Date
Ulises M 4a5b947afd Transformed successfully 2024-01-18 01:32:46 -06:00
Ulises M f673e442f3 test 2024-01-17 20:54:10 -06:00
Ulises M 548f212c6f Fix token input flickering 2024-01-17 18:52:14 -06:00
Ulises M f033677be8 Add custom keyboard to token-input preview 2024-01-17 18:52:14 -06:00
7 changed files with 4611 additions and 118 deletions
+4288
View File
File diff suppressed because one or more lines are too long
@@ -16,23 +16,48 @@
:flex-direction :row
:justify-content :space-between})
(defn token-name
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 8
:padding-bottom 2})
(def token-label-container
{:position :absolute
:left 32
:right 0
:bottom 0
:top 0
:flex-direction :row
:align-items :flex-end})
(def text-input-container
{:position :absolute
:top 0
:bottom 0
:left 32 ; token image size
:right 0})
(def text-input-dimensions
(assoc typography/heading-1
:font-weight "600"
:margin-left 8
:margin-right (if platform/ios? 6 4)
:padding 0
:height "100%"))
(defn text-input
[theme]
(merge typography/heading-1
{:font-weight "600"
:margin-left 8
:margin-right (if platform/ios? 6 4)
:color (colors/theme-colors colors/neutral-100 colors/white theme)
:padding 0
:text-align :center
:height "100%"}))
(assoc text-input-dimensions :color (colors/theme-colors colors/neutral-100 colors/white theme)))
(defn placeholder-text
[theme]
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))
(defn divider
[width theme]
{:height 1
:width width
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)
:margin-vertical 8})
[theme]
{:margin-vertical 8
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)})
(def data-container
{:padding-top 4
@@ -40,3 +65,7 @@
:flex-direction :row
:justify-content :space-between
:align-items :center})
(defn fiat-amount
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
+97 -61
View File
@@ -7,7 +7,6 @@
[quo.components.tags.network-tags.view :as network-tag]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.theme :as quo.theme]
[react-native.core :as rn]
@@ -15,77 +14,114 @@
(defn calc-value
[crypto? currency token value conversion]
(let [num-value (if (string? value) (parse-double (or value "0")) value)]
(let [num-value (if (string? value)
(or (parse-double value) 0)
value)]
(if crypto?
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
(str (.toFixed (/ num-value conversion) 2)
" "
(string/upper-case (or (clj->js token) ""))))))
(defn- data-info
[{:keys [theme conversion networks title crypto? currency token amount]}]
[rn/view {:style style/data-container}
[network-tag/view {:networks networks :title title}]
[text/text
{:size :paragraph-2
:weight :medium
:style (style/fiat-amount theme)}
(calc-value crypto? currency token amount conversion)]])
(defn- token-name-text
[theme text]
[text/text
{:style (style/token-name theme)
:size :paragraph-2
:weight :semi-bold}
(string/upper-case (or (clj->js text) ""))])
(defn- token-label
[{:keys [theme value text]}]
[rn/view
{:style style/token-label-container
:pointer-events :none}
[rn/text-input
{:auto-focus true
:max-length 12
:style style/text-input-dimensions
:editable false
:opacity 0
:value value}]
[token-name-text theme text]])
(defn input-section
[{:keys [on-change-text value value-atom]}]
(let [input-ref (atom nil)
set-ref #(reset! input-ref %)
focus-input #(when-let [ref ^js @input-ref]
(.focus ref))
controlled-input? (some? value)
handle-on-change-text (fn [v]
(when-not controlled-input?
(reset! value-atom v))
(when on-change-text
(on-change-text v)))]
(fn [{:keys [theme token customization-color show-keyboard? crypto? currency value]
:or {show-keyboard? true}}]
[rn/pressable
{:on-press focus-input
:style {:flex 1}}
[token/view
{:token token
:size :size-32}]
[rn/view {:style style/text-input-container}
[rn/text-input
(cond-> {:style (style/text-input theme)
:placeholder-text-color (style/placeholder-text theme)
:auto-focus true
:ref set-ref
:placeholder "0"
:keyboard-type :numeric
:max-length 12
:on-change-text handle-on-change-text
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?}
controlled-input? (assoc :value value)
(not controlled-input?) (assoc :default-value @value-atom))]]
[token-label
{:theme theme
:text (if crypto? token currency)
:value (if controlled-input? value @value-atom)}]])))
(defn- view-internal
[{external-value :value}]
(let [width (:width (rn/get-window))
value (reagent/atom nil)
crypto? (reagent/atom true)
input-ref (atom nil)
controlled-input? (some? external-value)]
(fn [{:keys [theme token currency conversion networks title customization-color
on-change-text on-swap container-style show-keyboard?]
:or {show-keyboard? true}
external-value :value}]
[rn/view
{:style (merge
(style/main-container width)
container-style)}
[{:keys [on-swap]}]
(let [width (:width (rn/get-window))
value-atom (reagent/atom nil)
crypto? (reagent/atom true)
handle-on-swap (fn []
(swap! crypto? not)
(when on-swap
(on-swap @crypto?)))]
(fn [{:keys [theme container-style value] :as props}]
[rn/view {:style (merge (style/main-container width) container-style)}
[rn/view {:style style/amount-container}
[rn/pressable
{:on-press #(when @input-ref (.focus ^js @input-ref))
:style {:flex-direction :row
:flex-grow 1
:align-items :flex-end}}
[token/view {:token token :size :size-32}]
[rn/text-input
(cond-> {:auto-focus true
:ref #(reset! input-ref %)
:placeholder "0"
:placeholder-text-color (colors/theme-colors colors/neutral-40
colors/neutral-50
theme)
:keyboard-type :numeric
:max-length 12
:on-change-text (fn [v]
(when-not controlled-input?
(reset! value v))
(when on-change-text
(on-change-text v)))
:style (style/text-input theme)
:selection-color customization-color
:show-soft-input-on-focus show-keyboard?}
controlled-input? (assoc :value external-value)
(not controlled-input?) (assoc :default-value @value))]
[text/text
{:size :paragraph-2
:weight :semi-bold
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 8
:padding-bottom 2}}
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
[input-section
(assoc props
:value-atom value-atom
:crypto? @crypto?)]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press (fn []
(swap! crypto? not)
(when on-swap
(on-swap @crypto?)))
:on-press handle-on-swap
:type :outline
:accessibility-label :reorder}
:i/reorder]]
[divider-line/view {:container-style {:margin-vertical 8}}]
[rn/view {:style style/data-container}
[network-tag/view {:networks networks :title title}]
[text/text
{:size :paragraph-2
:weight :medium
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(calc-value @crypto? currency token (or external-value @value) conversion)]]])))
[divider-line/view {:container-style (style/divider theme)}]
[data-info
(assoc props
:crypto? @crypto?
:amount (or value @value-atom))]])))
(def view (quo.theme/with-theme view-internal))
@@ -320,7 +320,7 @@
(defn- f-preview-container
[{:keys [title state descriptor blur? blur-dark-only?
component-container-style
blur-container-style blur-view-props blur-height show-blur-background?]
blur-container-style blur-view-props blur-height show-blur-background? full-screen?]
:or {blur-height 200}}
& children]
(let [theme (quo.theme/use-theme-value)
@@ -337,8 +337,11 @@
[common/navigation-bar {:title title}]
[rn/scroll-view
{:style (style/panel-basic)
:shows-vertical-scroll-indicator false}
[rn/pressable {:on-press rn/dismiss-keyboard!}
:shows-vertical-scroll-indicator false
:content-container-style (when full-screen? {:flex 1})}
[rn/pressable
{:style (when full-screen? {:flex 1})
:on-press rn/dismiss-keyboard!}
(when descriptor
[rn/view {:style style/customizer-container}
[customizer state descriptor]])
@@ -2,6 +2,7 @@
(:require
[quo.core :as quo]
[quo.foundations.resources :as resources]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
@@ -24,17 +25,29 @@
(defn view
[]
(let [state (reagent/atom {:token :eth
:currency :usd
:conversion 0.02
:networks networks
:title title
:customization-color :blue})]
(let [state (reagent/atom {:token :eth
:currency :usd
:conversion 0.02
:networks networks
:title title
:customization-color :blue
:show-keyboard? false})
value (reagent/atom "")
set-value (fn [v]
(swap! value str v))
delete (fn [_]
(swap! value #(subs % 0 (dec (count %)))))]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:component-container-style {:padding-horizontal 20
:margin-top 50
:align-items :center}}
[quo/token-input @state]])))
:full-screen? true
:component-container-style {:flex 1
:justify-content :space-between}}
[quo/token-input (assoc @state :value @value)]
[quo/numbered-keyboard
{:container-style {:padding-bottom (safe-area/get-top)}
:left-action :dot
:delete-key? true
:on-press set-value
:on-delete delete}]])))
@@ -1,42 +1,65 @@
(ns status-im.contexts.profile.settings.header.avatar
(:require [quo.core :as quo]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im.contexts.profile.settings.header.style :as style]))
[status-im.contexts.profile.settings.header.style :as style]
["react-native-reanimated" :as animated]
))
(def scroll-animation-input-range [0 50])
(def header-extrapolation-option
#_(def header-extrapolation-option
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
(defn f-avatar
[{:keys [scroll-y full-name online? profile-picture customization-color]}]
(let [image-scale-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[1 0.4]
header-extrapolation-option)
image-top-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 20]
header-extrapolation-option)
image-side-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 -20]
header-extrapolation-option)
theme (quo.theme/get-theme)]
[reanimated/view
{:style (style/avatar-container theme
image-scale-animation
image-top-margin-animation
image-side-margin-animation)}
[quo/user-avatar
{:full-name full-name
:online? online?
:profile-picture profile-picture
:status-indicator? true
:ring? true
:customization-color customization-color
:size :big}]]))
(defn f-avatar [a]
(let [sv (reanimated/use-shared-value 0)
THIS-THING (animated/useAnimatedStyle
(fn HEEEEEEY []
(js* "'worklet;'")
(js/console.log "hola")
#js{:transform #js[#js{:translateX (.-value sv)}]}
))
;image-scale-animation (reanimated/interpolate scroll-y
; scroll-animation-input-range
; [1 0.4]
; header-extrapolation-option)
;image-top-margin-animation (reanimated/interpolate scroll-y
; scroll-animation-input-range
; [0 20]
; header-extrapolation-option)
;image-side-margin-animation (reanimated/interpolate scroll-y
; scroll-animation-input-range
; [0 -20]
; header-extrapolation-option)
;theme (quo.theme/get-theme)
]
[rn/view
[quo/button {:size 56
:above :i/placeholder
:on-press (fn []
(set! (.-value sv) (reanimated/with-timing 200 #js{:duration 2000}))
)}
"Trigger change"]
[reanimated/view {:style [THIS-THING ;{:transform [{:translate-x sv}]}
{:background-color "red"
:width 20
:height 20}]
#_(style/avatar-container theme
image-scale-animation
image-top-margin-animation
image-side-margin-animation)}
#_[quo/user-avatar
{:full-name full-name
:online? online?
:profile-picture profile-picture
:status-indicator? true
:ring? true
:customization-color customization-color
:size :big}]]
]))
(defn view
[props]
+101
View File
@@ -0,0 +1,101 @@
//import {useAnimatedStyle, useDerivedValue} from 'react-native-reanimated';
const babel = require('@babel/core');
const plugin = require('./node_modules/react-native-reanimated/plugin');
// const codeString = "goog.provide(\x27status_im.contexts.profile.settings.header.avatar\x27);\nstatus_im.contexts.profile.settings.header.avatar.f_avatar \x3d (function status_im$contexts$profile$settings$header$avatar$f_avatar(a){\nvar sv \x3d react_native.reanimated.use_shared_value.call(null,(0));\nvar THIS_THING \x3d shadow.js.shim.module$react_native_reanimated.useAnimatedStyle((function status_im$contexts$profile$settings$header$avatar$f_avatar_$_HEEEEEEY(){\n\x27worklet;\x27;\n\nconsole.log(\x22hola\x22);\n\nreturn ({\x22transform\x22: [({\x22translateX\x22: sv.value})]});\n}));\nreturn null;\n});\nstatus_im.contexts.profile.settings.header.avatar.view \x3d (function status_im$contexts$profile$settings$header$avatar$view(props){\nreturn new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,\x22f\x3e\x22,\x22f\x3e\x22,1484564198),status_im.contexts.profile.settings.header.avatar.f_avatar,props], null);\n});\n"
//
// const fs = require('fs');
//
// function workletize(s) {
// return babel.transformSync(eval(s), {
// filename: '/dev/null', compact: false, plugins: [plugin]
// }).code
// }
//
// function extractStrings(filePath) {
// try {
// // Read the content of the file
// const fileContent = fs.readFileSync(filePath, 'utf8');
//
// // Use a regular expression to find all strings enclosed in double quotes
// const stringMatches = fileContent.match(
// /(?<!\\)"(goog\.provide\(.+?)"/g
// );
//
// // transforms the code
// const mod = stringMatches.map(workletize);
//
// // Return the array of matched strings
// return mod.filter(str => str !== "") || [];
// } catch (err) {
// console.error('Error reading the file:', err.message);
// return [];
// }
// }
//
// const filePath = './result/index.js';
// const result = extractStrings(filePath);
//
//
// console.log('Strings found in the file:');
// result.forEach((str, index) => {
// console.log(`${index + 1}: ${str}`);
// });
//
// // console.log(codeString);
//
// // transformedCode = babel.transformSync(codeString, {
// // filename: '/dev/null',
// // compact: false,
// // plugins: [plugin]
// // }).code
// //
// // console.log(transformedCode);
//
// // SHADOW_ENV.evalLoad
const fs = require('fs');
function transformString(inputString) {
// Customize this function based on your transformation logic
return babel.transformSync(eval(inputString), {
filename: '/dev/null', compact: false, plugins: [plugin]
}).code
}
function processFile(filePath) {
try {
// Read the content of the file
let fileContent = fs.readFileSync(filePath, 'utf8');
// Use a regular expression to find strings in the file
const stringMatches = fileContent.match(
/(?<!\\)"(goog\.provide\(.+?)"/g
);
// Apply the transformation function to each matched string
if (stringMatches) {
stringMatches.forEach(match => {
if (match.indexOf("HEEEEEEY") !== -1){
const transformedString = transformString(match);
fileContent = fileContent.replace(match, JSON.stringify(transformedString));
}
});
// Write the modified content back to the file
fs.writeFileSync(filePath, fileContent, 'utf8');
console.log('File successfully processed.');
} else {
console.log('No strings found in the file.');
}
} catch (err) {
console.error('Error processing the file:', err.message);
}
}
// Example usage
const filePath = "./result/index.js";
processFile(filePath);