htmgo/framework/h/app.go

133 lines
2.2 KiB
Go
Raw Normal View History

2024-09-11 00:52:18 +00:00
package h
import (
"fmt"
2024-09-17 17:13:22 +00:00
"github.com/labstack/echo/v4"
"github.com/maddalax/htmgo/framework/htmgo/service"
"github.com/maddalax/htmgo/framework/util/process"
"log/slog"
"time"
2024-09-11 00:52:18 +00:00
)
type RequestContext struct {
echo.Context
locator *service.Locator
}
func (c *RequestContext) ServiceLocator() *service.Locator {
return c.locator
}
type AppOpts struct {
LiveReload bool
ServiceLocator *service.Locator
Register func(echo *echo.Echo)
}
2024-09-11 00:52:18 +00:00
type App struct {
Opts AppOpts
Echo *echo.Echo
2024-09-11 00:52:18 +00:00
}
var instance *App
func GetApp() *App {
if instance == nil {
panic("App instance not initialized")
}
return instance
}
func Start(opts AppOpts) {
e := echo.New()
instance := App{
Opts: opts,
Echo: e,
}
instance.start()
2024-09-11 00:52:18 +00:00
}
func (a App) start() {
2024-09-11 00:52:18 +00:00
a.Echo.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cc := &RequestContext{
c,
a.Opts.ServiceLocator,
}
return next(cc)
}
})
if a.Opts.Register != nil {
a.Opts.Register(a.Echo)
}
2024-09-11 00:52:18 +00:00
if a.Opts.LiveReload {
2024-09-17 17:13:22 +00:00
AddLiveReloadHandler("/dev/livereload", a.Echo)
2024-09-11 00:52:18 +00:00
}
port := ":3000"
2024-09-17 17:13:22 +00:00
err := a.Echo.Start(port)
2024-09-11 00:52:18 +00:00
if err != nil {
// If we are in watch mode, just try to kill any processes holding that port
// and try again
if IsDevelopment() && IsWatchMode() {
slog.Info("Port already in use, trying to kill the process and start again")
process.RunOrExit(fmt.Sprintf("kill -9 $(lsof -t -i%s)", port))
time.Sleep(time.Millisecond * 50)
2024-09-17 17:13:22 +00:00
err = a.Echo.Start(port)
if err != nil {
panic(err)
}
} else {
panic(err)
}
2024-09-11 00:52:18 +00:00
}
}
2024-09-17 17:13:22 +00:00
func HtmlView(c echo.Context, page *Page) error {
root := page.Root.Render()
2024-09-17 17:13:22 +00:00
return c.HTML(200,
2024-09-11 00:52:18 +00:00
Render(
root,
),
)
}
2024-09-17 17:13:22 +00:00
func PartialViewWithHeaders(c echo.Context, headers *Headers, partial *Partial) error {
2024-09-11 18:09:55 +00:00
if partial.Headers != nil {
for s, a := range *partial.Headers {
c.Set(s, a)
}
}
if headers != nil {
for s, a := range *headers {
c.Set(s, a)
}
}
2024-09-17 17:13:22 +00:00
return c.HTML(200,
2024-09-11 18:09:55 +00:00
Render(
partial.Root,
),
)
}
2024-09-17 17:13:22 +00:00
func PartialView(c echo.Context, partial *Partial) error {
c.Set(echo.HeaderContentType, echo.MIMETextHTML)
2024-09-11 00:52:18 +00:00
if partial.Headers != nil {
for s, a := range *partial.Headers {
c.Set(s, a)
}
}
2024-09-17 17:13:22 +00:00
return c.HTML(200,
2024-09-11 00:52:18 +00:00
Render(
partial.Root,
),
)
}