105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
package plugin_ui
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/dop251/goja"
|
|
)
|
|
|
|
type ScreenManager struct {
|
|
ctx *Context
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func NewScreenManager(ctx *Context) *ScreenManager {
|
|
return &ScreenManager{
|
|
ctx: ctx,
|
|
}
|
|
}
|
|
|
|
// bind binds 'screen' to the ctx object
|
|
//
|
|
// Example:
|
|
// ctx.screen.navigateTo("/entry?id=21");
|
|
func (s *ScreenManager) bind(ctxObj *goja.Object) {
|
|
screenObj := s.ctx.vm.NewObject()
|
|
_ = screenObj.Set("onNavigate", s.jsOnNavigate)
|
|
_ = screenObj.Set("navigateTo", s.jsNavigateTo)
|
|
_ = screenObj.Set("reload", s.jsReload)
|
|
_ = screenObj.Set("loadCurrent", s.jsLoadCurrent)
|
|
|
|
_ = ctxObj.Set("screen", screenObj)
|
|
}
|
|
|
|
// jsNavigateTo navigates to a new screen
|
|
//
|
|
// Example:
|
|
// ctx.screen.navigateTo("/entry?id=21");
|
|
func (s *ScreenManager) jsNavigateTo(path string, searchParams map[string]string) {
|
|
if !strings.HasPrefix(path, "/") {
|
|
path = "/" + path
|
|
}
|
|
|
|
queryString := ""
|
|
if len(searchParams) > 0 {
|
|
query := url.Values{}
|
|
for key, value := range searchParams {
|
|
query.Add(key, value)
|
|
}
|
|
queryString = "?" + query.Encode()
|
|
}
|
|
|
|
finalPath := path + queryString
|
|
|
|
s.ctx.SendEventToClient(ServerScreenNavigateToEvent, ServerScreenNavigateToEventPayload{
|
|
Path: finalPath,
|
|
})
|
|
}
|
|
|
|
// jsReload reloads the current screen
|
|
func (s *ScreenManager) jsReload() {
|
|
s.ctx.SendEventToClient(ServerScreenReloadEvent, ServerScreenReloadEventPayload{})
|
|
}
|
|
|
|
// jsLoadCurrent calls onNavigate with the current screen data
|
|
func (s *ScreenManager) jsLoadCurrent() {
|
|
s.ctx.SendEventToClient(ServerScreenGetCurrentEvent, ServerScreenGetCurrentEventPayload{})
|
|
}
|
|
|
|
// jsOnNavigate registers a callback to be called when the current screen changes
|
|
//
|
|
// Example:
|
|
// const onNavigate = (event) => {
|
|
// console.log(event.screen);
|
|
// };
|
|
// ctx.screen.onNavigate(onNavigate);
|
|
func (s *ScreenManager) jsOnNavigate(callback goja.Callable) goja.Value {
|
|
eventListener := s.ctx.RegisterEventListener(ClientScreenChangedEvent)
|
|
|
|
eventListener.SetCallback(func(event *ClientPluginEvent) {
|
|
var payload ClientScreenChangedEventPayload
|
|
if event.ParsePayloadAs(ClientScreenChangedEvent, &payload) {
|
|
s.ctx.scheduler.ScheduleAsync(func() error {
|
|
|
|
parsedQuery, _ := url.ParseQuery(strings.TrimPrefix(payload.Query, "?"))
|
|
queryMap := make(map[string]string)
|
|
for key, value := range parsedQuery {
|
|
queryMap[key] = strings.Join(value, ",")
|
|
}
|
|
|
|
ret := map[string]interface{}{
|
|
"pathname": payload.Pathname,
|
|
"searchParams": queryMap,
|
|
}
|
|
|
|
_, err := callback(goja.Undefined(), s.ctx.vm.ToValue(ret))
|
|
return err
|
|
})
|
|
}
|
|
})
|
|
|
|
return goja.Undefined()
|
|
}
|