Commit fed352ee authored by Cédric F.'s avatar Cédric F.

Pass coin to models to format views accordingly

parent 3b1b864c
...@@ -24,6 +24,12 @@ ...@@ -24,6 +24,12 @@
<script src="assets/js/elm.min.js" async defer></script> <script src="assets/js/elm.min.js" async defer></script>
<script>
// CONFIGURE ME:
const coin = 'BCH';
// TODO: use fuzzy search to guess coin based on hostname?
</script>
<style> <style>
/* inconsolata-regular - latin */ /* inconsolata-regular - latin */
@font-face { @font-face {
...@@ -58,10 +64,6 @@ ...@@ -58,10 +64,6 @@
background: orange; background: orange;
box-shadow: 0 0 10px 5px orange; box-shadow: 0 0 10px 5px orange;
} }
.amount::after {
content: " DCR";
}
</style> </style>
</head> </head>
<body class="bg-black text-white"> <body class="bg-black text-white">
...@@ -72,6 +74,13 @@ ...@@ -72,6 +74,13 @@
}; };
</script> </script>
<script>
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.amount::after { content: " ' + coin + '" };';
document.getElementsByTagName('head')[0].appendChild(style);
</script>
<div class="container-fluid"> <div class="container-fluid">
<div class="row" style="position:absolute;width:100%;height:100%"> <div class="row" style="position:absolute;width:100%;height:100%">
<div class="col"> <div class="col">
...@@ -95,7 +104,7 @@ ...@@ -95,7 +104,7 @@
window.addEventListener('load', () => { window.addEventListener('load', () => {
const elmAppDiv = document.querySelector('#elm-app'); const elmAppDiv = document.querySelector('#elm-app');
const elmApp = Elm.Trappisto.embed(elmAppDiv, { coin: 'BTC' }); const elmApp = Elm.Trappisto.embed(elmAppDiv, { coin: coin });
elmApp.ports.elmToJs.subscribe((command) => { elmApp.ports.elmToJs.subscribe((command) => {
console.log('Received command: ' + command); console.log('Received command: ' + command);
......
...@@ -16,26 +16,29 @@ type alias Model = ...@@ -16,26 +16,29 @@ type alias Model =
, tickets : List String , tickets : List String
, fetching : Bool , fetching : Bool
, error : Maybe String , error : Maybe String
, coin : Coin
} }
initialModel : Model initialModel : Coin -> Model
initialModel = initialModel coin =
{ address = "" { address = ""
, transactions = [] , transactions = []
, tickets = [] , tickets = []
, fetching = False , fetching = False
, error = Nothing , error = Nothing
, coin = coin
} }
modelFromJson : JsonModel -> Model modelFromJson : JsonModel -> Coin -> Model
modelFromJson jsonModel = modelFromJson jsonModel coin =
{ address = jsonModel.address { address = jsonModel.address
, transactions = List.map Transaction.modelFromJson jsonModel.transactions , transactions = List.map (\tx -> Transaction.modelFromJson tx coin) jsonModel.transactions
, tickets = [] , tickets = []
, fetching = False , fetching = False
, error = Nothing , error = Nothing
, coin = coin
} }
...@@ -144,7 +147,7 @@ update msg model = ...@@ -144,7 +147,7 @@ update msg model =
SearchRawTransactionsResult result -> SearchRawTransactionsResult result ->
case result of case result of
Ok jsonModel -> Ok jsonModel ->
( modelFromJson jsonModel, Cmd.none ) ( modelFromJson jsonModel model.coin, Cmd.none )
Err error -> Err error ->
( { model ( { model
......
...@@ -26,11 +26,12 @@ type alias Model = ...@@ -26,11 +26,12 @@ type alias Model =
, nextBlockHash : Maybe String , nextBlockHash : Maybe String
, fetching : Bool , fetching : Bool
, error : Maybe String , error : Maybe String
, coin : Coin
} }
initialModel : Model initialModel : Coin -> Model
initialModel = initialModel coin =
{ hash = "" { hash = ""
, height = -1 , height = -1
, time = -1 , time = -1
...@@ -43,6 +44,25 @@ initialModel = ...@@ -43,6 +44,25 @@ initialModel =
, nextBlockHash = Nothing , nextBlockHash = Nothing
, fetching = False , fetching = False
, error = Nothing , error = Nothing
, coin = coin
}
modelFromJson : JsonModel -> Coin -> Model
modelFromJson jsonModel coin =
{ height = jsonModel.height
, hash = jsonModel.hash
, time = Time.second * (toFloat jsonModel.time)
, confirmations = jsonModel.confirmations
, size = jsonModel.size
, ticketPrice = jsonModel.ticketPrice
, transactions = jsonModel.transactions
, tickets = jsonModel.tickets
, previousBlockHash = zeroesToNothing jsonModel.previousBlockHash
, nextBlockHash = jsonModel.nextBlockHash
, fetching = False
, error = Nothing
, coin = coin
} }
...@@ -70,45 +90,52 @@ type Msg ...@@ -70,45 +90,52 @@ type Msg
view : Model -> Html Msg view : Model -> Html Msg
view model = view model =
let let
transactions = sibbling maybeHash html =
[ dt [ class "col-3 text-right" ] [ text "stake transactions" ] [ case maybeHash of
, dd [ class "col-9" ] Nothing ->
((span [ class "mr-2" ] [ text (toString <| List.length model.tickets) ]) span [] []
:: (List.map
(\tx -> Just hash ->
a a
[ href tx, class "badge badge-secondary ml-1" ] [ class "btn btn-secondary"
[ text <| shortHash tx ] , href "javascript:void(0)"
) , onClick (GetBlock hash)
model.tickets ]
) [ text html ]
)
, dt [ class "col-3 text-right" ] [ text "normal transactions" ]
, dd [ class "col-9" ]
((span [ class "mr-2" ] [ text (toString <| List.length model.transactions) ])
:: (List.map
(\tx ->
a
[ href tx, class "badge badge-light ml-1" ]
[ text <| shortHash tx ]
)
model.transactions
)
)
] ]
in
div [ class "row align-items-center" ]
[ div [ class "col-2 text-right" ]
[ a
[ class "btn btn-secondary"
, href "javascript:void(0)"
-- FIXME: prevblock transactions list color =
, onClick (GetBlock "000000000000006fa9bf10d4a39d0cbc6ef8dc2f2db3e7841fd33b7ad973811a") case list of
[] ->
Nothing
list ->
div []
((span [ class "mr-2" ] [ text (toString <| List.length list) ])
:: (List.map
(\tx ->
a
[ href tx, class <| "ml-1 badge badge-" ++ color ]
[ text <| shortHash tx ]
)
list
)
)
|> Just
allTransactions =
case model.coin of
DCR ->
[ ( "stake transactions", transactions model.tickets "secondary" )
, ( "normal transactions", transactions model.transactions "light" )
] ]
[ text "<" ]
] _ ->
, div [ class "col-8" ] [ ( "transactions", transactions model.transactions "light" ) ]
in
div [ class "row align-items-center" ]
[ div [ class "col-1 text-right" ] (sibbling model.previousBlockHash "<")
, div [ class "col-10" ]
[ div [ div
[ class "card bg-dark" ] [ class "card bg-dark" ]
[ h5 [ class "card-header" ] [ h5 [ class "card-header" ]
...@@ -118,32 +145,36 @@ view model = ...@@ -118,32 +145,36 @@ view model =
, div [ class "card-body" ] , div [ class "card-body" ]
[ p [ class "card-text" ] [ p [ class "card-text" ]
[ dlBuilder <| [ dlBuilder <|
[ ( "height" List.concat
, Just <| [ [ ( "height"
span [] , Just <|
[ text <| toString model.height ] span []
) [ text <| formatNumber model.height ]
, ( "time" )
, Just <| , ( "time"
span [] , Just <|
[ text <| TimeExtra.toISOString model.time ] span []
) [ text <| TimeExtra.toISOString model.time ]
, ( "confirmations" )
, Just <| , ( "confirmations"
span [] , Just <|
[ text <| toString model.confirmations ] span []
) [ text <| toString model.confirmations ]
, ( "size" )
, Just <| , ( "size"
span [] , Just <|
[ text <| toString model.size ++ " bytes" ] span []
) [ text <| formatNumber model.size ++ " bytes" ]
, ( "ticket price", Maybe.map formatAmount model.ticketPrice ) )
] , ( "ticket price", Maybe.map formatAmount model.ticketPrice )
]
, allTransactions
]
] ]
] ]
] ]
] ]
, div [ class "col-1 text-left" ] (sibbling model.nextBlockHash ">")
] ]
...@@ -167,26 +198,7 @@ update msg model = ...@@ -167,26 +198,7 @@ update msg model =
GetBlockResult result -> GetBlockResult result ->
case result of case result of
Ok jsonModel -> Ok jsonModel ->
let ( modelFromJson jsonModel model.coin, Cmd.none )
previousBlockHash =
zeroesToNothing jsonModel.previousBlockHash
in
( { model
| height = jsonModel.height
, hash = jsonModel.hash
, time = Time.second * (toFloat jsonModel.time)
, confirmations = jsonModel.confirmations
, size = jsonModel.size
, ticketPrice = jsonModel.ticketPrice
, transactions = jsonModel.transactions
, tickets = jsonModel.tickets
, previousBlockHash = previousBlockHash
, nextBlockHash = jsonModel.nextBlockHash
, fetching = False
, error = Nothing
}
, Cmd.none
)
Err error -> Err error ->
( { model ( { model
......
...@@ -25,11 +25,12 @@ type alias Model = ...@@ -25,11 +25,12 @@ type alias Model =
, vOut : List VOut , vOut : List VOut
, fetching : Bool , fetching : Bool
, error : Maybe String , error : Maybe String
, coin : Coin
} }
initialModel : Model initialModel : Coin -> Model
initialModel = initialModel coin =
{ hash = "" { hash = ""
, type_ = "?" , type_ = "?"
, size = -1 , size = -1
...@@ -41,11 +42,12 @@ initialModel = ...@@ -41,11 +42,12 @@ initialModel =
, vOut = [] , vOut = []
, fetching = False , fetching = False
, error = Nothing , error = Nothing
, coin = coin
} }
modelFromJson : JsonModel -> Model modelFromJson : JsonModel -> Coin -> Model
modelFromJson jsonModel = modelFromJson jsonModel coin =
{ hash = jsonModel.hash { hash = jsonModel.hash
, type_ = computeType jsonModel , type_ = computeType jsonModel
, size = computeSize jsonModel , size = computeSize jsonModel
...@@ -57,6 +59,7 @@ modelFromJson jsonModel = ...@@ -57,6 +59,7 @@ modelFromJson jsonModel =
, vOut = List.sortBy .value jsonModel.vOut |> List.reverse , vOut = List.sortBy .value jsonModel.vOut |> List.reverse
, fetching = False , fetching = False
, error = Nothing , error = Nothing
, coin = coin
} }
...@@ -110,7 +113,7 @@ view model = ...@@ -110,7 +113,7 @@ view model =
span [] [ text "N/A (unconfirmed)" ] span [] [ text "N/A (unconfirmed)" ]
( Just hash, Nothing ) -> ( Just hash, Nothing ) ->
a [ href hash ] [ text hash ] a [ href hash ] [ text <| shortHash hash ]
( Nothing, Just height ) -> ( Nothing, Just height ) ->
a [ href <| toString height ] [ text <| toString height ] a [ href <| toString height ] [ text <| toString height ]
...@@ -118,6 +121,24 @@ view model = ...@@ -118,6 +121,24 @@ view model =
( Just hash, Just height ) -> ( Just hash, Just height ) ->
a [ href hash ] [ text <| toString height ] a [ href hash ] [ text <| toString height ]
formatFees model =
case model.coin of
DCR ->
[ ( "total sent", Just <| formatAmount (totalSent model) )
, ( "fee"
, Just <|
span []
[ formatAmount (fee model)
, span [] [ text " (" ]
, formatAmount (feePerKb model)
, span [] [ text "/kB)" ]
]
)
]
_ ->
[]
formatAddresses scriptPubKey = formatAddresses scriptPubKey =
div [] <| div [] <|
(List.map (List.map
...@@ -140,7 +161,14 @@ view model = ...@@ -140,7 +161,14 @@ view model =
"stakebase" "stakebase"
) )
] ]
, span [ class "float-right" ] [ text <| toString vIn.amountIn ] , span [ class "float-right" ]
[ text <|
(if vIn.amountIn > 0 then
toString vIn.amountIn
else
""
)
]
, div [] , div []
[ (case vIn.txId of [ (case vIn.txId of
Just hash -> Just hash ->
...@@ -168,7 +196,7 @@ view model = ...@@ -168,7 +196,7 @@ view model =
) )
in in
div [ class "row" ] div [ class "row" ]
[ div [ class "col-8 offset-2" ] [ div [ class "col-12 col-xl-10 offset-xl-1" ]
[ div [ div
[ class "card bg-dark" ] [ class "card bg-dark" ]
[ h5 [ class "card-header" ] [ h5 [ class "card-header" ]
...@@ -177,33 +205,26 @@ view model = ...@@ -177,33 +205,26 @@ view model =
] ]
, div [ class "card-body" ] , div [ class "card-body" ]
[ p [ class "card-text" ] [ p [ class "card-text" ]
[ dl [ class "row" ] [ dlBuilder <|
[ dt [ class "col-3 text-right" ] [ text "type" ] List.concat
, dd [ class "col-9" ] [ [ ( "type"
[ formatType model.type_ ] , Just <| formatType model.type_
, dt [ class "col-3 text-right" ] [ text "confirmations" ] )
, dd [ class "col-9" ] , ( "confirmations"
[ text <| toString model.confirmations ] , Just <| span [] [ text <| toString model.confirmations ]
, dt [ class "col-3 text-right" ] [ text "time" ] )
, dd [ class "col-9" ] , ( "time"
[ text <| formatTime model ] , Just <| span [] [ text <| formatTime model ]
, dt [ class "col-3 text-right" ] [ text "block" ] )
, dd [ class "col-9" ] , ( "block"
[ formatBlock model.blockHash model.blockHeight ] , Just <| formatBlock model.blockHash model.blockHeight
, dt [ class "col-3 text-right" ] [ text "size" ] )
, dd [ class "col-9" ] , ( "size"
[ text <| toString model.size ++ " bytes" ] , Just <| span [] [ text <| (formatNumber model.size) ++ " bytes" ]
, dt [ class "col-3 text-right" ] [ text "total sent" ] )
, dd [ class "col-9" ] ]
[ formatAmount (totalSent model) ] , formatFees model
, dt [ class "col-3 text-right" ] [ text "fee" ]
, dd [ class "col-9" ]
[ formatAmount (fee model)
, span [] [ text " (" ]
, formatAmount (feePerKb model)
, span [] [ text "/kB)" ]
] ]
]
] ]
, hr [] [] , hr [] []
, div [ class "row" ] , div [ class "row" ]
...@@ -243,7 +264,7 @@ update msg model = ...@@ -243,7 +264,7 @@ update msg model =
GetRawTransactionResult result -> GetRawTransactionResult result ->
case result of case result of
Ok jsonModel -> Ok jsonModel ->
( modelFromJson jsonModel, Cmd.none ) ( modelFromJson jsonModel model.coin, Cmd.none )
Err error -> Err error ->
( { model ( { model
...@@ -296,7 +317,7 @@ decodeVIn = ...@@ -296,7 +317,7 @@ decodeVIn =
) )
Nothing Nothing
|> Pipeline.optionalAt [ "coinbase" ] (Decode.maybe Decode.string) Nothing |> Pipeline.optionalAt [ "coinbase" ] (Decode.maybe Decode.string) Nothing
|> Pipeline.optionalAt [ "amountin" ] Decode.float 0 |> Pipeline.optionalAt [ "amountin" ] Decode.float -1
|> Pipeline.optionalAt [ "blockheight" ] (Decode.maybe Decode.int) Nothing |> Pipeline.optionalAt [ "blockheight" ] (Decode.maybe Decode.int) Nothing
......
...@@ -6,7 +6,7 @@ import Trappisto.Update exposing (init, update, subscriptions) ...@@ -6,7 +6,7 @@ import Trappisto.Update exposing (init, update, subscriptions)
import Trappisto.View exposing (view) import Trappisto.View exposing (view)
main : Program Trappisto.Model.Config Trappisto.Model.Model Trappisto.Model.Msg main : Program Trappisto.Model.Flags Trappisto.Model.Model Trappisto.Model.Msg
main = main =
Navigation.programWithFlags Trappisto.Model.NewUrl Navigation.programWithFlags Trappisto.Model.NewUrl
{ init = init { init = init
......
...@@ -4,6 +4,12 @@ import Html exposing (..) ...@@ -4,6 +4,12 @@ import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
type Coin
= BCH
| BTC
| DCR
pluralize : Int -> String -> String pluralize : Int -> String -> String
pluralize count singular = pluralize count singular =
let let
...@@ -27,6 +33,21 @@ formatAmount float = ...@@ -27,6 +33,21 @@ formatAmount float =
[ text <| toString rounded ] [ text <| toString rounded ]
formatNumber : Int -> String
formatNumber int =
let
split digits =
if String.length digits > 3 then
digits
|> String.dropRight 3
|> split
|> (::) (String.right 3 digits)
else
[ digits ]
in
toString int |> split |> List.reverse |> String.join ","
shortHash : String -> String shortHash : String -> String
shortHash hash = shortHash hash =
String.concat [ String.left 2 hash, "...", String.right 2 hash ] String.concat [ String.left 2 hash, "...", String.right 2 hash ]
......
...@@ -8,12 +8,17 @@ import Components.Status as StatusComponent ...@@ -8,12 +8,17 @@ import Components.Status as StatusComponent
import Components.Address as AddressComponent import Components.Address as AddressComponent
import Components.Block as BlockComponent import Components.Block as BlockComponent
import Components.Transaction as TransactionComponent import Components.Transaction as TransactionComponent
import Trappisto.Helpers exposing (Coin)
type alias Config = type alias Flags =
{ coin : String } { coin : String }
type alias Config =
{ coin : Coin }
type Template type Template
= Status = Status
| Address | Address
...@@ -38,16 +43,16 @@ type alias Model = ...@@ -38,16 +43,16 @@ type alias Model =
} }
initialModel : Model initialModel : Coin -> String -> Model
initialModel = initialModel coin query =
{ config = Config "BTC" { config = Config coin
, keys = Keys False False False False False False , keys = Keys False False False False False False
, window = Window.Size 0 0 , window = Window.Size 0 0
, statusModel = StatusComponent.initialModel , statusModel = StatusComponent.initialModel
, addressModel = AddressComponent.initialModel , addressModel = AddressComponent.initialModel coin
, blockModel = BlockComponent.initialModel , blockModel = BlockComponent.initialModel coin
, transactionModel = TransactionComponent.initialModel , transactionModel = TransactionComponent.initialModel coin
, query = "" , query = query
, template = Status , template = Status
, error = Nothing , error = Nothing
, vimMode = False , vimMode = False
......
...@@ -10,6 +10,7 @@ import Components.Status as StatusComponent ...@@ -10,6 +10,7 @@ import Components.Status as StatusComponent
import Components.Address as AddressComponent import Components.Address as AddressComponent
import Components.Block as BlockComponent import Components.Block as BlockComponent
import Components.Transaction as TransactionComponent import Components.Transaction as TransactionComponent
import Trappisto.Helpers as Coin exposing (Coin)
port elmToJs : String -> Cmd msg port elmToJs : String -> Cmd msg
...@@ -18,14 +19,31 @@ port elmToJs : String -> Cmd msg ...@@ -18,14 +19,31 @@ port elmToJs : String -> Cmd msg
port jsToElm : (String -> msg) -> Sub msg port jsToElm : (String -> msg) -> Sub msg
init : Config -> Navigation.Location -> ( Model, Cmd Msg ) init : Flags -> Navigation.Location -> ( Model, Cmd Msg )
init config location = init flags location =
let let
query = query =
extractQuery location extractQuery location
coin =
case flags.coin of
"BCH" ->
Coin.BCH
"BTC" ->
Coin.BTC
"DCR" ->
Coin.DCR