whispervis/network_selector.go

157 lines
3.5 KiB
Go
Raw Normal View History

2018-09-18 14:01:13 +00:00
package main
import (
2018-09-19 09:02:35 +00:00
"bytes"
2018-09-18 16:01:45 +00:00
"fmt"
2018-09-18 14:01:13 +00:00
"github.com/gopherjs/vecty"
"github.com/gopherjs/vecty/elem"
"github.com/gopherjs/vecty/event"
2018-09-19 09:02:35 +00:00
"github.com/status-im/whispervis/widgets"
2018-09-18 14:01:13 +00:00
)
// NetworkSelector represents widget for choosing or uploading network topology
// to be used for visualization.
type NetworkSelector struct {
vecty.Core
2018-09-18 14:35:16 +00:00
current *Network
2018-09-18 16:01:45 +00:00
isCustom bool
2018-09-18 14:35:16 +00:00
networks map[string]*Network
2018-09-18 16:01:45 +00:00
2018-09-19 09:02:35 +00:00
upload *widgets.UploadWidget
handler func(*Network) // executed on network change
2018-09-18 14:01:13 +00:00
}
// NewNetworkSelector creates new NetworkSelector.
2018-09-18 16:01:45 +00:00
func NewNetworkSelector(handler func(*Network)) *NetworkSelector {
current := &Network{}
networks, err := LoadNetworks()
if err != nil {
fmt.Println("No networks loaded:", err)
} else {
current = networks["net100.json"]
}
2018-09-19 09:02:35 +00:00
ns := &NetworkSelector{
2018-09-18 16:01:45 +00:00
networks: networks,
current: current,
handler: handler,
}
2018-09-19 09:02:35 +00:00
ns.upload = widgets.NewUploadWidget(ns.onUpload)
2018-09-19 09:45:54 +00:00
ns.setCurrentNetwork(current)
2018-09-19 09:02:35 +00:00
return ns
2018-09-18 14:01:13 +00:00
}
// Render implements the vecty.Component interface.
func (n *NetworkSelector) Render() vecty.ComponentOrHTML {
return elem.Div(
elem.Heading3(vecty.Text("Choose network:")),
elem.Select(
vecty.Markup(
event.Change(n.onChange),
),
2018-09-18 16:01:45 +00:00
n.networkOptions(),
2018-09-18 14:01:13 +00:00
elem.Option(
vecty.Markup(
vecty.Property("value", "upload"),
2018-09-18 16:01:45 +00:00
vecty.Property("selected", n.isCustom),
2018-09-18 14:01:13 +00:00
),
vecty.Text("Upload custom..."),
),
),
n.descriptionBlock(),
2018-09-19 09:02:35 +00:00
vecty.If(n.isCustom, n.upload),
2018-09-18 14:01:13 +00:00
)
}
2018-09-19 16:11:02 +00:00
// descriptionBlock renders the block with network description.
2018-09-18 14:01:13 +00:00
func (n *NetworkSelector) descriptionBlock() *vecty.HTML {
return elem.Div(
vecty.Markup(
vecty.Style("padding", "7px"),
vecty.Style("font-style", "italic"),
vecty.Style("color", "blue"),
),
2018-09-18 14:35:16 +00:00
vecty.Text(n.current.Description),
2018-09-18 14:01:13 +00:00
)
}
2018-09-18 16:01:45 +00:00
// LoadNetworks imports preloaded neworks from the directory with JSON files.
func LoadNetworks() (map[string]*Network, error) {
files, err := AssetDir("data")
if err != nil {
return nil, err
}
networks := map[string]*Network{}
for _, file := range files {
network, err := LoadNetwork("data/" + file)
if err != nil {
return nil, fmt.Errorf("load network: %v", err)
}
networks[file] = network
}
return networks, nil
}
2018-09-19 16:11:02 +00:00
// networkOptions renders 'option' elements for network 'select' input tag.
2018-09-18 16:01:45 +00:00
func (n *NetworkSelector) networkOptions() vecty.List {
var options vecty.List
2018-09-19 09:45:54 +00:00
for name := range n.networks {
2018-09-18 16:01:45 +00:00
options = append(options, elem.Option(
vecty.Markup(
vecty.Property("value", name),
2018-09-19 09:45:54 +00:00
vecty.Property("selected", n.current.Name == "data/"+name), // TODO(divan): get rid of "data"
2018-09-18 16:01:45 +00:00
),
vecty.Text(name),
))
}
return options
}
2018-09-19 09:02:35 +00:00
2018-09-19 09:45:54 +00:00
// onChange implements handler for select input changed value
func (n *NetworkSelector) onChange(e *vecty.Event) {
value := e.Target.Get("value").String()
if value == "upload" {
n.isCustom = true
vecty.Rerender(n)
return
}
n.isCustom = false
net := n.networks[value]
n.setCurrentNetwork(net)
vecty.Rerender(n)
}
2018-09-19 09:02:35 +00:00
// onUpload implements callback for "Upload" button clicked event.
func (n *NetworkSelector) onUpload(json []byte) {
r := bytes.NewReader(json)
net, err := LoadNetworkFromReader(r)
if err != nil {
fmt.Printf("[ERROR] Load network: %v", err)
}
net.Name = fmt.Sprintf("Uploaded (%d nodes)", net.NodesCount())
2018-09-19 09:45:54 +00:00
2018-09-19 09:02:35 +00:00
n.networks[net.Name] = net
2018-09-19 09:45:54 +00:00
n.setCurrentNetwork(net)
vecty.Rerender(n)
}
// setCurrentNetwork changes current network and runs needed update handlers.
func (n *NetworkSelector) setCurrentNetwork(net *Network) {
2018-09-19 09:02:35 +00:00
n.current = net
if n.handler != nil {
go n.handler(n.current)
}
}