rui_orig/appWasm.go

187 lines
4.5 KiB
Go
Raw Normal View History

2022-10-27 16:14:30 +03:00
//go:build wasm
package rui
import (
_ "embed"
2022-11-02 20:08:02 +03:00
"encoding/base64"
"path/filepath"
2022-11-01 20:13:09 +03:00
"strings"
2022-10-27 16:14:30 +03:00
"syscall/js"
)
//go:embed app_wasm.js
var wasmScripts string
type wasmApp struct {
params AppParams
createContentFunc func(Session) SessionContent
session Session
2024-03-12 19:32:22 +03:00
bridge bridge
2022-11-01 20:13:09 +03:00
close chan DataObject
2022-10-27 16:14:30 +03:00
}
func (app *wasmApp) Finish() {
app.session.close()
}
func (app *wasmApp) Params() AppParams {
params := app.params
params.SocketAutoClose = 0
return params
}
2022-11-09 13:40:08 +03:00
func debugLog(text string) {
2022-11-08 16:31:21 +03:00
js.Global().Get("console").Call("log", text)
2022-10-27 16:14:30 +03:00
}
2022-11-09 13:40:08 +03:00
func errorLog(text string) {
js.Global().Get("console").Call("log", "%c"+text, "color: #F00;")
}
2022-11-01 20:13:09 +03:00
func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
if len(args) > 0 {
2022-11-03 14:33:54 +03:00
text := args[0].String()
if ProtocolInDebugLog {
DebugLog(text)
}
if obj := ParseDataText(text); obj != nil {
2022-11-01 20:13:09 +03:00
switch command := obj.Tag(); command {
2022-11-08 16:31:21 +03:00
case "session-close":
app.close <- obj
2022-11-01 20:13:09 +03:00
default:
2024-03-12 19:32:22 +03:00
if !app.session.handleAnswer(command, obj) {
app.session.handleEvent(command, obj)
}
2022-10-27 16:14:30 +03:00
}
}
}
2022-11-01 20:13:09 +03:00
return nil
2022-10-27 16:14:30 +03:00
}
2022-11-01 20:13:09 +03:00
func (app *wasmApp) removeSession(id int) {
2022-10-27 16:14:30 +03:00
}
2022-11-01 20:13:09 +03:00
func (app *wasmApp) createSession() Session {
session := newSession(app, 0, "", ParseDataText(js.Global().Call("sessionInfo", "").String()))
2022-11-02 21:05:55 +03:00
session.setBridge(app.close, app.bridge)
2022-11-01 20:13:09 +03:00
session.setContent(app.createContentFunc(session))
return session
2022-10-27 16:14:30 +03:00
}
2022-11-02 20:08:02 +03:00
func (app *wasmApp) init(params AppParams) {
app.params = params
2022-10-27 16:14:30 +03:00
2022-11-01 20:13:09 +03:00
document := js.Global().Get("document")
body := document.Call("querySelector", "body")
2022-11-02 20:08:02 +03:00
head := document.Call("querySelector", "head")
meta := document.Call("createElement", "meta")
meta.Set("name", "viewport")
meta.Set("content", "width=device-width")
head.Call("appendChild", meta)
meta = document.Call("createElement", "base")
meta.Set("target", "_blank")
meta.Set("rel", "noopener")
head.Call("appendChild", meta)
if params.Icon != "" {
2022-11-11 12:55:58 +03:00
url := params.Icon
2022-11-02 20:08:02 +03:00
if image, ok := resources.images[params.Icon]; ok && image.fs != nil {
dataType := map[string]string{
".svg": "data:image/svg+xml",
".png": "data:image/png",
".jpg": "data:image/jpg",
".jpeg": "data:image/jpg",
".gif": "data:image/gif",
}
ext := strings.ToLower(filepath.Ext(params.Icon))
if prefix, ok := dataType[ext]; ok {
if data, err := image.fs.ReadFile(image.path); err == nil {
2022-11-11 12:55:58 +03:00
url = prefix + ";base64," + base64.StdEncoding.EncodeToString(data)
2022-11-02 20:08:02 +03:00
} else {
DebugLog(err.Error())
}
}
}
2022-11-11 12:55:58 +03:00
meta = document.Call("createElement", "link")
meta.Set("rel", "icon")
meta.Set("href", url)
head.Call("appendChild", meta)
2022-11-02 20:08:02 +03:00
}
2022-10-27 16:14:30 +03:00
2022-11-01 20:13:09 +03:00
script := document.Call("createElement", "script")
script.Set("type", "text/javascript")
script.Set("textContent", defaultScripts+wasmScripts)
body.Call("appendChild", script)
js.Global().Set("sendMessage", js.FuncOf(app.handleMessage))
app.close = make(chan DataObject)
app.session = app.createSession()
style := document.Call("createElement", "style")
css := appStyles + app.session.getCurrentTheme().cssText(app.session)
css = strings.ReplaceAll(css, `\n`, "\n")
css = strings.ReplaceAll(css, `\t`, "\t")
style.Set("textContent", css)
document.Call("querySelector", "head").Call("appendChild", style)
2022-11-08 16:31:21 +03:00
style = document.Call("createElement", "style")
style.Set("id", "ruiAnimations")
document.Call("querySelector", "head").Call("appendChild", style)
2022-11-01 20:13:09 +03:00
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
div := document.Call("createElement", "div")
div.Set("className", "ruiRoot")
div.Set("id", "ruiRootView")
viewHTML(app.session.RootView(), buffer)
div.Set("innerHTML", buffer.String())
body.Call("appendChild", div)
div = document.Call("createElement", "div")
div.Set("className", "ruiPopupLayer")
div.Set("id", "ruiPopupLayer")
div.Set("style", "visibility: hidden;")
body.Call("appendChild", div)
div = document.Call("createElement", "a")
div.Set("id", "ruiDownloader")
div.Set("download", "")
div.Set("style", "display: none;")
body.Call("appendChild", div)
2022-11-02 20:08:02 +03:00
if params.TitleColor != 0 {
2022-11-02 21:05:55 +03:00
app.bridge.callFunc("setTitleColor", params.TitleColor.cssString())
2022-11-02 20:08:02 +03:00
}
2022-11-01 20:13:09 +03:00
}
2022-10-27 16:14:30 +03:00
2022-11-01 20:13:09 +03:00
// StartApp - create the new wasmApp and start it
func StartApp(addr string, createContentFunc func(Session) SessionContent, params AppParams) {
if createContentFunc == nil {
return
2022-10-27 16:14:30 +03:00
}
2022-11-01 20:13:09 +03:00
app := new(wasmApp)
app.createContentFunc = createContentFunc
2022-11-08 16:31:21 +03:00
app.close = make(chan DataObject)
app.bridge = createWasmBridge(app.close)
2022-11-01 20:13:09 +03:00
2022-11-02 20:08:02 +03:00
app.init(params)
2022-11-01 20:13:09 +03:00
<-app.close
}
func FinishApp() {
}
func OpenBrowser(url string) bool {
return false
2022-10-27 16:14:30 +03:00
}