html_container.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package ethui
  2. import (
  3. "errors"
  4. "github.com/ethereum/eth-go/ethchain"
  5. "github.com/ethereum/eth-go/ethpub"
  6. "github.com/ethereum/eth-go/ethutil"
  7. "github.com/go-qml/qml"
  8. "github.com/howeyc/fsnotify"
  9. "io/ioutil"
  10. "log"
  11. "net/url"
  12. "os"
  13. "path"
  14. "path/filepath"
  15. )
  16. type HtmlApplication struct {
  17. win *qml.Window
  18. webView qml.Object
  19. engine *qml.Engine
  20. lib *UiLib
  21. path string
  22. watcher *fsnotify.Watcher
  23. }
  24. func NewHtmlApplication(path string, lib *UiLib) *HtmlApplication {
  25. engine := qml.NewEngine()
  26. return &HtmlApplication{engine: engine, lib: lib, path: path}
  27. }
  28. func (app *HtmlApplication) Create() error {
  29. component, err := app.engine.LoadFile(app.lib.AssetPath("qml/webapp.qml"))
  30. if err != nil {
  31. return err
  32. }
  33. if filepath.Ext(app.path) == "eth" {
  34. return errors.New("Ethereum package not yet supported")
  35. // TODO
  36. ethutil.OpenPackage(app.path)
  37. }
  38. win := component.CreateWindow(nil)
  39. win.Set("url", app.path)
  40. webView := win.ObjectByName("webView")
  41. app.win = win
  42. app.webView = webView
  43. return nil
  44. }
  45. func (app *HtmlApplication) RootFolder() string {
  46. folder, err := url.Parse(app.path)
  47. if err != nil {
  48. return ""
  49. }
  50. return path.Dir(folder.RequestURI())
  51. }
  52. func (app *HtmlApplication) RecursiveFolders() []os.FileInfo {
  53. files, _ := ioutil.ReadDir(app.RootFolder())
  54. var folders []os.FileInfo
  55. for _, file := range files {
  56. if file.IsDir() {
  57. folders = append(folders, file)
  58. }
  59. }
  60. return folders
  61. }
  62. func (app *HtmlApplication) NewWatcher(quitChan chan bool) {
  63. var err error
  64. app.watcher, err = fsnotify.NewWatcher()
  65. if err != nil {
  66. return
  67. }
  68. err = app.watcher.Watch(app.RootFolder())
  69. if err != nil {
  70. log.Fatal(err)
  71. }
  72. for _, folder := range app.RecursiveFolders() {
  73. fullPath := app.RootFolder() + "/" + folder.Name()
  74. app.watcher.Watch(fullPath)
  75. }
  76. go func() {
  77. out:
  78. for {
  79. select {
  80. case <-quitChan:
  81. app.watcher.Close()
  82. break out
  83. case <-app.watcher.Event:
  84. //logger.Debugln("Got event:", ev)
  85. app.webView.Call("reload")
  86. case err := <-app.watcher.Error:
  87. // TODO: Do something here
  88. logger.Infoln("Watcher error:", err)
  89. }
  90. }
  91. }()
  92. }
  93. func (app *HtmlApplication) Engine() *qml.Engine {
  94. return app.engine
  95. }
  96. func (app *HtmlApplication) Window() *qml.Window {
  97. return app.win
  98. }
  99. func (app *HtmlApplication) NewBlock(block *ethchain.Block) {
  100. b := &ethpub.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())}
  101. app.webView.Call("onNewBlockCb", b)
  102. }
  103. func (app *HtmlApplication) ObjectChanged(stateObject *ethchain.StateObject) {
  104. app.webView.Call("onObjectChangeCb", ethpub.NewPStateObject(stateObject))
  105. }
  106. func (app *HtmlApplication) StorageChanged(storageObject *ethchain.StorageState) {
  107. app.webView.Call("onStorageChangeCb", ethpub.NewPStorageState(storageObject))
  108. }
  109. func (app *HtmlApplication) Destroy() {
  110. app.engine.Destroy()
  111. }