Skip to content
Snippets Groups Projects
Commit 9fe40f1c authored by Richard T. Carback III's avatar Richard T. Carback III
Browse files

Merge branch 'clientIntegration' into 'master'

Client integration

See merge request elixxir/xx-coin-game-ui!1
parents a06b3cb9 2ab19d51
No related branches found
No related tags found
No related merge requests found
client.go 0 → 100644
package main
import (
"gitlab.com/elixxir/client/api"
"gitlab.com/elixxir/client/interfaces/contact"
"gitlab.com/elixxir/client/interfaces/params"
"gitlab.com/xx_network/primitives/utils"
"io/ioutil"
"gitlab.com/elixxir/client/single"
"os"
jww "github.com/spf13/jwalterweatherman"
"time"
)
func initClient() (*api.Client, *single.Manager) {
createClient()
pass := password
storeDir := session
netParams := params.GetDefaultNetwork()
client, err := api.Login(storeDir, []byte(pass), netParams)
if err != nil {
jww.FATAL.Panicf("%+v", err)
}
_, err = client.StartNetworkFollower()
if err != nil {
jww.FATAL.Panicf("%+v", err)
}
// Wait until connected or crash on timeout
connected := make(chan bool, 10)
client.GetHealth().AddChannel(connected)
waitUntilConnected(connected)
// Make single-use manager and start receiving process
singleMng := single.NewManager(client)
client.AddService(singleMng.StartProcesses)
return client, singleMng
}
func createClient() *api.Client {
pass := password
storeDir := session
//create a new client if none exist
if _, err := os.Stat(storeDir); os.IsNotExist(err) {
// Load NDF
ndfJSON, err := ioutil.ReadFile(ndfPath)
if err != nil {
jww.FATAL.Panicf(err.Error())
}
err = api.NewClient(string(ndfJSON), storeDir,
[]byte(pass), "")
if err != nil {
jww.FATAL.Panicf("%+v", err)
}
}
netParams := params.GetDefaultNetwork()
client, err := api.OpenClient(storeDir, []byte(pass), netParams)
if err != nil {
jww.FATAL.Panicf("%+v", err)
}
return client
}
func waitUntilConnected(connected chan bool) {
timeoutTimer := time.NewTimer(90 * time.Second)
isConnected := false
//Wait until we connect or panic if we can't by a timeout
for !isConnected {
select {
case isConnected = <-connected:
jww.INFO.Printf("Network Status: %v\n",
isConnected)
break
case <-timeoutTimer.C:
jww.FATAL.Panic("timeout on connection")
}
}
// Now start a thread to empty this channel and update us
// on connection changes for debugging purposes.
go func() {
prev := true
for {
select {
case isConnected = <-connected:
if isConnected != prev {
prev = isConnected
jww.INFO.Printf(
"Network Status Changed: %v\n",
isConnected)
}
break
}
}
}()
}
func readBotContact() contact.Contact {
// Read from file
data, err := utils.ReadFile(botContactPath)
jww.INFO.Printf("Contact file size read in: %d bytes", len(data))
if err != nil {
jww.FATAL.Panicf("Failed to read contact file: %+v", err)
}
// Unmarshal contact
c, err := contact.Unmarshal(data)
if err != nil {
jww.FATAL.Panicf("Failed to unmarshal contact: %+v", err)
}
return c
}
func initLog(){
jww.SetStdoutOutput(ioutil.Discard)
logOutput, err := os.OpenFile(logPath,
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err.Error())
}
jww.SetLogOutput(logOutput)
jww.SetStdoutThreshold(jww.LevelDebug)
jww.SetLogThreshold(jww.LevelDebug)
}
\ No newline at end of file
......@@ -3,11 +3,8 @@ module gitlab.com/elixxir/xx-coin-game-ui
go 1.13
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dtylman/gowd v0.0.0-20190619113956-15e38debca22
github.com/kr/text v0.2.0 // indirect
github.com/stretchr/testify v1.6.1 // indirect
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
github.com/spf13/jwalterweatherman v1.1.0
gitlab.com/elixxir/client v1.5.1-0.20210318142430-f30312df2a7c
gitlab.com/xx_network/primitives v0.0.4-0.20210309173740-eb8cd411334a
)
This diff is collapsed.
......@@ -2,16 +2,31 @@ package main
import (
"github.com/dtylman/gowd"
"fmt"
"time"
"github.com/dtylman/gowd/bootstrap"
"gitlab.com/elixxir/client/interfaces/contact"
"gitlab.com/elixxir/client/single"
"time"
)
var password = "password"
var session = ".session"
var ndfPath = "ndf.json"
var logPath = "client.log"
var botContactPath = "botContact.bin"
var botContact contact.Contact
var singleMngr *single.Manager
var body *gowd.Element
func main() {
initLog()
botContact = readBotContact()
_, singleMngr = initClient()
// creates a new bootstrap fluid container
body = bootstrap.NewContainer(false)
......@@ -20,63 +35,105 @@ func main() {
row := bootstrap.NewRow(bootstrap.NewColumn(bootstrap.ColumnSmall, 3, div))
body.AddElement(row)
div.AddHTML(`
<label for="fname">Ethereum address:</label><br>
<input type="text" id="ethaddr" name="ethaddr"><br>
<label for="lname">Message:</label><br>
<input type="text" id="message" name="message"><br><br>`, nil)
row.SetAttribute("style", "font-size:1.5em")
ethAddr := bootstrap.NewFormInput(bootstrap.InputTypeText, "Ethereum Address:")
ethAddr.Element.Kids[1].SetAttribute("style", "font-family:'Roboto Mono', 'Courier New', Courier, monospace;")
sendText := bootstrap.NewFormInput(bootstrap.InputTypeText, "Message:")
div.AddElement(ethAddr.Element)
div.AddElement(sendText.Element)
// add a button
btn := bootstrap.NewButton(bootstrap.ButtonPrimary, "Send")
btn.OnEvent(gowd.OnClick, btnClicked)
row.AddElement(bootstrap.NewColumn(bootstrap.ColumnSmall, 3, bootstrap.NewElement("div", "well", btn)))
/*
// add some other elements from HTML
div.AddHTML(`<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu" id="dropdown-menu">
<li><a href="#">HTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
</ul>
</div>`, nil)
btn := bootstrap.NewButton(bootstrap.ButtonPrimary, "Send over xx")
btn.SetAttribute("style","background:#037281;background-color:#037281")
rtnDiv := bootstrap.NewElement("div", "well")
rtnRow := bootstrap.NewRow(bootstrap.NewColumn(bootstrap.ColumnSmall, 3, rtnDiv))
body.AddElement(rtnRow)
btnEvent := func(sender *gowd.Element, event *gowd.EventElement) {
btnClicked(sender, event, ethAddr.Element.Kids[1], sendText.Element.Kids[1], rtnDiv)
}
btn.OnEvent(gowd.OnClick, btnEvent)
div.AddElement(btn)
*/
// div.AddHTML(`
// <label for="fname">Ethereum address:</label><br>
// <input type="text" id="ethaddr" name="ethaddr"><br>
// <label for="lname">Message:</label><br>
// <input type="text" id="message" name="message"><br><br>`, nil)
//
// // add a button
// btn := bootstrap.NewButton(bootstrap.ButtonPrimary, "Send")
// btn.OnEvent(gowd.OnClick, btnClicked)
// row.AddElement(bootstrap.NewColumn(bootstrap.ColumnSmall, 3, bootstrap.NewElement("div", "well", btn)))
// start the ui loop
gowd.Run(body)
}
var lastElement *gowd.Element
// happens when the 'start' button is clicked
func btnClicked(sender *gowd.Element, event *gowd.EventElement) {
// adds a text and progress bar to the body
sender.SetText("Working...")
text := body.AddElement(gowd.NewStyledText("Working...", gowd.BoldText))
progressBar := bootstrap.NewProgressBar()
body.AddElement(progressBar.Element)
func btnClicked(sender *gowd.Element, event *gowd.EventElement, ethAddr,
sendText *gowd.Element, div *gowd.Element) {
sender.SetAttribute("disabled", "true")
sender.Parent.AddHTML(`<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>`, nil)
body.Render()
if lastElement!=nil{
div.RemoveElement(lastElement)
}
// adds test to the body
// makes the body stop responding to user events
body.Disable()
// clean up - remove the added elements
// Send the message
message := ethAddr.GetValue() + ";" + sendText.GetValue()
defer func() {
sender.SetText("Start")
body.RemoveElement(text)
body.RemoveElement(progressBar.Element)
sender.RemoveAttribute("disabled")
body.Render()
body.Enable()
}()
// render the progress bar
for i := 0; i <= 123; i++ {
progressBar.SetValue(i, 123)
text.SetText(fmt.Sprintf("Working %v", i))
time.Sleep(time.Millisecond * 20)
// this will cause the body to be refreshed
body.Render()
//text.SetText(message)
replyString := make(chan string)
// Inline function to print message from client to page, callback for upcoming function
replyFunc := func(payload []byte, err error) {
var result string
if err != nil {
result = err.Error()
} else {
result = string(payload)
}
replyString <- result
//sender.SetText("Start")
//body.RemoveElement(text)
//body.Enable()
}
err := singleMngr.TransmitSingleUse(botContact, []byte(message),
"xxCoinGame", 10, replyFunc, 30*time.Second)
if err != nil {
//body.Enable()
lastElement = div.AddElement(gowd.NewStyledText(err.Error(), gowd.BoldText))
//sender.SetText("Start")
//body.RemoveElement(text)
//body.Enable()
return
}
body.AddHTML(`<textarea readonly style="width:100%;">Client output would go here</textarea>`, nil)
result := <- replyString
lastElement = div.AddElement(gowd.NewStyledText(result, gowd.BoldText))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment