Skip to content

Commit 4f327fa

Browse files
Merge pull request #1366 from input-output-hk/ffakenz/fix-new-tx-selecting-recipient-own-addr
Fix TUI new transaction dialog goes blank
2 parents e12d18e + 9b77bcf commit 4f327fa

File tree

2 files changed

+85
-14
lines changed

2 files changed

+85
-14
lines changed

hydra-tui/src/Hydra/TUI/Forms.hs

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ import Brick.Forms (
1919
newForm,
2020
radioField,
2121
)
22-
import Brick.Types (Location (..))
22+
import Brick.Types (Location (..), Widget)
2323
import Brick.Widgets.Core (clickable, putCursor, txt, (<+>))
2424
import Cardano.Api.UTxO qualified as UTxO
2525
import Data.Map.Strict qualified as Map
2626
import Data.Text qualified as Text
2727
import Graphics.Vty (Event (..), Key (..))
2828
import Hydra.Chain.Direct.State ()
29-
import Lens.Micro (Lens')
29+
import Lens.Micro (Lens', (^.))
3030
import Prelude qualified
3131

3232
utxoCheckboxField ::
@@ -83,14 +83,15 @@ confirmRadioField =
8383

8484
radioFields = radioField id [(opt, fst opt, show $ fst opt) | opt <- options]
8585

86+
type LeftBracketChar = Char
87+
type CheckmarkChar = Char
88+
type RightBracketChar = Char
89+
8690
checkboxGroupField ::
8791
(Ord k, Ord n) =>
88-
-- | Left bracket character.
89-
Char ->
90-
-- | Checkmark character.
91-
Char ->
92-
-- | Right bracket character.
93-
Char ->
92+
LeftBracketChar ->
93+
CheckmarkChar ->
94+
RightBracketChar ->
9495
-- | The state lens for this value.
9596
Lens' (Map k (a, Bool)) (Map k (a, Bool)) ->
9697
-- | The available choices, in order.
@@ -148,3 +149,69 @@ checkboxGroupField lb check rb stLens options initialState =
148149
case Map.lookup k cur of
149150
Nothing -> return ()
150151
Just _ -> put $ Map.adjust (second not) k cur
152+
153+
type FormFieldRenderHelper a n = (a -> Text -> Bool -> Widget n -> Widget n)
154+
155+
customRadioField ::
156+
(Ord n, Eq a) =>
157+
LeftBracketChar ->
158+
CheckmarkChar ->
159+
RightBracketChar ->
160+
-- | The state lens for this value.
161+
Lens' s a ->
162+
-- | The available choices, in order. Each choice has a value
163+
-- of type @a@, a resource name, and a text label.
164+
[(a, n, Text.Text)] ->
165+
-- | Render widget helper.
166+
FormFieldRenderHelper a n ->
167+
-- | The initial form state.
168+
s ->
169+
FormFieldState s e n
170+
customRadioField lb check rb stLens options decorator initialState =
171+
let initVal = initialState ^. stLens
172+
173+
lookupOptionValue n =
174+
let results = filter (\(_, n', _) -> n' == n) options
175+
in case results of
176+
[(val, _, _)] -> Just val
177+
_ -> Nothing
178+
179+
handleEvent _ (MouseDown n _ _ _) = forM_ (lookupOptionValue n) put
180+
handleEvent new (VtyEvent (EvKey (KChar ' ') [])) = put new
181+
handleEvent _ _ = return ()
182+
183+
optionFields = mkOptionField <$> options
184+
mkOptionField (val, name, lbl) =
185+
FormField
186+
name
187+
Just
188+
True
189+
(renderRadio val name lbl)
190+
(handleEvent val)
191+
in FormFieldState
192+
{ formFieldState = initVal
193+
, formFields = optionFields
194+
, formFieldLens = stLens
195+
, formFieldUpdate = const
196+
, formFieldRenderHelper = id
197+
, formFieldConcat = vBox
198+
, formFieldVisibilityMode = ShowFocusedFieldOnly
199+
}
200+
where
201+
renderRadio val name lbl foc cur =
202+
let addAttr =
203+
if foc
204+
then withDefAttr focusedFormInputAttr
205+
else id
206+
isSet = val == cur
207+
csr = if foc then putCursor name (Location (1, 0)) else id
208+
in clickable name $
209+
addAttr $
210+
csr $
211+
decorator val lbl isSet $
212+
txt $
213+
Text.concat
214+
[ Text.singleton lb
215+
, if isSet then Text.singleton check else " "
216+
, Text.singleton rb <> " " <> lbl
217+
]

hydra-tui/src/Hydra/TUI/Handlers.hs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Brick
1111
import Hydra.Cardano.Api hiding (Active)
1212
import Hydra.Chain (PostTxError (InternalWalletError, NotEnoughFuel), reason)
1313

14-
import Brick.Forms (Form (formState), editShowableFieldWithValidate, handleFormEvent, newForm, radioField)
14+
import Brick.Forms (Form (formState), editShowableFieldWithValidate, handleFormEvent, newForm)
1515
import Cardano.Api.UTxO qualified as UTxO
1616
import Data.List (nub, (\\))
1717
import Data.Map qualified as Map
@@ -34,6 +34,7 @@ import Hydra.TUI.Handlers.Global (handleVtyGlobalEvents)
3434
import Hydra.TUI.Logging.Handlers (info, report, warn)
3535
import Hydra.TUI.Logging.Types (LogMessage, LogState, LogVerbosity (..), Severity (..), logMessagesL, logVerbosityL)
3636
import Hydra.TUI.Model
37+
import Hydra.TUI.Style (own)
3738
import Lens.Micro.Mtl (use, (%=), (.=))
3839
import Prelude qualified
3940

@@ -181,16 +182,19 @@ handleVtyEventsOpen cardanoClient hydraClient utxo e = do
181182
EvKey KEsc [] -> id .= OpenHome
182183
EvKey KEnter [] -> do
183184
let amountEntered = formState i
184-
let ownAddress = mkVkAddress (networkId cardanoClient) (getVerificationKey $ sk hydraClient)
185+
let ownAddress = mkVkAddress @Era (networkId cardanoClient) (getVerificationKey $ sk hydraClient)
185186
let field =
186-
radioField
187-
id
187+
customRadioField '[' 'X' ']' id $
188188
[ (u, show u, decodeUtf8 $ encodePretty u)
189-
| u <- filter (/= ownAddress) (nub addresses)
189+
| u <- nub addresses
190190
]
191191
addresses = getRecipientAddress <$> Map.elems (UTxO.toMap utxo)
192192
getRecipientAddress TxOut{txOutAddress = addr} = addr
193-
let selectingRecipientForm = newForm [field] (Prelude.head addresses)
193+
decorator a _ _ =
194+
if a == ownAddress
195+
then withAttr own
196+
else id
197+
let selectingRecipientForm = newForm [field decorator] (Prelude.head addresses)
194198
id .= SelectingRecipient{utxoSelected, amountEntered, selectingRecipientForm}
195199
_ -> pure ()
196200
zoom enteringAmountFormL $ handleFormEvent (VtyEvent e)

0 commit comments

Comments
 (0)