intrepidshape/elm-web3-ui/4.0.0

Web3.Ui.TxQueue

Many transactions in flight, without Model gymnastics.

A TxQueue is a labelled collection of Tx.Status machines keyed by correlation id. begin when the user acts, route each port Tx.Msg to its id with update, render the whole thing as a toast stack:

type alias Model =
    { txs : TxQueue }


-- user clicks buy:
{ model | txs = TxQueue.begin "buy-42" "Buy 1.2M FOO" model.txs }


-- port message for a tx:
{ model | txs = TxQueue.update incomingId txMsg model.txs }


-- in view:
TxQueue.toastStack []
    { onDismiss = DismissTx
    , explorerUrl = Just "https://scan.pulsechain.com/tx/"
    }
    model.txs

Every entry is a full Web3.Transaction state machine, so all its guarantees hold per-transaction (terminal absorbing, monotonic confirmations) -- and because messages are routed by id, one transaction's late confirmation can never touch another's state.

CSS classes: web3-txq, web3-txq__toast, web3-txq__toast--pending, --confirmed, --failed, web3-txq__label, web3-txq__status, web3-txq__dismiss.

type TxQueue

The queue. Opaque; read it through entries / pendingCount.

No transactions.

begin : String -> String -> TxQueue -> TxQueue

Start tracking a transaction under a correlation id, with a human-readable label ("Approve FOO", "Stake 50k"). Starts in AwaitingSignature -- call it when you fire the write.

update : String -> Msg -> TxQueue -> TxQueue

Route a port Tx.Msg to the transaction it belongs to. Unknown ids are ignored -- a message for a transaction you never began (or already dismissed) cannot create ghost entries.

dismiss : String -> TxQueue -> TxQueue

Remove an entry (the toast's x button).

How many transactions are still in flight.

-> List
( String
, { label : String
, status : Status
}
)

Every entry, id-ordered -- for custom renderings.

toastStack : List (Attribute msg) -> Config msg -> TxQueue -> Html msg

Render the queue as a stack of toasts (aria-live="polite" -- status changes are announced without stealing focus). Empty queue renders an empty container, so the stack can be styled position: fixed unconditionally.

type alias Config msg =
{ onDismiss : String -> msg
, explorerUrl : Maybe String
}