mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-19 02:27:03 +00:00
Many small refinements to front/backend UI
Changes: - Added a friendlyTime helper for nicer timestamps - Added validation to most action methods - Added error flash to several template files - Now making use to c.RenderError() to handle action errors - Removed message list slideUp() effect, takes too long - Fixed a problem with my vim indentation configuration, so CSS and HTML should be indented more consistently.
This commit is contained in:
19
app/controllers/helpers.go
Normal file
19
app/controllers/helpers.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/robfig/revel"
|
||||||
|
"html/template"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rev.TRACE.Println("Registering helpers")
|
||||||
|
rev.Funcs["friendlyTime"] = func(t time.Time) template.HTML {
|
||||||
|
ty, tm, td := t.Date()
|
||||||
|
ny, nm, nd := time.Now().Date()
|
||||||
|
if (ty == ny) && (tm == nm) && (td == nd) {
|
||||||
|
return template.HTML(t.Format("03:04:05 PM"))
|
||||||
|
}
|
||||||
|
return template.HTML(t.Format("Mon Jan 2, 2006"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,22 +10,34 @@ type Mailbox struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Mailbox) Index(name string) rev.Result {
|
func (c Mailbox) Index(name string) rev.Result {
|
||||||
|
c.Validation.Required(name).Message("Account name is required")
|
||||||
|
|
||||||
|
if c.Validation.HasErrors() {
|
||||||
|
c.Validation.Keep()
|
||||||
|
c.FlashParams()
|
||||||
|
return c.Redirect(Application.Index)
|
||||||
|
}
|
||||||
|
|
||||||
return c.Render(name)
|
return c.Render(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Mailbox) List(name string) rev.Result {
|
func (c Mailbox) List(name string) rev.Result {
|
||||||
|
c.Validation.Required(name).Message("Account name is required")
|
||||||
|
|
||||||
|
if c.Validation.HasErrors() {
|
||||||
|
c.Validation.Keep()
|
||||||
|
c.FlashParams()
|
||||||
|
return c.Redirect(Application.Index)
|
||||||
|
}
|
||||||
|
|
||||||
ds := inbucket.NewDataStore()
|
ds := inbucket.NewDataStore()
|
||||||
mb, err := ds.MailboxFor(name)
|
mb, err := ds.MailboxFor(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
messages, err := mb.GetMessages()
|
messages, err := mb.GetMessages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
rev.INFO.Printf("Got %v messsages", len(messages))
|
rev.INFO.Printf("Got %v messsages", len(messages))
|
||||||
|
|
||||||
@@ -34,24 +46,27 @@ func (c Mailbox) List(name string) rev.Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Mailbox) Show(name string, id string) rev.Result {
|
func (c Mailbox) Show(name string, id string) rev.Result {
|
||||||
|
c.Validation.Required(name).Message("Account name is required")
|
||||||
|
c.Validation.Required(id).Message("Message ID is required")
|
||||||
|
|
||||||
|
if c.Validation.HasErrors() {
|
||||||
|
c.Validation.Keep()
|
||||||
|
c.FlashParams()
|
||||||
|
return c.Redirect(Application.Index)
|
||||||
|
}
|
||||||
|
|
||||||
ds := inbucket.NewDataStore()
|
ds := inbucket.NewDataStore()
|
||||||
mb, err := ds.MailboxFor(name)
|
mb, err := ds.MailboxFor(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
message, err := mb.GetMessage(id)
|
message, err := mb.GetMessage(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
_, body, err := message.ReadBody()
|
_, body, err := message.ReadBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Response.Out.Header().Set("Expires", "-1")
|
c.Response.Out.Header().Set("Expires", "-1")
|
||||||
@@ -59,47 +74,53 @@ func (c Mailbox) Show(name string, id string) rev.Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Mailbox) Delete(name string, id string) rev.Result {
|
func (c Mailbox) Delete(name string, id string) rev.Result {
|
||||||
|
c.Validation.Required(name).Message("Account name is required")
|
||||||
|
c.Validation.Required(id).Message("Message ID is required")
|
||||||
|
|
||||||
|
if c.Validation.HasErrors() {
|
||||||
|
c.Validation.Keep()
|
||||||
|
c.FlashParams()
|
||||||
|
return c.Redirect(Application.Index)
|
||||||
|
}
|
||||||
|
|
||||||
ds := inbucket.NewDataStore()
|
ds := inbucket.NewDataStore()
|
||||||
mb, err := ds.MailboxFor(name)
|
mb, err := ds.MailboxFor(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
message, err := mb.GetMessage(id)
|
message, err := mb.GetMessage(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
err = message.Delete()
|
err = message.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
return c.RenderText("OK")
|
return c.RenderText("OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Mailbox) Source(name string, id string) rev.Result {
|
func (c Mailbox) Source(name string, id string) rev.Result {
|
||||||
|
c.Validation.Required(name).Message("Account name is required")
|
||||||
|
c.Validation.Required(id).Message("Message ID is required")
|
||||||
|
|
||||||
|
if c.Validation.HasErrors() {
|
||||||
|
c.Validation.Keep()
|
||||||
|
c.FlashParams()
|
||||||
|
return c.Redirect(Application.Index)
|
||||||
|
}
|
||||||
|
|
||||||
ds := inbucket.NewDataStore()
|
ds := inbucket.NewDataStore()
|
||||||
mb, err := ds.MailboxFor(name)
|
mb, err := ds.MailboxFor(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
message, err := mb.GetMessage(id)
|
message, err := mb.GetMessage(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
raw, err := message.ReadRaw()
|
raw, err := message.ReadRaw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rev.ERROR.Printf(err.Error())
|
return c.RenderError(err)
|
||||||
c.Flash.Error(err.Error())
|
|
||||||
return c.Redirect(Application.Index)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Response.Out.Header().Set("Expires", "-1")
|
c.Response.Out.Header().Set("Expires", "-1")
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
{{template "menu.html" .}}
|
{{template "menu.html" .}}
|
||||||
|
|
||||||
<div id="colTwo">
|
<div id="colTwo">
|
||||||
|
{{template "errors.html" .}}
|
||||||
|
|
||||||
<p>Inbucket is an email testing service; it will accept email for any email
|
<p>Inbucket is an email testing service; it will accept email for any email
|
||||||
address and make it available to view without a password.</p>
|
address and make it available to view without a password.</p>
|
||||||
<p>To view email for a particular address, enter the username portion
|
<p>To view email for a particular address, enter the username portion
|
||||||
|
|||||||
@@ -65,6 +65,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="colTwo">
|
<div id="colTwo">
|
||||||
|
{{template "errors.html" .}}
|
||||||
|
|
||||||
<div id="emailContent">
|
<div id="emailContent">
|
||||||
<p>Select a message at left, or enter a different username into the box on upper right.</p>
|
<p>Select a message at left, or enter a different username into the box on upper right.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{{$name := .name}}
|
{{$name := .name}}
|
||||||
{{range .messages}}
|
{{range .messages}}
|
||||||
<div class="box listEntry" id="{{.Id}}">
|
<div class="box listEntry" id="{{.Id}}">
|
||||||
<div class="subject">{{/*<a href="/mailbox/show/{{$name}}/{{.Id}}">*/}}{{.Subject}}</div>
|
<div class="subject">{{.Subject}}</div>
|
||||||
<div class="from">{{.From}}</div>
|
<div class="from">{{.From}}</div>
|
||||||
<div class="date">{{.Date}}</div>
|
<div class="date">{{friendlyTime .Date}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
|||||||
10
app/views/errors.html
Normal file
10
app/views/errors.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{{if .errors}}
|
||||||
|
<div class="errors">
|
||||||
|
<p>Please fix the following errors and resubmit:<p>
|
||||||
|
<ul>
|
||||||
|
{{range .errors}}
|
||||||
|
<li>{{.Message}}</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
@@ -304,3 +304,10 @@ a:hover {
|
|||||||
#emailActions a:hover {
|
#emailActions a:hover {
|
||||||
background: #becf74;
|
background: #becf74;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.errors {
|
||||||
|
background-color: #ffa0a0;
|
||||||
|
color: #333;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user