|
| 1 | +module Lumi.Components2.QRCode where |
| 2 | + |
| 3 | +import Prelude |
| 4 | +import Data.Maybe (Maybe(..)) |
| 5 | +import Data.Newtype (class Newtype) |
| 6 | +import Data.Nullable as Nullable |
| 7 | +import Effect (Effect) |
| 8 | +import Effect.Unsafe (unsafePerformEffect) |
| 9 | +import Lumi.Components (LumiComponent, lumiComponent) |
| 10 | +import Lumi.Styles (toCSS) |
| 11 | +import Lumi.Styles.QRCode as Styles.QRCode |
| 12 | +import Lumi.Styles.Theme (useTheme) |
| 13 | +import React.Basic.DOM as R |
| 14 | +import React.Basic.Emotion as E |
| 15 | +import React.Basic.Hooks (type (/\), Hook, ReactComponent, Ref, UnsafeReference(..), UseEffect, UseMemo, UseRef, UseState, coerceHook, element, useEffect, useMemo, useRef, useState, (/\)) |
| 16 | +import React.Basic.Hooks as React |
| 17 | +import Web.DOM (Node) |
| 18 | +import Web.HTML.History (URL(..)) |
| 19 | + |
| 20 | +newtype UseQRCode hooks |
| 21 | + = UseQRCode |
| 22 | + ( UseEffect |
| 23 | + (UnsafeReference (LumiComponent ())) |
| 24 | + ( UseState |
| 25 | + (Maybe URL) |
| 26 | + ( UseMemo |
| 27 | + (String /\ ErrorCorrectLevel) |
| 28 | + (LumiComponent ()) |
| 29 | + (UseRef (Nullable.Nullable Node) hooks) |
| 30 | + ) |
| 31 | + ) |
| 32 | + ) |
| 33 | + |
| 34 | +derive instance ntUseQRCode :: Newtype (UseQRCode hooks) _ |
| 35 | + |
| 36 | +data ErrorCorrectLevel |
| 37 | + = ECLLow |
| 38 | + | ECLMedium |
| 39 | + | ECLQuality |
| 40 | + | ECLHigh |
| 41 | + |
| 42 | +derive instance eqErrorCorrectLevel :: Eq ErrorCorrectLevel |
| 43 | + |
| 44 | +errorCorrectLevelToString :: ErrorCorrectLevel -> String |
| 45 | +errorCorrectLevelToString = case _ of |
| 46 | + ECLLow -> "L" |
| 47 | + ECLMedium -> "M" |
| 48 | + ECLQuality -> "Q" |
| 49 | + ECLHigh -> "H" |
| 50 | + |
| 51 | +useQRCode :: ErrorCorrectLevel -> String -> Hook UseQRCode { qrcode :: LumiComponent (), url :: Maybe URL } |
| 52 | +useQRCode level value = |
| 53 | + coerceHook React.do |
| 54 | + ref <- useRef Nullable.null |
| 55 | + qrcode <- |
| 56 | + useMemo (value /\ level) \_ -> |
| 57 | + unsafePerformEffect do |
| 58 | + lumiComponent "QRCode" {} \props -> React.do |
| 59 | + theme <- useTheme |
| 60 | + pure |
| 61 | + $ E.element R.div' |
| 62 | + { children: |
| 63 | + [ element qrcode_ |
| 64 | + { value |
| 65 | + , level: errorCorrectLevelToString level |
| 66 | + , renderAs: "svg" |
| 67 | + , xmlns: "http://www.w3.org/2000/svg" |
| 68 | + , size: Nullable.null |
| 69 | + , bgColor: "rgba(255,255,255,0.0)" |
| 70 | + , fgColor: "rgba(0,0,0,1.0)" |
| 71 | + } |
| 72 | + ] |
| 73 | + , ref |
| 74 | + , className: props.className |
| 75 | + , css: toCSS theme props Styles.QRCode.qrcode |
| 76 | + } |
| 77 | + url /\ setUrl <- useState Nothing |
| 78 | + useEffect (UnsafeReference qrcode) do |
| 79 | + svgUrl <- generateSVGUrl ref |
| 80 | + setUrl \_ -> Just $ URL svgUrl.url |
| 81 | + pure svgUrl.dispose |
| 82 | + pure { qrcode, url } |
| 83 | + |
| 84 | +foreign import qrcode_ :: |
| 85 | + ReactComponent |
| 86 | + { value :: String |
| 87 | + , level :: String |
| 88 | + , renderAs :: String |
| 89 | + , xmlns :: String |
| 90 | + , size :: Nullable.Nullable Int |
| 91 | + , bgColor :: String |
| 92 | + , fgColor :: String |
| 93 | + } |
| 94 | + |
| 95 | +foreign import generateSVGUrl :: Ref (Nullable.Nullable Node) -> Effect { url :: String, dispose :: Effect Unit } |
0 commit comments