package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "github.com/maxence-charriere/go-app/v9/pkg/app" ) //################################# //## ### //## Link with status component ### //## ### //################################# type linkWithStatus struct { app.Compo Ilink string IText string ILinkText string ILinkBody app.UI status bool } func newLinkWithStatus() *linkWithStatus { return &linkWithStatus{} } func (f *linkWithStatus) Link(s string) *linkWithStatus { f.Ilink = s return f } func (f *linkWithStatus) LinkBody(v app.UI) *linkWithStatus { f.ILinkBody = v return f } func (f *linkWithStatus) LinkText(s string) *linkWithStatus { return f.LinkBody(app.Text(s)) } func (f *linkWithStatus) Text(s string) *linkWithStatus { f.IText = s return f } func (f *linkWithStatus) checkStatus(ctx app.Context) { ctx.Async(func() { data := struct { Url string `json:"url"` }{ Url: f.Ilink, } jsondata, err := json.Marshal(data) if err != nil { app.Log(err) return } req, err := http.NewRequest("POST", ApiURL+"/checkonline", bytes.NewBuffer(jsondata)) if err != nil { app.Log(err) return } resp, err := http.DefaultClient.Do(req) if err != nil { app.Log(err) return } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { app.Log(err) return } jsonresp := struct { Status bool `json:"status"` }{} err = json.Unmarshal(body, &jsonresp) if err != nil { app.Log(err) return } ctx.Dispatch(func(ctx app.Context) { f.status = jsonresp.Status }) }) } func (f *linkWithStatus) OnNav(ctx app.Context) { f.checkStatus(ctx) } func (f *linkWithStatus) Render() app.UI { return app.Div(). Body( app.Div(). Style("display", "flex"). Style("gap", "20px"). Body( app.A(). Href(f.Ilink). Class("p-h3"). Class("m-t5"). Body(f.ILinkBody), app.If(f.status, app.P(). Style("color", "green"). Style("width", "fit-content"). Style("margin", "5px 0px 0px 0px"). Text("Online"), ).Else( app.P(). Style("color", "red"). Style("width", "fit-content"). Style("margin", "5px 0px 0px 0px"). Text("Offline"), ), ), app.P(). Class("m-t5"). Text(f.IText), ) } //################################# //## ### //## Text with tooltip ### //## ### //################################# type textWithTooltip struct { app.Compo ITooltip app.UI IClass string ITextClass string IText string activated bool mousex, mousey int } func newTextWithTooltip() *textWithTooltip { return &textWithTooltip{} } func (f *textWithTooltip) Class(v string) *textWithTooltip { f.IClass = app.AppendClass(f.IClass, v) return f } func (f *textWithTooltip) TextClass(v string) *textWithTooltip { f.ITextClass = app.AppendClass(f.ITextClass, v) return f } func (f *textWithTooltip) Text(v string) *textWithTooltip { f.IText = v return f } func (f *textWithTooltip) Tooltip(v app.UI) *textWithTooltip { f.ITooltip = v return f } func (f *textWithTooltip) Render() app.UI { return app.Div(). Class(f.IClass). Body( app.Span(). Class(f.ITextClass). Text(f.IText). OnMouseOver(func(ctx app.Context, e app.Event) { f.activated = true }). OnMouseMove(func(ctx app.Context, e app.Event) { f.mousex, f.mousey = app.Window().CursorPosition() }). OnMouseOut(func(ctx app.Context, e app.Event) { f.activated = false }), app.If(f.activated, app.Div(). Style("position", "fixed"). Style("overflow", "hidden"). Style("top", fmt.Sprintf("%dpx", f.mousey+20)). Style("left", fmt.Sprintf("%dpx", f.mousex+20)). Body( f.ITooltip, ), ), ) } //################################# //## ### //## Tooltip ### //## ### //################################# type toolTip struct { app.Compo }