Major file restructuring
This commit is contained in:
parent
6abacd4bed
commit
cae11a2e19
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func initConfig() error {
|
||||
viper.SetDefault("host", "[::]")
|
||||
viper.SetDefault("port", 8080)
|
||||
viper.SetDefault("db_path", "bin.db")
|
||||
viper.SetDefault("smtp.enabled", false)
|
||||
viper.SetDefault("user.registration_enabled", false)
|
||||
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("toml")
|
||||
viper.AddConfigPath("/etc/bin")
|
||||
viper.AddConfigPath("$HOME/.config/bin")
|
||||
viper.AddConfigPath("$XDG_CONFIG_HOME/bin")
|
||||
viper.AddConfigPath(".")
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
logrus.Warnln("No config file found.")
|
||||
} else {
|
||||
logrus.WithError(err).Errorln("Config file found but could not read it.")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/global"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"git.myrkvi.com/myrkvi/bin/utils"
|
||||
"git.myrkvi.com/myrkvi/bin/views/components"
|
||||
"git.myrkvi.com/myrkvi/bin/views/pages"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func GetBinHandler(c echo.Context) error {
|
||||
file := models.File{}
|
||||
result := global.DB.Where("page_key = ?", c.Param("id")).First(&file)
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
logrus.WithError(result.Error).Errorln("no file")
|
||||
}
|
||||
if result.Error != nil {
|
||||
logrus.WithError(result.Error).Errorln("server error")
|
||||
|
||||
}
|
||||
|
||||
file.AdminKey = c.QueryParam("delcode")
|
||||
|
||||
return utils.RenderComponents(c, http.StatusOK,
|
||||
pages.BinFull(file),
|
||||
)
|
||||
}
|
||||
|
||||
func DeleteBinHandler(c echo.Context) error {
|
||||
code := c.Param("id")
|
||||
adminCode := c.FormValue("adminKey")
|
||||
|
||||
if adminCode == "" {
|
||||
return utils.RenderErrorToast(c, "deletion key cannot be empty")
|
||||
}
|
||||
|
||||
file := models.File{}
|
||||
result := global.DB.Where("page_key = ?", code).First(&file)
|
||||
|
||||
if result.Error != nil {
|
||||
return utils.RenderErrorToast(c, "file not found")
|
||||
}
|
||||
|
||||
if adminCode != file.AdminKey {
|
||||
return utils.RenderErrorToast(c, "invalid deletion key")
|
||||
}
|
||||
|
||||
global.DB.Delete(&file)
|
||||
|
||||
if file.Filename == "" {
|
||||
file.Filename = "file"
|
||||
}
|
||||
|
||||
utils.SetHeader(c, "HX-Push", "/")
|
||||
return utils.RenderComponents(
|
||||
c,
|
||||
http.StatusOK,
|
||||
pages.IndexPartial(),
|
||||
components.SwapOOB(
|
||||
"beforeend:#toast",
|
||||
components.ToastSuccess(fmt.Sprintf("%s deleted", file.Filename)),
|
||||
),
|
||||
components.NavMenu(models.DefaultMenu, 0, true),
|
||||
components.SetTitle(""),
|
||||
)
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/utils"
|
||||
"git.myrkvi.com/myrkvi/bin/views/partials"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func GetPartialUploadHandler(c echo.Context) error {
|
||||
c.Response().Header().Add("HX-Push", "/new")
|
||||
return utils.RenderComponents(c, http.StatusOK, partials.NewFileUpload())
|
||||
}
|
||||
|
||||
func GetPartialTextHandler(c echo.Context) error {
|
||||
c.Response().Header().Add("HX-Push", "/new?text")
|
||||
return utils.RenderComponents(c, http.StatusOK, partials.NewTextSubmit())
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/utils"
|
||||
"git.myrkvi.com/myrkvi/bin/views/pages"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func IndexHandler(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
logrus.Infof("id is '%s'", id)
|
||||
|
||||
return utils.RenderComponents(c, http.StatusOK, pages.IndexFull())
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/global"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"git.myrkvi.com/myrkvi/bin/utils"
|
||||
"git.myrkvi.com/myrkvi/bin/views/components"
|
||||
"git.myrkvi.com/myrkvi/bin/views/pages"
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func GetNewHandler(c echo.Context) error {
|
||||
values := c.QueryParams()
|
||||
wantsText := values.Has("text")
|
||||
return utils.RenderComponents(c, http.StatusOK, pages.NewFull(wantsText))
|
||||
}
|
||||
|
||||
func PostNewHandler(c echo.Context) error {
|
||||
file, err := c.FormFile("file")
|
||||
text := c.FormValue("text")
|
||||
|
||||
name := c.FormValue("name")
|
||||
description := c.FormValue("description")
|
||||
lang := c.FormValue("lang")
|
||||
|
||||
if (file == nil || err != nil) && text == "" {
|
||||
return utils.RenderErrorToast(c, "file or text must be provided")
|
||||
}
|
||||
|
||||
code, adminCode, err := utils.GenerateCodes()
|
||||
if err != nil {
|
||||
return utils.RenderErrorToast(c, "server-side error occurred")
|
||||
}
|
||||
|
||||
if file != nil {
|
||||
text, err = getTextFromFile(file)
|
||||
if name == "" {
|
||||
name = file.Filename
|
||||
}
|
||||
if err != nil {
|
||||
return utils.RenderErrorToast(c, "server-side error occurred")
|
||||
}
|
||||
}
|
||||
// Determine language from file extension if not set.
|
||||
if lang == "" {
|
||||
lexer := lexers.Match(name)
|
||||
if lexer != nil {
|
||||
lang = lexer.Config().Name
|
||||
}
|
||||
}
|
||||
|
||||
createdFile, err := models.CreateNewBin(global.DB, text, name, description, lang, code, adminCode)
|
||||
if err != nil {
|
||||
return utils.RenderErrorToast(c, "server-side error occurred")
|
||||
}
|
||||
|
||||
utils.SetHeader(c, "HX-Push", fmt.Sprintf("/b/%s", code))
|
||||
return utils.RenderComponents(c, http.StatusOK,
|
||||
pages.BinPartial(createdFile),
|
||||
components.SetTitle(file.Filename),
|
||||
)
|
||||
}
|
||||
|
||||
func getTextFromFile(fileHeader *multipart.FileHeader) (text string, err error) {
|
||||
f, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
text = string(b)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package global
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var DB *gorm.DB
|
13
go.mod
13
go.mod
|
@ -29,7 +29,9 @@ require (
|
|||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gohugoio/hugo v0.118.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
|
@ -37,9 +39,11 @@ require (
|
|||
github.com/labstack/echo/v4 v4.11.1 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
|
@ -47,6 +51,12 @@ require (
|
|||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.16.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tdewolff/parse/v2 v2.6.8 // indirect
|
||||
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
|
@ -64,6 +74,7 @@ require (
|
|||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/gorm v1.25.4 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
|
|
27
go.sum
27
go.sum
|
@ -69,6 +69,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
|
|||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cosmtrek/air v1.45.0 h1:JwNWE61dXW2SmGDy8bB28KTX+v0KFh+xqaF4kFJav6U=
|
||||
github.com/cosmtrek/air v1.45.0/go.mod h1:yOz9vy7edZ75KRN9+Ofqwm3OU0wuv4Csc+ikMeZxxS8=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
|
@ -172,13 +173,19 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
|||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
|
@ -203,6 +210,8 @@ github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8
|
|||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
|
@ -212,6 +221,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP
|
|||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -232,13 +243,25 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
|||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
|
@ -249,6 +272,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
|||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA=
|
||||
github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM=
|
||||
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
|
@ -603,6 +628,8 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
142
handlers.go
142
handlers.go
|
@ -1,142 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func indexHandler(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
logrus.Infof("id is '%s'", id)
|
||||
|
||||
return RenderComponent(c, http.StatusOK, indexFull())
|
||||
}
|
||||
|
||||
// ░█▀█░█▀▀░█░█░░░░░█░░░█▀▀░█░█░█▀▄░█▄█░▀█▀░▀█▀░░░█▀█░█▀█░█▀▀░█▀▀
|
||||
// ░█░█░█▀▀░█▄█░░░▄▀░░░░▀▀█░█░█░█▀▄░█░█░░█░░░█░░░░█▀▀░█▀█░█░█░█▀▀
|
||||
// ░▀░▀░▀▀▀░▀░▀░░░▀░░░░░▀▀▀░▀▀▀░▀▀░░▀░▀░▀▀▀░░▀░░░░▀░░░▀░▀░▀▀▀░▀▀▀
|
||||
|
||||
func getNewHandler(c echo.Context) error {
|
||||
values := c.QueryParams()
|
||||
wantsText := values.Has("text")
|
||||
return RenderComponent(c, http.StatusOK, newFull(wantsText))
|
||||
}
|
||||
|
||||
func postNewHandler(c echo.Context) error {
|
||||
file, err := c.FormFile("file")
|
||||
text := c.FormValue("text")
|
||||
wantsText := c.FormValue("wantsText") == "true"
|
||||
|
||||
name := c.FormValue("name")
|
||||
description := c.FormValue("description")
|
||||
lang := c.FormValue("lang")
|
||||
|
||||
if (file == nil || err != nil) && text == "" {
|
||||
/* return RenderComponent(c, http.StatusOK,
|
||||
CombineTempls(
|
||||
newPartial(wantsText),
|
||||
ErrorMessage("file or text must be provided", "error-span"),
|
||||
),
|
||||
) */
|
||||
return RenderErrorToast(c, "File or text must be provided.")
|
||||
}
|
||||
|
||||
code, adminCode, err := generateCodes()
|
||||
if err != nil {
|
||||
return RenderComponent(c, http.StatusOK,
|
||||
CombineTempls(
|
||||
newPartial(wantsText),
|
||||
ErrorMessage("server-side error occurred", "error-span"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if file != nil {
|
||||
text, err = getTextFromFile(file)
|
||||
if name == "" {
|
||||
name = file.Filename
|
||||
}
|
||||
if err != nil {
|
||||
return RenderComponent(c, http.StatusOK,
|
||||
CombineTempls(
|
||||
newPartial(wantsText),
|
||||
ErrorMessage("server-side error occurred", "error-span"),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
// Determine language from file extension if not set.
|
||||
if lang == "" {
|
||||
lexer := lexers.Match(name)
|
||||
if lexer != nil {
|
||||
lang = lexer.Config().Name
|
||||
}
|
||||
}
|
||||
|
||||
createdFile, err := createNewBin(text, name, description, lang, code, adminCode)
|
||||
if err != nil {
|
||||
return RenderComponent(c, http.StatusOK,
|
||||
CombineTempls(
|
||||
newPartial(wantsText),
|
||||
ErrorMessage("server-side error occurred", "error-span"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
c.Response().Header().Add("HX-Push", fmt.Sprintf("/b/%s", code))
|
||||
return RenderComponent(c, http.StatusOK,
|
||||
binPartial(createdFile),
|
||||
)
|
||||
}
|
||||
|
||||
// ░█▀▄░▀█▀░█▀█░░░░░█░░░█▀▀░▀█▀░█░░░█▀▀░█▀▀
|
||||
// ░█▀▄░░█░░█░█░░░▄▀░░░░█▀▀░░█░░█░░░█▀▀░▀▀█
|
||||
// ░▀▀░░▀▀▀░▀░▀░░░▀░░░░░▀░░░▀▀▀░▀▀▀░▀▀▀░▀▀▀
|
||||
// Individual pages of uploaded files.
|
||||
|
||||
func getBinHandler(c echo.Context) error {
|
||||
file := File{}
|
||||
result := db.Where("page_key = ?", c.Param("id")).First(&file)
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
logrus.WithError(result.Error).Errorln("no file")
|
||||
}
|
||||
if result.Error != nil {
|
||||
logrus.WithError(result.Error).Errorln("server error")
|
||||
|
||||
}
|
||||
|
||||
file.AdminKey = c.QueryParam("delcode")
|
||||
|
||||
return RenderComponent(c, http.StatusOK,
|
||||
binFull(file),
|
||||
)
|
||||
}
|
||||
|
||||
func deleteBinHandler(c echo.Context) error {
|
||||
code := c.Param("id")
|
||||
adminCode := c.FormValue("adminKey")
|
||||
|
||||
if adminCode == "" {
|
||||
return RenderErrorToast(c, "deletion key cannot be empty")
|
||||
}
|
||||
|
||||
file := File{}
|
||||
result := db.Where("page_key = ?", code).First(&file)
|
||||
|
||||
if result.Error != nil {
|
||||
return RenderErrorToast(c, "file not found")
|
||||
}
|
||||
|
||||
if adminCode != file.AdminKey {
|
||||
return RenderErrorToast(c, "invalid deletion key")
|
||||
}
|
||||
|
||||
db.Delete(&file)
|
||||
|
||||
return c.HTML(http.StatusOK, "<h1>file deleted!</h1>")
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func getPartialUploadHandler(c echo.Context) error {
|
||||
c.Response().Header().Add("HX-Push", "/new")
|
||||
return RenderComponent(c, http.StatusOK, newFileUpload())
|
||||
}
|
||||
|
||||
func getPartialTextHandler(c echo.Context) error {
|
||||
c.Response().Header().Add("HX-Push", "/new?text")
|
||||
return RenderComponent(c, http.StatusOK, newTextSubmit())
|
||||
}
|
53
main.go
53
main.go
|
@ -1,34 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"fmt"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/controllers"
|
||||
"git.myrkvi.com/myrkvi/bin/global"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
prefixed "github.com/x-cray/logrus-prefixed-formatter"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type MenuItem struct {
|
||||
label string
|
||||
href string
|
||||
}
|
||||
|
||||
var db *gorm.DB
|
||||
|
||||
func main() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logrus.SetFormatter(&prefixed.TextFormatter{
|
||||
FullTimestamp: true,
|
||||
})
|
||||
logrus.Infoln("Application started.")
|
||||
initConfig()
|
||||
|
||||
db_string := "bin.db"
|
||||
var err error
|
||||
db, err = gorm.Open(sqlite.Open(db_string), &gorm.Config{})
|
||||
global.DB, err = gorm.Open(sqlite.Open(db_string), &gorm.Config{})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalln("Could not open database connection.")
|
||||
}
|
||||
|
@ -36,7 +33,7 @@ func main() {
|
|||
"db connection": db_string,
|
||||
}).Infoln("Connected to database.")
|
||||
|
||||
databaseMigrations(db)
|
||||
models.DatabaseMigrations(global.DB)
|
||||
|
||||
e := echo.New()
|
||||
e.Debug = false
|
||||
|
@ -58,29 +55,21 @@ func main() {
|
|||
|
||||
e.Static("/static", "static")
|
||||
|
||||
e.GET("/", indexHandler)
|
||||
e.GET("/new", getNewHandler)
|
||||
e.POST("/new", postNewHandler)
|
||||
e.GET("/b/:id", getBinHandler)
|
||||
e.POST("/b/:id/delete", deleteBinHandler)
|
||||
e.GET("/", controllers.IndexHandler)
|
||||
e.GET("/new", controllers.GetNewHandler)
|
||||
e.POST("/new", controllers.PostNewHandler)
|
||||
e.GET("/b/:id", controllers.GetBinHandler)
|
||||
e.POST("/b/:id/delete", controllers.DeleteBinHandler)
|
||||
|
||||
partial := e.Group("/partial")
|
||||
new := partial.Group("/new")
|
||||
new.GET("/upload", getPartialUploadHandler)
|
||||
new.GET("/text", getPartialTextHandler)
|
||||
e.Logger.Fatal(e.Start(":8080"))
|
||||
}
|
||||
new.GET("/upload", controllers.GetPartialUploadHandler)
|
||||
new.GET("/text", controllers.GetPartialTextHandler)
|
||||
|
||||
func getTextFromFile(fileHeader *multipart.FileHeader) (text string, err error) {
|
||||
f, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
text = string(b)
|
||||
return
|
||||
listenAt := fmt.Sprintf(
|
||||
"%s:%d",
|
||||
viper.GetString("host"),
|
||||
viper.GetUint16("port"),
|
||||
)
|
||||
e.Logger.Fatal(e.Start(listenAt))
|
||||
}
|
||||
|
|
49
models.go
49
models.go
|
@ -1,49 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
gorm.Model
|
||||
|
||||
PageKey string `gorm:"index:idx_pagekey,unique"`
|
||||
AdminKey string `gorm:"index:idx_adminkey"`
|
||||
|
||||
// The "virtual" filename.
|
||||
Filename string
|
||||
|
||||
// The description of the file submission.
|
||||
Description string
|
||||
|
||||
Language string
|
||||
|
||||
// The contents of the file must be valid text.
|
||||
Data string
|
||||
}
|
||||
|
||||
func databaseMigrations(db *gorm.DB) {
|
||||
logrus.Infoln("Running database migrations.")
|
||||
err := db.AutoMigrate(&File{})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Fatalln("Failed to run database migration.")
|
||||
}
|
||||
logrus.Infoln("Migrations ran successfully.")
|
||||
}
|
||||
|
||||
func createNewBin(text, name, description, language, key, adminKey string) (File, error) {
|
||||
bin := File{
|
||||
Filename: name,
|
||||
Description: description,
|
||||
Language: language,
|
||||
PageKey: key,
|
||||
AdminKey: adminKey,
|
||||
Data: text,
|
||||
}
|
||||
result := db.Create(&bin)
|
||||
if result.Error != nil {
|
||||
return File{}, result.Error
|
||||
}
|
||||
return bin, nil
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package models
|
||||
|
||||
type MenuItem struct {
|
||||
Label string
|
||||
Href string
|
||||
}
|
||||
|
||||
var DefaultMenu []MenuItem = []MenuItem{
|
||||
{
|
||||
Label: "home",
|
||||
Href: "/",
|
||||
},
|
||||
{
|
||||
Label: "new",
|
||||
Href: "/new",
|
||||
},
|
||||
{
|
||||
Label: "about",
|
||||
Href: "/about",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
gorm.Model
|
||||
|
||||
PageKey string `gorm:"index:idx_pagekey,unique;unique"`
|
||||
AdminKey string `gorm:"index:idx_adminkey"`
|
||||
|
||||
// The "virtual" filename.
|
||||
Filename string
|
||||
|
||||
// The description of the file submission.
|
||||
Description string
|
||||
|
||||
Language string
|
||||
|
||||
// The contents of the file must be valid text.
|
||||
Data string
|
||||
|
||||
UserID uint
|
||||
User User
|
||||
}
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
|
||||
DisplayName string
|
||||
Email string `gorm:"unique"`
|
||||
Salt string
|
||||
HashedPassword []byte
|
||||
}
|
||||
|
||||
func (u *User) MatchesPassword(password string) bool {
|
||||
combined := append([]byte(u.Salt), []byte(password)...)
|
||||
|
||||
return bcrypt.CompareHashAndPassword(u.HashedPassword, []byte(combined)) == nil
|
||||
}
|
||||
|
||||
func DatabaseMigrations(db *gorm.DB) {
|
||||
tables := []interface{}{
|
||||
File{},
|
||||
User{},
|
||||
}
|
||||
|
||||
logrus.Infoln("Running database migrations.")
|
||||
for _, table := range tables {
|
||||
name := reflect.TypeOf(table).Name()
|
||||
err := db.AutoMigrate(&table)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("table", name).Fatalln("Migration failed.")
|
||||
} else {
|
||||
logrus.WithField("table", name).Infoln("Migration successful.")
|
||||
}
|
||||
}
|
||||
logrus.Infoln("Migrations ran successfully.")
|
||||
}
|
||||
|
||||
func CreateNewBin(db *gorm.DB, text, name, description, language, key, adminKey string) (File, error) {
|
||||
bin := File{
|
||||
Filename: name,
|
||||
Description: description,
|
||||
Language: language,
|
||||
PageKey: key,
|
||||
AdminKey: adminKey,
|
||||
Data: text,
|
||||
}
|
||||
result := db.Create(&bin)
|
||||
if result.Error != nil {
|
||||
return File{}, result.Error
|
||||
}
|
||||
return bin, nil
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func TestHashPassword(t *testing.T) {
|
||||
salt := "BlahHa!?591"
|
||||
password := "MyPassword123"
|
||||
|
||||
combined := append([]byte(salt), []byte(password)...)
|
||||
hashed, err := bcrypt.GenerateFromPassword(combined, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate password: %v\n", err)
|
||||
}
|
||||
|
||||
user := User{
|
||||
Salt: salt,
|
||||
HashedPassword: hashed[:],
|
||||
}
|
||||
|
||||
matches := user.MatchesPassword(password)
|
||||
if !matches {
|
||||
t.Fatal("Password does not match")
|
||||
} else {
|
||||
t.Log("Password matches")
|
||||
}
|
||||
}
|
|
@ -642,8 +642,8 @@ video {
|
|||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.mt-12 {
|
||||
margin-top: 3rem;
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
|
@ -775,8 +775,12 @@ video {
|
|||
border-bottom-width: 4px;
|
||||
}
|
||||
|
||||
.border-t-4 {
|
||||
border-top-width: 4px;
|
||||
.border-r-4 {
|
||||
border-right-width: 4px;
|
||||
}
|
||||
|
||||
.border-t-0 {
|
||||
border-top-width: 0px;
|
||||
}
|
||||
|
||||
.border-amber-300 {
|
||||
|
@ -789,6 +793,11 @@ video {
|
|||
border-color: rgb(0 0 0 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-emerald-600 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(5 150 105 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-rose-600 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(225 29 72 / var(--tw-border-opacity));
|
||||
|
@ -799,6 +808,11 @@ video {
|
|||
background-color: rgb(255 251 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-emerald-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(52 211 153 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-rose-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(251 113 133 / var(--tw-bg-opacity));
|
||||
|
@ -809,6 +823,11 @@ video {
|
|||
padding-right: 0.25rem;
|
||||
}
|
||||
|
||||
.px-2 {
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
|
@ -961,6 +980,15 @@ video {
|
|||
margin-right: 6rem;
|
||||
}
|
||||
|
||||
.sm\:my-2 {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:mt-12 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.sm\:grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
@ -968,6 +996,19 @@ video {
|
|||
.sm\:flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sm\:border-r-0 {
|
||||
border-right-width: 0px;
|
||||
}
|
||||
|
||||
.sm\:border-t-4 {
|
||||
border-top-width: 4px;
|
||||
}
|
||||
|
||||
.sm\:px-0 {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
@ -975,11 +1016,6 @@ video {
|
|||
grid-column: span 4 / span 4;
|
||||
}
|
||||
|
||||
.md\:mx-2 {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.md\:mx-32 {
|
||||
margin-left: 8rem;
|
||||
margin-right: 8rem;
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
package main
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.myrkvi.com/myrkvi/bin/views/components"
|
||||
"github.com/a-h/templ"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/teris-io/shortid"
|
||||
)
|
||||
|
||||
func RenderComponent(c echo.Context, status int, component templ.Component) error {
|
||||
// func RenderComponent(c echo.Context, status int, component templ.Component) error {
|
||||
// w := c.Response().Writer
|
||||
// c.Response().Status = status
|
||||
|
||||
// return component.Render(context.Background(), w)
|
||||
// }
|
||||
|
||||
func RenderComponents(c echo.Context, status int, comps ...templ.Component) error {
|
||||
w := c.Response().Writer
|
||||
c.Response().Status = status
|
||||
|
||||
return component.Render(context.Background(), w)
|
||||
combine := components.CombineTempls(comps...)
|
||||
|
||||
return combine.Render(context.Background(), w)
|
||||
}
|
||||
|
||||
func RenderErrorToast(c echo.Context, message string) error {
|
||||
SetHeader(c, "HX-Retarget", "#toast")
|
||||
SetHeader(c, "HX-Reswap", "beforeend")
|
||||
|
||||
return RenderComponent(c, 200, ToastError(message))
|
||||
return RenderComponents(c, 200, components.ToastError(message))
|
||||
}
|
||||
|
||||
func AddHeader(c echo.Context, key, value string) {
|
||||
|
@ -34,7 +44,7 @@ func SetContentType(c echo.Context, value string) {
|
|||
SetHeader(c, "Content-Type", value)
|
||||
}
|
||||
|
||||
func generateCodes() (code string, adminCode string, err error) {
|
||||
func GenerateCodes() (code string, adminCode string, err error) {
|
||||
code, err = shortid.Generate()
|
||||
if err != nil {
|
||||
return
|
|
@ -1,6 +1,9 @@
|
|||
package main
|
||||
package components
|
||||
|
||||
import "github.com/alecthomas/chroma/lexers"
|
||||
import (
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
)
|
||||
|
||||
func getLanguages() []string {
|
||||
names := lexers.Names(false)
|
||||
|
@ -9,7 +12,7 @@ func getLanguages() []string {
|
|||
return names
|
||||
}
|
||||
|
||||
templ chooseSyntax(name string) {
|
||||
templ ChooseSyntax(name string) {
|
||||
<select class="max-w-full bg-amber-50" name={ name } id={ name }>
|
||||
for i, lang := range getLanguages() {
|
||||
if i == 0 {
|
||||
|
@ -21,7 +24,7 @@ templ chooseSyntax(name string) {
|
|||
</select>
|
||||
}
|
||||
|
||||
templ fileUpload(text, name, id string) {
|
||||
templ FileUpload(text, name, id string) {
|
||||
<span>
|
||||
<label
|
||||
role="button"
|
||||
|
@ -55,7 +58,7 @@ templ fileUpload(text, name, id string) {
|
|||
</span>
|
||||
}
|
||||
|
||||
templ boostButton(label, to string) {
|
||||
templ BoostButton(label, to string) {
|
||||
<span hx-boost="true">
|
||||
<a
|
||||
role="button"
|
||||
|
@ -72,7 +75,7 @@ templ boostButton(label, to string) {
|
|||
</span>
|
||||
}
|
||||
|
||||
templ submitFormButton(label string) {
|
||||
templ SubmitFormButton(label string) {
|
||||
<input
|
||||
type="submit"
|
||||
value={ label }
|
||||
|
@ -86,7 +89,7 @@ templ submitFormButton(label string) {
|
|||
/>
|
||||
}
|
||||
|
||||
templ NavMenu(items []MenuItem, current int, swapOob bool) {
|
||||
templ NavMenu(items []models.MenuItem, current int, swapOob bool) {
|
||||
<nav
|
||||
id="page-nav"
|
||||
class="flex flex-col sm:flex-row justify-around"
|
||||
|
@ -96,24 +99,36 @@ templ NavMenu(items []MenuItem, current int, swapOob bool) {
|
|||
hx-boost="true">
|
||||
for i, item := range items {
|
||||
if i == current {
|
||||
<span class="mx-4 md:mx-2 my-2 current-page border-t-4 border-black cursor-pointer">
|
||||
<b>{ item.label }</b>
|
||||
<span class="px-2 sm:px-0 sm:mx-2 sm:my-2
|
||||
border-t-0 border-r-4
|
||||
sm:border-t-4 sm:border-r-0
|
||||
border-black cursor-pointer">
|
||||
<b>{ item.Label }</b>
|
||||
</span>
|
||||
} else {
|
||||
<a
|
||||
class="mx-4 sm:mx-2 my-2 border-t-4 border-amber-300"
|
||||
href={ templ.URL(item.href) }
|
||||
class="px-2 sm:px-0 sm:mx-2 my-2
|
||||
border-t-0 border-r-4
|
||||
sm:border-t-4 sm:border-r-0
|
||||
border-amber-300"
|
||||
href={ templ.URL(item.Href) }
|
||||
>
|
||||
{ item.label }
|
||||
{ item.Label }
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</nav>
|
||||
}
|
||||
|
||||
templ CombineTempls(top, bottom templ.Component) {
|
||||
{! top }
|
||||
{! bottom }
|
||||
// templ CombineTempls(top, bottom templ.Component) {
|
||||
// {! top }
|
||||
// {! bottom }
|
||||
// }
|
||||
|
||||
templ CombineTempls(comps ...templ.Component) {
|
||||
for _, comp := range comps {
|
||||
{! comp }
|
||||
}
|
||||
}
|
||||
|
||||
templ ErrorMessage(msg, id string) {
|
||||
|
@ -127,7 +142,7 @@ templ ErrorMessage(msg, id string) {
|
|||
}
|
||||
|
||||
templ ToastError(message string) {
|
||||
<div
|
||||
<div
|
||||
class="relative px-4 py-2 bg-rose-400 opacity-0
|
||||
border border-rose-600 rounded-lg m-1"
|
||||
_="init transition my opacity to 1 over 250ms"
|
||||
|
@ -144,4 +159,40 @@ templ ToastError(message string) {
|
|||
</span>
|
||||
{ message }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ ToastSuccess(message string) {
|
||||
<div
|
||||
class="relative px-4 py-2 bg-emerald-400 opacity-0
|
||||
border border-emerald-600 rounded-lg m-1"
|
||||
_="init transition my opacity to 1 over 250ms"
|
||||
>
|
||||
<span
|
||||
tabindex="0"
|
||||
role="button" aria-label="Close the toast message"
|
||||
class="absolute top-0 right-1 cursor-pointer select-none"
|
||||
_="on click set prnt to my parentElement
|
||||
then transition element prnt's opacity to 0 over 500ms
|
||||
then remove my parentElement"
|
||||
>
|
||||
<sup>🞬</sup>
|
||||
</span>
|
||||
{ message }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ SwapOOB(swapspec string, component templ.Component) {
|
||||
<div hx-swap-oob={ swapspec }>
|
||||
{! component }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ SetTitle(title string) {
|
||||
<title id="title" hx-swap-oob="true">
|
||||
if title == "" {
|
||||
bin
|
||||
} else {
|
||||
{ title } - bin
|
||||
}
|
||||
</title>
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by templ@v0.2.316 DO NOT EDIT.
|
||||
|
||||
package main
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
|
@ -9,7 +9,10 @@ import "context"
|
|||
import "io"
|
||||
import "bytes"
|
||||
|
||||
import "github.com/alecthomas/chroma/lexers"
|
||||
import (
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
)
|
||||
|
||||
func getLanguages() []string {
|
||||
names := lexers.Names(false)
|
||||
|
@ -18,7 +21,7 @@ func getLanguages() []string {
|
|||
return names
|
||||
}
|
||||
|
||||
func chooseSyntax(name string) templ.Component {
|
||||
func ChooseSyntax(name string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -93,7 +96,7 @@ func chooseSyntax(name string) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func fileUpload(text, name, id string) templ.Component {
|
||||
func FileUpload(text, name, id string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -183,7 +186,7 @@ func fileUpload(text, name, id string) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func boostButton(label, to string) templ.Component {
|
||||
func BoostButton(label, to string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -225,7 +228,7 @@ func boostButton(label, to string) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func submitFormButton(label string) templ.Component {
|
||||
func SubmitFormButton(label string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -257,7 +260,7 @@ func submitFormButton(label string) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func NavMenu(items []MenuItem, current int, swapOob bool) templ.Component {
|
||||
func NavMenu(items []models.MenuItem, current int, swapOob bool) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -286,11 +289,11 @@ func NavMenu(items []MenuItem, current int, swapOob bool) templ.Component {
|
|||
}
|
||||
for i, item := range items {
|
||||
if i == current {
|
||||
_, err = templBuffer.WriteString("<span class=\"mx-4 md:mx-2 my-2 current-page border-t-4 border-black cursor-pointer\"><b>")
|
||||
_, err = templBuffer.WriteString("<span class=\"px-2 sm:px-0 sm:mx-2 sm:my-2\n border-t-0 border-r-4 \n sm:border-t-4 sm:border-r-0 \n border-black cursor-pointer\"><b>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_12 string = item.label
|
||||
var var_12 string = item.Label
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_12))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -300,11 +303,11 @@ func NavMenu(items []MenuItem, current int, swapOob bool) templ.Component {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
_, err = templBuffer.WriteString("<a class=\"mx-4 sm:mx-2 my-2 border-t-4 border-amber-300\" href=\"")
|
||||
_, err = templBuffer.WriteString("<a class=\"px-2 sm:px-0 sm:mx-2 my-2 \n border-t-0 border-r-4\n sm:border-t-4 sm:border-r-0\n border-amber-300\" href=\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_13 templ.SafeURL = templ.URL(item.href)
|
||||
var var_13 templ.SafeURL = templ.URL(item.Href)
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(string(var_13)))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -313,7 +316,7 @@ func NavMenu(items []MenuItem, current int, swapOob bool) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_14 string = item.label
|
||||
var var_14 string = item.Label
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_14))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -335,7 +338,12 @@ func NavMenu(items []MenuItem, current int, swapOob bool) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func CombineTempls(top, bottom templ.Component) templ.Component {
|
||||
// templ CombineTempls(top, bottom templ.Component) {
|
||||
// {! top }
|
||||
// {! bottom }
|
||||
// }
|
||||
|
||||
func CombineTempls(comps ...templ.Component) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -348,13 +356,11 @@ func CombineTempls(top, bottom templ.Component) templ.Component {
|
|||
var_15 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
err = top.Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bottom.Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, comp := range comps {
|
||||
err = comp.Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
|
@ -445,3 +451,135 @@ func ToastError(message string) templ.Component {
|
|||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func ToastSuccess(message string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_21 := templ.GetChildren(ctx)
|
||||
if var_21 == nil {
|
||||
var_21 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<div class=\"relative px-4 py-2 bg-emerald-400 opacity-0\n border border-emerald-600 rounded-lg m-1\" _=\"init transition my opacity to 1 over 250ms\"><span tabindex=\"0\" role=\"button\" aria-label=\"Close the toast message\" class=\"absolute top-0 right-1 cursor-pointer select-none\" _=\"on click set prnt to my parentElement\n then transition element prnt's opacity to 0 over 500ms\n then remove my parentElement\"><sup>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_22 := `🞬`
|
||||
_, err = templBuffer.WriteString(var_22)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</sup></span>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_23 string = message
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_23))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</div>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func SwapOOB(swapspec string, component templ.Component) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_24 := templ.GetChildren(ctx)
|
||||
if var_24 == nil {
|
||||
var_24 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<div hx-swap-oob=\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(swapspec))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = component.Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</div>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func SetTitle(title string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
templBuffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_25 := templ.GetChildren(ctx)
|
||||
if var_25 == nil {
|
||||
var_25 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<title id=\"title\" hx-swap-oob=\"true\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if title == "" {
|
||||
var_26 := `bin`
|
||||
_, err = templBuffer.WriteString(var_26)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
var var_27 string = title
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_27))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_28 := `- bin`
|
||||
_, err = templBuffer.WriteString(var_28)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = templBuffer.WriteString("</title>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !templIsBuffer {
|
||||
_, err = io.Copy(w, templBuffer)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
package main
|
||||
package pages
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"git.myrkvi.com/myrkvi/bin/views/components"
|
||||
"git.myrkvi.com/myrkvi/bin/views/partials"
|
||||
)
|
||||
|
||||
templ page(inner templ.Component, menu []MenuItem, currentMenu int, args interface{}) {
|
||||
templ page(inner templ.Component, menu []models.MenuItem, currentMenu int, title string) {
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -10,12 +15,16 @@ templ page(inner templ.Component, menu []MenuItem, currentMenu int, args interfa
|
|||
<script src="/static/htmx.min.js"></script>
|
||||
<script src="/static/_hyperscript.min.js"></script>
|
||||
<link rel="stylesheet" href="/static/tailwind.css" />
|
||||
<title>bin</title>
|
||||
if title == "" {
|
||||
<title id="title">bin</title>
|
||||
} else {
|
||||
<title id="title">{ title } - bin</title>
|
||||
}
|
||||
</head>
|
||||
<body class="mt-12 mx-16 xl:mx-72 lg:mx-64 md:mx-32 sm:mx-24 bg-amber-50">
|
||||
<body class="mt-4 sm:mt-12 mx-16 xl:mx-72 lg:mx-64 md:mx-32 sm:mx-24 bg-amber-50">
|
||||
<header class="flex flex-row justify-between my-16">
|
||||
<h1 class="text-5xl">bin</h1>
|
||||
@NavMenu(menu, currentMenu, false)
|
||||
@components.NavMenu(menu, currentMenu, false)
|
||||
</header>
|
||||
<main id="main-content">
|
||||
{! inner }
|
||||
|
@ -29,46 +38,30 @@ templ page(inner templ.Component, menu []MenuItem, currentMenu int, args interfa
|
|||
</html>
|
||||
}
|
||||
|
||||
var defaultMenu []MenuItem = []MenuItem{
|
||||
{
|
||||
label: "home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "new",
|
||||
href: "/new",
|
||||
},
|
||||
{
|
||||
label: "about",
|
||||
href: "/about",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
templ indexFull() {
|
||||
templ IndexFull() {
|
||||
@page(
|
||||
indexPartial(),
|
||||
defaultMenu,
|
||||
IndexPartial(),
|
||||
models.DefaultMenu,
|
||||
0,
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
templ indexPartial() {
|
||||
templ IndexPartial() {
|
||||
<h2 class="text-xl">Welcome to <i>bin</i></h2>
|
||||
<p>bin is a simple paste bin.</p>
|
||||
<br />
|
||||
@boostButton("new", "/new")
|
||||
@components.BoostButton("new", "/new")
|
||||
|
||||
}
|
||||
|
||||
templ newFull(wantsText bool) {
|
||||
templ NewFull(wantsText bool) {
|
||||
@page(
|
||||
newPartial(wantsText),
|
||||
defaultMenu,
|
||||
NewPartial(wantsText),
|
||||
models.DefaultMenu,
|
||||
1,
|
||||
nil,
|
||||
"upload",
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -80,7 +73,7 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}`
|
||||
|
||||
templ newPartial(wantsText bool) {
|
||||
templ NewPartial(wantsText bool) {
|
||||
<h2 class="text-xl">submit a new file</h2>
|
||||
<form
|
||||
hx-post="/new"
|
||||
|
@ -105,7 +98,7 @@ templ newPartial(wantsText bool) {
|
|||
_="on change set #description's @placeholder to `some stuff about ${my value} ...`"
|
||||
/>
|
||||
<label for="lang" class="col-span-1">language:</label>
|
||||
<div class="col-span-2 md:col-span-4">@chooseSyntax("lang")</div>
|
||||
<div class="col-span-2 md:col-span-4">@components.ChooseSyntax("lang")</div>
|
||||
<label class="col-span-1" for="description">description:</label>
|
||||
<textarea
|
||||
class="col-span-2 md:col-span-4 resize-none hover:resize justify-self-start
|
||||
|
@ -120,25 +113,25 @@ templ newPartial(wantsText bool) {
|
|||
/>
|
||||
</div>
|
||||
if wantsText {
|
||||
@newTextSubmit()
|
||||
@partials.NewTextSubmit()
|
||||
<input type="text" name="wantsText" hidden value="true" />
|
||||
} else {
|
||||
@newFileUpload()
|
||||
@partials.NewFileUpload()
|
||||
}
|
||||
@submitFormButton("submit")
|
||||
@components.SubmitFormButton("submit")
|
||||
</form>
|
||||
}
|
||||
|
||||
templ binFull(file File) {
|
||||
templ BinFull(file models.File) {
|
||||
@page(
|
||||
binPartial(file),
|
||||
defaultMenu,
|
||||
BinPartial(file),
|
||||
models.DefaultMenu,
|
||||
-1,
|
||||
nil,
|
||||
file.Filename,
|
||||
)
|
||||
}
|
||||
|
||||
templ binPartial(file File) {
|
||||
templ BinPartial(file models.File) {
|
||||
<div>
|
||||
<h1 class="text-xl my-2 inline-block">{ file.Filename }
|
||||
if file.Language != "" {
|
||||
|
@ -152,6 +145,7 @@ templ binPartial(file File) {
|
|||
class="absolute -bottom-32"
|
||||
hx-post={ "/b/" + file.PageKey + "/delete" }
|
||||
hx-confirm="Are you sure you want to delete this?"
|
||||
hx-target="#main-content"
|
||||
>
|
||||
<input
|
||||
name="adminKey"
|
||||
|
@ -164,7 +158,7 @@ templ binPartial(file File) {
|
|||
placeholder="deletion key"
|
||||
value={ file.AdminKey }
|
||||
/>
|
||||
@submitFormButton("delete")
|
||||
@components.SubmitFormButton("delete")
|
||||
if file.AdminKey != "" {
|
||||
<a class="text-blue-500 mx-4" href={ templ.URL(fmt.Sprintf("/b/%s?delcode=%s", file.PageKey, file.AdminKey))}><sup>permalink with deletion key</sup></a>
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by templ@v0.2.316 DO NOT EDIT.
|
||||
|
||||
package main
|
||||
package pages
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
|
@ -9,9 +9,14 @@ import "context"
|
|||
import "io"
|
||||
import "bytes"
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"git.myrkvi.com/myrkvi/bin/models"
|
||||
"git.myrkvi.com/myrkvi/bin/views/components"
|
||||
"git.myrkvi.com/myrkvi/bin/views/partials"
|
||||
)
|
||||
|
||||
func page(inner templ.Component, menu []MenuItem, currentMenu int, args interface{}) templ.Component {
|
||||
func page(inner templ.Component, menu []models.MenuItem, currentMenu int, title string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -42,21 +47,54 @@ func page(inner templ.Component, menu []MenuItem, currentMenu int, args interfac
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</script><link rel=\"stylesheet\" href=\"/static/tailwind.css\"><title>")
|
||||
_, err = templBuffer.WriteString("</script><link rel=\"stylesheet\" href=\"/static/tailwind.css\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_4 := `bin`
|
||||
_, err = templBuffer.WriteString(var_4)
|
||||
if title == "" {
|
||||
_, err = templBuffer.WriteString("<title id=\"title\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_4 := `bin`
|
||||
_, err = templBuffer.WriteString(var_4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</title>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err = templBuffer.WriteString("<title id=\"title\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_5 string = title
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_5))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString(" ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_6 := `- bin`
|
||||
_, err = templBuffer.WriteString(var_6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</title>")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = templBuffer.WriteString("</head><body class=\"mt-4 sm:mt-12 mx-16 xl:mx-72 lg:mx-64 md:mx-32 sm:mx-24 bg-amber-50\"><header class=\"flex flex-row justify-between my-16\"><h1 class=\"text-5xl\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</title></head><body class=\"mt-12 mx-16 xl:mx-72 lg:mx-64 md:mx-32 sm:mx-24 bg-amber-50\"><header class=\"flex flex-row justify-between my-16\"><h1 class=\"text-5xl\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_5 := `bin`
|
||||
_, err = templBuffer.WriteString(var_5)
|
||||
var_7 := `bin`
|
||||
_, err = templBuffer.WriteString(var_7)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -64,7 +102,7 @@ func page(inner templ.Component, menu []MenuItem, currentMenu int, args interfac
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = NavMenu(menu, currentMenu, false).Render(ctx, templBuffer)
|
||||
err = components.NavMenu(menu, currentMenu, false).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -87,22 +125,7 @@ func page(inner templ.Component, menu []MenuItem, currentMenu int, args interfac
|
|||
})
|
||||
}
|
||||
|
||||
var defaultMenu []MenuItem = []MenuItem{
|
||||
{
|
||||
label: "home",
|
||||
href: "/",
|
||||
},
|
||||
{
|
||||
label: "new",
|
||||
href: "/new",
|
||||
},
|
||||
{
|
||||
label: "about",
|
||||
href: "/about",
|
||||
},
|
||||
}
|
||||
|
||||
func indexFull() templ.Component {
|
||||
func IndexFull() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -110,16 +133,16 @@ func indexFull() templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_6 := templ.GetChildren(ctx)
|
||||
if var_6 == nil {
|
||||
var_6 = templ.NopComponent
|
||||
var_8 := templ.GetChildren(ctx)
|
||||
if var_8 == nil {
|
||||
var_8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
err = page(
|
||||
indexPartial(),
|
||||
defaultMenu,
|
||||
IndexPartial(),
|
||||
models.DefaultMenu,
|
||||
0,
|
||||
nil,
|
||||
"",
|
||||
).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -131,7 +154,7 @@ func indexFull() templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func indexPartial() templ.Component {
|
||||
func IndexPartial() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -139,17 +162,17 @@ func indexPartial() templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_7 := templ.GetChildren(ctx)
|
||||
if var_7 == nil {
|
||||
var_7 = templ.NopComponent
|
||||
var_9 := templ.GetChildren(ctx)
|
||||
if var_9 == nil {
|
||||
var_9 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<h2 class=\"text-xl\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_8 := `Welcome to `
|
||||
_, err = templBuffer.WriteString(var_8)
|
||||
var_10 := `Welcome to `
|
||||
_, err = templBuffer.WriteString(var_10)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -157,8 +180,8 @@ func indexPartial() templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_9 := `bin`
|
||||
_, err = templBuffer.WriteString(var_9)
|
||||
var_11 := `bin`
|
||||
_, err = templBuffer.WriteString(var_11)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -166,8 +189,8 @@ func indexPartial() templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_10 := `bin is a simple paste bin.`
|
||||
_, err = templBuffer.WriteString(var_10)
|
||||
var_12 := `bin is a simple paste bin.`
|
||||
_, err = templBuffer.WriteString(var_12)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -175,7 +198,7 @@ func indexPartial() templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = boostButton("new", "/new").Render(ctx, templBuffer)
|
||||
err = components.BoostButton("new", "/new").Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -186,7 +209,7 @@ func indexPartial() templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func newFull(wantsText bool) templ.Component {
|
||||
func NewFull(wantsText bool) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -194,16 +217,16 @@ func newFull(wantsText bool) templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_11 := templ.GetChildren(ctx)
|
||||
if var_11 == nil {
|
||||
var_11 = templ.NopComponent
|
||||
var_13 := templ.GetChildren(ctx)
|
||||
if var_13 == nil {
|
||||
var_13 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
err = page(
|
||||
newPartial(wantsText),
|
||||
defaultMenu,
|
||||
NewPartial(wantsText),
|
||||
models.DefaultMenu,
|
||||
1,
|
||||
nil,
|
||||
"upload",
|
||||
).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -223,7 +246,7 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}`
|
||||
|
||||
func newPartial(wantsText bool) templ.Component {
|
||||
func NewPartial(wantsText bool) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -231,17 +254,17 @@ func newPartial(wantsText bool) templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_12 := templ.GetChildren(ctx)
|
||||
if var_12 == nil {
|
||||
var_12 = templ.NopComponent
|
||||
var_14 := templ.GetChildren(ctx)
|
||||
if var_14 == nil {
|
||||
var_14 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<h2 class=\"text-xl\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_13 := `submit a new file`
|
||||
_, err = templBuffer.WriteString(var_13)
|
||||
var_15 := `submit a new file`
|
||||
_, err = templBuffer.WriteString(var_15)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -249,8 +272,8 @@ func newPartial(wantsText bool) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_14 := `file name:`
|
||||
_, err = templBuffer.WriteString(var_14)
|
||||
var_16 := `file name:`
|
||||
_, err = templBuffer.WriteString(var_16)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -258,8 +281,8 @@ func newPartial(wantsText bool) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_15 := `language:`
|
||||
_, err = templBuffer.WriteString(var_15)
|
||||
var_17 := `language:`
|
||||
_, err = templBuffer.WriteString(var_17)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -267,7 +290,7 @@ func newPartial(wantsText bool) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = chooseSyntax("lang").Render(ctx, templBuffer)
|
||||
err = components.ChooseSyntax("lang").Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -275,8 +298,8 @@ func newPartial(wantsText bool) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_16 := `description:`
|
||||
_, err = templBuffer.WriteString(var_16)
|
||||
var_18 := `description:`
|
||||
_, err = templBuffer.WriteString(var_18)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -285,7 +308,7 @@ func newPartial(wantsText bool) templ.Component {
|
|||
return err
|
||||
}
|
||||
if wantsText {
|
||||
err = newTextSubmit().Render(ctx, templBuffer)
|
||||
err = partials.NewTextSubmit().Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -294,12 +317,12 @@ func newPartial(wantsText bool) templ.Component {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
err = newFileUpload().Render(ctx, templBuffer)
|
||||
err = partials.NewFileUpload().Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = submitFormButton("submit").Render(ctx, templBuffer)
|
||||
err = components.SubmitFormButton("submit").Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -314,7 +337,7 @@ func newPartial(wantsText bool) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func binFull(file File) templ.Component {
|
||||
func BinFull(file models.File) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -322,16 +345,16 @@ func binFull(file File) templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_17 := templ.GetChildren(ctx)
|
||||
if var_17 == nil {
|
||||
var_17 = templ.NopComponent
|
||||
var_19 := templ.GetChildren(ctx)
|
||||
if var_19 == nil {
|
||||
var_19 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
err = page(
|
||||
binPartial(file),
|
||||
defaultMenu,
|
||||
BinPartial(file),
|
||||
models.DefaultMenu,
|
||||
-1,
|
||||
nil,
|
||||
file.Filename,
|
||||
).Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -343,7 +366,7 @@ func binFull(file File) templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func binPartial(file File) templ.Component {
|
||||
func BinPartial(file models.File) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -351,17 +374,17 @@ func binPartial(file File) templ.Component {
|
|||
defer templ.ReleaseBuffer(templBuffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
var_18 := templ.GetChildren(ctx)
|
||||
if var_18 == nil {
|
||||
var_18 = templ.NopComponent
|
||||
var_20 := templ.GetChildren(ctx)
|
||||
if var_20 == nil {
|
||||
var_20 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, err = templBuffer.WriteString("<div><h1 class=\"text-xl my-2 inline-block\">")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_19 string = file.Filename
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_19))
|
||||
var var_21 string = file.Filename
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_21))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -370,21 +393,21 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_20 := `(`
|
||||
_, err = templBuffer.WriteString(var_20)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_21 string = file.Language
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_21))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_22 := `)`
|
||||
var_22 := `(`
|
||||
_, err = templBuffer.WriteString(var_22)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_23 string = file.Language
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_23))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_24 := `)`
|
||||
_, err = templBuffer.WriteString(var_24)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("</sup>")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -394,8 +417,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_23 string = file.Description
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_23))
|
||||
var var_25 string = file.Description
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_25))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -403,8 +426,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_24 string = file.Data
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_24))
|
||||
var var_26 string = file.Data
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(var_26))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -416,7 +439,7 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = templBuffer.WriteString("\" hx-confirm=\"Are you sure you want to delete this?\"><input name=\"adminKey\" id=\"adminKey\" type=\"text\" class=\"mr-4 w-24 bg-amber-50\n hover:outline-slate-400 hover:outline-dotted \n focus:outline-slate-600 focus:outline-dashed\n active:outline-green-600\" placeholder=\"deletion key\" value=\"")
|
||||
_, err = templBuffer.WriteString("\" hx-confirm=\"Are you sure you want to delete this?\" hx-target=\"#main-content\"><input name=\"adminKey\" id=\"adminKey\" type=\"text\" class=\"mr-4 w-24 bg-amber-50\n hover:outline-slate-400 hover:outline-dotted \n focus:outline-slate-600 focus:outline-dashed\n active:outline-green-600\" placeholder=\"deletion key\" value=\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -428,7 +451,7 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = submitFormButton("delete").Render(ctx, templBuffer)
|
||||
err = components.SubmitFormButton("delete").Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -437,8 +460,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var var_25 templ.SafeURL = templ.URL(fmt.Sprintf("/b/%s?delcode=%s", file.PageKey, file.AdminKey))
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(string(var_25)))
|
||||
var var_27 templ.SafeURL = templ.URL(fmt.Sprintf("/b/%s?delcode=%s", file.PageKey, file.AdminKey))
|
||||
_, err = templBuffer.WriteString(templ.EscapeString(string(var_27)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -446,8 +469,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_26 := `permalink with deletion key`
|
||||
_, err = templBuffer.WriteString(var_26)
|
||||
var_28 := `permalink with deletion key`
|
||||
_, err = templBuffer.WriteString(var_28)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -460,8 +483,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_27 := `this is your deletion key! `
|
||||
_, err = templBuffer.WriteString(var_27)
|
||||
var_29 := `this is your deletion key! `
|
||||
_, err = templBuffer.WriteString(var_29)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -469,8 +492,8 @@ func binPartial(file File) templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var_28 := `you will need to store it if you want to delete the file.`
|
||||
_, err = templBuffer.WriteString(var_28)
|
||||
var_30 := `you will need to store it if you want to delete the file.`
|
||||
_, err = templBuffer.WriteString(var_30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
|
@ -1,7 +1,16 @@
|
|||
package main
|
||||
package partials
|
||||
|
||||
import "git.myrkvi.com/myrkvi/bin/views/components"
|
||||
|
||||
templ newFileUpload() {
|
||||
const placeholderCode string = `#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("Hello, world!\n");
|
||||
|
||||
return 0;
|
||||
}`
|
||||
|
||||
templ NewFileUpload() {
|
||||
<div id="file-submission" class="my-2">
|
||||
<div class="mb-4 flex flex-row justify-start space-x-4">
|
||||
<span
|
||||
|
@ -18,11 +27,11 @@ templ newFileUpload() {
|
|||
text
|
||||
</a>
|
||||
</div>
|
||||
@fileUpload("browse ...", "file", "file")
|
||||
@components.FileUpload("browse ...", "file", "file")
|
||||
</div>
|
||||
}
|
||||
|
||||
templ newTextSubmit() {
|
||||
templ NewTextSubmit() {
|
||||
<div id="file-submission" class="my-2">
|
||||
<div class="mb-4 flex flex-row justify-start space-x-4">
|
||||
<a
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by templ@v0.2.316 DO NOT EDIT.
|
||||
|
||||
package main
|
||||
package partials
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
|
@ -9,7 +9,17 @@ import "context"
|
|||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func newFileUpload() templ.Component {
|
||||
import "git.myrkvi.com/myrkvi/bin/views/components"
|
||||
|
||||
const placeholderCode string = `#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("Hello, world!\n");
|
||||
|
||||
return 0;
|
||||
}`
|
||||
|
||||
func NewFileUpload() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
||||
|
@ -44,7 +54,7 @@ func newFileUpload() templ.Component {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = fileUpload("browse ...", "file", "file").Render(ctx, templBuffer)
|
||||
err = components.FileUpload("browse ...", "file", "file").Render(ctx, templBuffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -59,7 +69,7 @@ func newFileUpload() templ.Component {
|
|||
})
|
||||
}
|
||||
|
||||
func newTextSubmit() templ.Component {
|
||||
func NewTextSubmit() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
|
||||
templBuffer, templIsBuffer := w.(*bytes.Buffer)
|
||||
if !templIsBuffer {
|
Loading…
Reference in New Issue