Browse Source

Add messages system (for {error,success,info,...} messages)

tags/v0.2.0b
Morgan Bazalgette 3 years ago
parent
commit
8f02dbb22d
10 changed files with 179 additions and 6 deletions
  1. 5
    1
      context.go
  2. 1
    1
      homepage.go
  3. 32
    3
      main.go
  4. 41
    0
      messages.go
  5. 1
    1
      not_found.go
  6. 50
    0
      sessions.go
  7. 14
    0
      static/ripple.css
  8. 10
    0
      static/ripple.js
  9. 14
    0
      templates.go
  10. 11
    0
      templates/base.html

+ 5
- 1
context.go View File

@@ -1,6 +1,10 @@
package main

type context struct {
User struct{ Username string }
User sessionUser
Token string
}
type sessionUser struct {
ID int
Username string
}

+ 1
- 1
homepage.go View File

@@ -9,7 +9,7 @@ type homePageData struct {

func homePage(c *gin.Context) {
posts := getBlogPosts(5)
resp(c, 200, "homepage.html", homePageData{
resp(c, 200, "homepage.html", &homePageData{
baseTemplateData: baseTemplateData{
TitleBar: "Home Page",
KyutGrill: "homepage.jpg",

+ 32
- 3
main.go View File

@@ -2,6 +2,7 @@ package main

import (
"database/sql"
"encoding/gob"
"fmt"

"git.zxq.co/ripple/schiavolib"
@@ -14,13 +15,18 @@ import (

var (
c struct {
DSN string
CookieSecret string
DSN string

CookieSecret string

RedisEnable bool
RedisMaxConnections int
RedisNetwork string
RedisAddress string
RedisPassword string

AvatarURL string
BaseURL string
}
db *sql.DB
)
@@ -43,6 +49,12 @@ func main() {
if c.CookieSecret == "" {
c.CookieSecret = rs.String(46)
}
if c.AvatarURL == "" {
c.AvatarURL = "https://a.ripple.moe"
}
if c.BaseURL == "" {
c.BaseURL = "https://ripple.moe"
}

db, err = sql.Open("mysql", c.DSN)
if err != nil {
@@ -77,6 +89,17 @@ func main() {
} else {
store = sessions.NewCookieStore([]byte(c.CookieSecret))
}
gobRegisters := []interface{}{
[]message{},
errorMessage{},
infoMessage{},
neutralMessage{},
warningMessage{},
successMessage{},
}
for _, el := range gobRegisters {
gob.Register(el)
}

fmt.Println("Importing templates...")
loadTemplates()
@@ -85,11 +108,17 @@ func main() {

r := gin.Default()

r.Use(sessions.Sessions("session", store))
r.Use(
sessions.Sessions("session", store),
sessionInitializer(),
)

r.Static("/static", "static")

r.GET("/", homePage)
r.GET("/test", func(c *gin.Context) {
addMessage(c, errorMessage{"test"})
})

r.NoRoute(notFound)


+ 41
- 0
messages.go View File

@@ -0,0 +1,41 @@
package main

type message interface {
Type() string
Content() string
}

type errorMessage struct {
C string
}

func (errorMessage) Type() string { return "error" }
func (m errorMessage) Content() string { return m.C }

type neutralMessage struct {
C string
}

func (neutralMessage) Type() string { return "" }
func (m neutralMessage) Content() string { return m.C }

type infoMessage struct {
C string
}

func (infoMessage) Type() string { return "info" }
func (m infoMessage) Content() string { return m.C }

type successMessage struct {
C string
}

func (successMessage) Type() string { return "positive" }
func (m successMessage) Content() string { return m.C }

type warningMessage struct {
C string
}

func (warningMessage) Type() string { return "warning" }
func (m warningMessage) Content() string { return m.C }

+ 1
- 1
not_found.go View File

@@ -3,7 +3,7 @@ package main
import "github.com/gin-gonic/gin"

func notFound(c *gin.Context) {
resp(c, 200, "not_found.html", baseTemplateData{
resp(c, 200, "not_found.html", &baseTemplateData{
TitleBar: "Not Found",
KyutGrill: "not_found.jpg",
})

+ 50
- 0
sessions.go View File

@@ -0,0 +1,50 @@
package main

import (
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
)

func sessionInitializer() func(c *gin.Context) {
return func(c *gin.Context) {
sess := sessions.Default(c)

var ctx context
tok := sess.Get("token")
if tok, ok := tok.(string); ok {
ctx.Token = tok
}
userid := sess.Get("userid")
if userid, ok := userid.(int); ok {
ctx.User.ID = userid
db.QueryRow("SELECT username FROM users WHERE id = ?", userid).Scan(&ctx.User.Username)
}
c.Set("context", ctx)
c.Set("session", sess)

c.Next()
}
}

func addMessage(c *gin.Context, m message) {
sess := c.MustGet("session").(sessions.Session)
var messages []message
messagesRaw := sess.Get("messages")
if messagesRaw != nil {
messages = messagesRaw.([]message)
}
messages = append(messages, m)
sess.Set("messages", messages)
sess.Save()
}

func getMessages(c *gin.Context) []message {
sess := c.MustGet("session").(sessions.Session)
messagesRaw := sess.Get("messages")
if messagesRaw == nil {
return nil
}
sess.Delete("messages")
sess.Save()
return messagesRaw.([]message)
}

+ 14
- 0
static/ripple.css View File

@@ -48,3 +48,17 @@ a.inherit {
a.inherit:hover {
opacity: 1;
}

.autopad {
margin: 1rem 0;
}
.autopad:first-child {
margin-top: 0;
}
.autopad:last-child {
margin-bottom: 0;
}

.margined.container {
margin: 1rem;
}

+ 10
- 0
static/ripple.js View File

@@ -0,0 +1,10 @@
// Ripple custom JS that goes on all pages

$('.message .close')
.on('click', function() {
$(this)
.closest('.message')
.transition('fade')
;
})
;

+ 14
- 0
templates.go View File

@@ -66,10 +66,15 @@ func resp(c *gin.Context, statusCode int, tpl string, data interface{}) {
c.String(500, "Template not found! Please tell this to a dev!")
return
}
// dirty hack to allow SetMessages to work if needed
if corrected, ok := data.(messageSetter); ok {
corrected.SetMessages(getMessages(c))
}
c.Status(statusCode)
err := t.ExecuteTemplate(c.Writer, "base", data)
if err != nil {
c.Writer.WriteString("What on earth? Please tell this to a dev!")
fmt.Println(err)
schiavo.Bunker.Send(err.Error())
}
}
@@ -80,6 +85,15 @@ type baseTemplateData struct {
KyutGrill string
Context context
Path string
Messages []message
}

func (b *baseTemplateData) SetMessages(m []message) {
b.Messages = m
}

type messageSetter interface {
SetMessages(m []message)
}

func reloader() error {

+ 11
- 0
templates/base.html View File

@@ -19,12 +19,23 @@
</div>
<div class="h-container">
{{ if .Messages }}
<div class="ui padded margined container">
{{ range $i, $v := .Messages }}
<div class="ui {{ $v.Type }} message">
<i class="close icon"></i>
{{ $v.Content }}
</div>
{{ end }}
</div>
{{ end }}
{{ template "tpl" . }}
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.min.js"></script>
<script src="static/semantic.min.js"></script>
<script src="static/ripple.js"></script>
{{/* If we got some more scripts to print, print'em */}}
{{ if .Scripts }}
{{ range .Scripts }}

Loading…
Cancel
Save