aboutsummaryrefslogtreecommitdiff
path: root/pkg/view
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/view')
-rw-r--r--pkg/view/auth.go97
-rw-r--r--pkg/view/filesystem.go66
-rw-r--r--pkg/view/media.go101
-rw-r--r--pkg/view/settings.go53
-rw-r--r--pkg/view/view.go7
5 files changed, 324 insertions, 0 deletions
diff --git a/pkg/view/auth.go b/pkg/view/auth.go
new file mode 100644
index 0000000..5c83eba
--- /dev/null
+++ b/pkg/view/auth.go
@@ -0,0 +1,97 @@
+package view
+
+import (
+ "encoding/base64"
+
+ "github.com/valyala/fasthttp"
+
+ "git.sr.ht/~gabrielgio/img"
+ "git.sr.ht/~gabrielgio/img/pkg/components/auth"
+ "git.sr.ht/~gabrielgio/img/pkg/ext"
+)
+
+type AuthView struct {
+ userController *auth.Controller
+}
+
+func NewAuthView(userController *auth.Controller) *AuthView {
+ return &AuthView{
+ userController: userController,
+ }
+}
+
+func (v *AuthView) LoginView(ctx *fasthttp.RequestCtx) error {
+ return img.Render[interface{}](ctx, "login.html", nil)
+}
+
+func (v *AuthView) Logout(ctx *fasthttp.RequestCtx) error {
+ cook := fasthttp.Cookie{}
+ cook.SetKey("auth")
+ cook.SetValue("")
+ cook.SetMaxAge(-1)
+ cook.SetHTTPOnly(true)
+ cook.SetSameSite(fasthttp.CookieSameSiteDefaultMode)
+ ctx.Response.Header.SetCookie(&cook)
+
+ ctx.Redirect("/", 307)
+ return nil
+}
+
+func (v *AuthView) Login(ctx *fasthttp.RequestCtx) error {
+ username := ctx.FormValue("username")
+ password := ctx.FormValue("password")
+
+ auth, err := v.userController.Login(ctx, username, password)
+ if err != nil {
+ return err
+ }
+
+ base64Auth := base64.StdEncoding.EncodeToString(auth)
+
+ cook := fasthttp.Cookie{}
+ cook.SetKey("auth")
+ cook.SetValue(base64Auth)
+ cook.SetHTTPOnly(true)
+ cook.SetSameSite(fasthttp.CookieSameSiteDefaultMode)
+ ctx.Response.Header.SetCookie(&cook)
+
+ redirect := string(ctx.FormValue("redirect"))
+ if redirect == "" {
+ ctx.Redirect("/", 307)
+ } else {
+ ctx.Redirect(redirect, 307)
+ }
+ return nil
+}
+
+func (v *AuthView) RegisterView(ctx *fasthttp.RequestCtx) error {
+ return img.Render[interface{}](ctx, "register.html", nil)
+}
+
+func (v *AuthView) Register(ctx *fasthttp.RequestCtx) error {
+ username := ctx.FormValue("username")
+ password := ctx.FormValue("password")
+
+ err := v.userController.Register(ctx, username, password)
+ if err != nil {
+ return err
+ }
+
+ ctx.Redirect("/login", 307)
+ return nil
+}
+
+func Index(ctx *fasthttp.RequestCtx) {
+ ctx.Redirect("/login", 307)
+}
+
+func (v *AuthView) SetMyselfIn(r *ext.Router) {
+ r.GET("/login", v.LoginView)
+ r.POST("/login", v.Login)
+
+ r.GET("/register", v.RegisterView)
+ r.POST("/register", v.Register)
+
+ r.GET("/logout", v.Logout)
+ r.POST("/logout", v.Logout)
+}
diff --git a/pkg/view/filesystem.go b/pkg/view/filesystem.go
new file mode 100644
index 0000000..f10d788
--- /dev/null
+++ b/pkg/view/filesystem.go
@@ -0,0 +1,66 @@
+package view
+
+import (
+ "github.com/valyala/fasthttp"
+
+ "git.sr.ht/~gabrielgio/img"
+ "git.sr.ht/~gabrielgio/img/pkg/components/filesystem"
+ "git.sr.ht/~gabrielgio/img/pkg/components/settings"
+ "git.sr.ht/~gabrielgio/img/pkg/ext"
+)
+
+type (
+ FileSystemView struct {
+ controller filesystem.Controller
+ settings settings.Repository
+ }
+ FilePage struct {
+ Page *filesystem.Page
+ ShowMode bool
+ ShowOwner bool
+ }
+)
+
+func NewFileSystemView(
+ controller filesystem.Controller,
+ settingsRepository settings.Repository,
+) *FileSystemView {
+ return &FileSystemView{
+ controller: controller,
+ settings: settingsRepository,
+ }
+}
+
+func (self *FileSystemView) Index(ctx *fasthttp.RequestCtx) error {
+ pathValue := string(ctx.FormValue("path"))
+
+ page, err := self.controller.GetPage(pathValue)
+ if err != nil {
+ return err
+ }
+
+ settings, err := self.settings.Load(ctx)
+ if err != nil {
+ return err
+ }
+
+ err = img.Render(ctx, "fs.html", &img.HTMLView[*FilePage]{
+ Title: pathValue,
+ Data: &FilePage{
+ Page: page,
+ ShowMode: settings.ShowMode,
+ ShowOwner: settings.ShowOwner,
+ },
+ })
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (self *FileSystemView) SetMyselfIn(r *ext.Router) {
+ r.GET("/", self.Index)
+ r.POST("/", self.Index)
+ r.GET("/fs/", self.Index)
+ r.POST("/fs/", self.Index)
+}
diff --git a/pkg/view/media.go b/pkg/view/media.go
new file mode 100644
index 0000000..22f950d
--- /dev/null
+++ b/pkg/view/media.go
@@ -0,0 +1,101 @@
+package view
+
+import (
+ "strconv"
+
+ "github.com/valyala/fasthttp"
+
+ "git.sr.ht/~gabrielgio/img"
+ "git.sr.ht/~gabrielgio/img/pkg/components/media"
+ "git.sr.ht/~gabrielgio/img/pkg/ext"
+)
+
+type (
+ MediaView struct {
+ mediaRepository media.Repository
+ }
+
+ Page struct {
+ Medias []*media.Media
+ Next *media.Pagination
+ }
+)
+
+func getPagination(ctx *fasthttp.RequestCtx) *media.Pagination {
+ var (
+ size int
+ page int
+ sizeStr = string(ctx.FormValue("size"))
+ pageStr = string(ctx.FormValue("page"))
+ )
+
+ if sizeStr == "" {
+ size = 100
+ } else if s, err := strconv.Atoi(sizeStr); err != nil {
+ size = 100
+ } else {
+ size = s
+ }
+
+ if pageStr == "" {
+ page = 0
+ } else if p, err := strconv.Atoi(pageStr); err != nil {
+ page = 0
+ } else {
+ page = p
+ }
+
+ return &media.Pagination{
+ Page: page,
+ Size: size,
+ }
+}
+
+func NewMediaView(mediaRepository media.Repository) *MediaView {
+ return &MediaView{
+ mediaRepository: mediaRepository,
+ }
+}
+
+func (self *MediaView) Index(ctx *fasthttp.RequestCtx) error {
+ p := getPagination(ctx)
+ medias, err := self.mediaRepository.List(ctx, p)
+ if err != nil {
+ return err
+ }
+
+ err = img.Render(ctx, "media.html", &img.HTMLView[*Page]{
+ Title: "Media",
+ Data: &Page{
+ Medias: medias,
+ Next: &media.Pagination{
+ Size: p.Size,
+ Page: p.Page + 1,
+ },
+ },
+ })
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (self *MediaView) GetImage(ctx *fasthttp.RequestCtx) error {
+ pathHash := string(ctx.FormValue("path_hash"))
+
+ media, err := self.mediaRepository.Get(ctx, pathHash)
+ if err != nil {
+ return err
+ }
+
+ ctx.Response.Header.SetContentType(media.MIMEType)
+ ctx.SendFile(media.Path)
+ return nil
+}
+
+func (self *MediaView) SetMyselfIn(r *ext.Router) {
+ r.GET("/media", self.Index)
+ r.POST("/media", self.Index)
+
+ r.GET("/media/image", self.GetImage)
+}
diff --git a/pkg/view/settings.go b/pkg/view/settings.go
new file mode 100644
index 0000000..746dee4
--- /dev/null
+++ b/pkg/view/settings.go
@@ -0,0 +1,53 @@
+package view
+
+import (
+ "github.com/valyala/fasthttp"
+
+ "git.sr.ht/~gabrielgio/img"
+ "git.sr.ht/~gabrielgio/img/pkg/components/settings"
+ "git.sr.ht/~gabrielgio/img/pkg/ext"
+)
+
+type SettingsView struct {
+ // there is not need to create a controller for this
+ repository settings.Repository
+}
+
+func NewSettingsView(respository settings.Repository) *SettingsView {
+ return &SettingsView{
+ repository: respository,
+ }
+}
+
+func (self *SettingsView) Index(ctx *fasthttp.RequestCtx) error {
+ s, err := self.repository.Load(ctx)
+ if err != nil {
+ return err
+ }
+ return img.Render(ctx, "settings.html", &img.HTMLView[*settings.Settings]{
+ Title: "Settings",
+ Data: s,
+ })
+}
+
+func (self *SettingsView) Save(ctx *fasthttp.RequestCtx) error {
+ var (
+ showMode = string(ctx.FormValue("showMode")) == "on"
+ showOwner = string(ctx.FormValue("showOwner")) == "on"
+ )
+
+ err := self.repository.Save(ctx, &settings.Settings{
+ ShowMode: showMode,
+ ShowOwner: showOwner,
+ })
+ if err != nil {
+ return err
+ }
+
+ return self.Index(ctx)
+}
+
+func (self *SettingsView) SetMyselfIn(r *ext.Router) {
+ r.GET("/settings/", self.Index)
+ r.POST("/settings/", self.Save)
+}
diff --git a/pkg/view/view.go b/pkg/view/view.go
new file mode 100644
index 0000000..663738b
--- /dev/null
+++ b/pkg/view/view.go
@@ -0,0 +1,7 @@
+package view
+
+import "git.sr.ht/~gabrielgio/img/pkg/ext"
+
+type View interface {
+ SetMyselfIn(r *ext.Router)
+}