refactor layouts and templates, initial commit of FAQs page, preview of json generation

This commit is contained in:
James Ravenscroft 2022-02-20 15:07:29 +00:00
parent 781c003bad
commit 306af3dcc1
23 changed files with 393 additions and 125 deletions

View File

@ -7,6 +7,10 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
const(
BROWSER_TIME_FORMAT = "2006-01-02T15:04"
)
var config *viper.Viper var config *viper.Viper
// Init is an exported method that takes the environment starts the viper // Init is an exported method that takes the environment starts the viper

View File

@ -4,7 +4,6 @@ import (
"net/http" "net/http"
"git.jamesravey.me/ravenscroftj/indiescrobble/models" "git.jamesravey.me/ravenscroftj/indiescrobble/models"
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -24,6 +23,21 @@ func Index(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{ c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "test", "title": "test",
"user": user, "user": user,
"scrobbleTypes": scrobble.ScrobbleTypeNames, })
}
func FAQ(c *gin.Context){
currentUser, exists := c.Get("user")
var user *models.BaseUser
if exists {
user = currentUser.(*models.BaseUser)
}else{
user = nil
}
c.HTML(http.StatusOK, "faq.tmpl", gin.H{
"user": user,
}) })
} }

3
controllers/posts.go Normal file
View File

@ -0,0 +1,3 @@
package controllers
/* Controllers concerning accessing user posts */

View File

@ -4,9 +4,10 @@ import (
"net/http" "net/http"
"time" "time"
"git.jamesravey.me/ravenscroftj/indiescrobble/config"
"git.jamesravey.me/ravenscroftj/indiescrobble/models" "git.jamesravey.me/ravenscroftj/indiescrobble/models"
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
"git.jamesravey.me/ravenscroftj/indiescrobble/services/micropub" "git.jamesravey.me/ravenscroftj/indiescrobble/services/micropub"
"git.jamesravey.me/ravenscroftj/indiescrobble/services/scrobble"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -36,7 +37,20 @@ func (s *ScrobbleController) DoScrobble(c *gin.Context){
return return
} }
s.scrobbler.Scrobble(&c.Request.Form, currentUser) post, err := s.scrobbler.Scrobble(&c.Request.Form, currentUser)
if err != nil{
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
"message": err,
})
return
}
c.HTML(http.StatusOK, "scrobble/done.tmpl", gin.H{
"user": currentUser,
"scrobbleTypeName": scrobble.ScrobbleTypeNames[post.PostType],
"post": post,
})
} }
@ -69,13 +83,13 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
}) })
return return
}else{ }else{
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ c.HTML(http.StatusOK, "scrobble/compose.tmpl", gin.H{
"user": currentUser, "user": currentUser,
"scrobbleType": scrobbleType, "scrobbleType": scrobbleType,
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
"item": item, "item": item,
"now": time.Now().Format("2006-01-02T15:04"), "now": time.Now().Format(config.BROWSER_TIME_FORMAT),
}) })
return return
} }
@ -91,7 +105,7 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
return return
} }
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{
"user": currentUser, "user": currentUser,
"scrobbleType": scrobbleType, "scrobbleType": scrobbleType,
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
@ -100,18 +114,25 @@ func (s *ScrobbleController) ScrobbleForm(c *gin.Context){
"searchResults": searchResults, "searchResults": searchResults,
"now": time.Now().Format("2006-01-02T15:04"), "now": time.Now().Format("2006-01-02T15:04"),
}) })
}else{ }else if scrobbleType := c.Request.Form.Get("type"); scrobbleType != "" {
c.HTML(http.StatusOK, "scrobble.tmpl", gin.H{ c.HTML(http.StatusOK, "scrobble/search.tmpl", gin.H{
"user": currentUser, "user": currentUser,
"scrobbleType": scrobbleType, "scrobbleType": scrobbleType,
"scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType], "scrobblePlaceholder": scrobble.ScrobblePlaceholders[scrobbleType],
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
"now": time.Now().Format("2006-01-02T15:04"), "now": time.Now().Format("2006-01-02T15:04"),
}) })
}else{
c.HTML(http.StatusOK, "scrobble/begin.tmpl", gin.H{
"user": currentUser,
"scrobbleTypes": scrobble.ScrobbleTypeNames,
"now": time.Now().Format("2006-01-02T15:04"),
})
} }
} }
/*Preview the content of a scrobble to be submitted to \*/
func (s *ScrobbleController) PreviewScrobble(c *gin.Context){ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
err := c.Request.ParseForm() err := c.Request.ParseForm()
@ -125,21 +146,17 @@ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
}) })
} }
scrobbleType := c.Request.Form.Get("type") post, err := s.scrobbler.Preview(&c.Request.Form)
searchEngine := scrobble.NewSearchProvider(scrobbleType, s.db)
itemID := c.Request.Form.Get("item")
item, err := searchEngine.SearchProvider.GetItem(itemID)
if err != nil{ if err != nil{
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{ c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
"message": err, "message": err,
}) })
return
} }
scrobbleType := c.Request.Form.Get("type")
discovery := micropub.MicropubDiscoveryService{} discovery := micropub.MicropubDiscoveryService{}
config, err := discovery.Discover(currentUser.Me, currentUser.Token ) config, err := discovery.Discover(currentUser.Me, currentUser.Token )
@ -151,15 +168,23 @@ func (s *ScrobbleController) PreviewScrobble(c *gin.Context){
return return
} }
c.HTML(http.StatusOK, "preview.tmpl", gin.H{ postBody, err := s.scrobbler.BuildMicroPubPayload(post)
if err != nil{
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
"message": err,
})
return
}
c.HTML(http.StatusOK, "scrobble/preview.tmpl", gin.H{
"user": currentUser, "user": currentUser,
"scrobbleType": scrobbleType, "scrobbleType": scrobbleType,
"scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType], "scrobbleTypeName": scrobble.ScrobbleTypeNames[scrobbleType],
"item": item, "post": post,
"when": c.Request.Form.Get("when"),
"rating": c.Request.Form.Get("rating"),
"content": c.Request.Form.Get("content"),
"config": config, "config": config,
"summary": s.scrobbler.GenerateSummary(post),
"postBody": string(postBody),
}) })
} }

View File

@ -16,4 +16,5 @@ type Post struct {
MediaItem MediaItem MediaItem MediaItem
ScrobbledAt sql.NullTime ScrobbledAt sql.NullTime
Content sql.NullString Content sql.NullString
Rating sql.NullString
} }

View File

@ -24,6 +24,7 @@ func NewRouter(db *gorm.DB) *gin.Engine {
router.Use(middlewares.AuthMiddleware(false, iam)) router.Use(middlewares.AuthMiddleware(false, iam))
router.GET("/", controllers.Index) router.GET("/", controllers.Index)
router.GET("/faqs", controllers.FAQ)
router.Static("/static", config.GetString("server.static_path")) router.Static("/static", config.GetString("server.static_path"))

View File

@ -32,6 +32,6 @@ func Init() {
db.AutoMigrate(&models.User{}, &models.Post{}, &models.MediaItem{}) db.AutoMigrate(&models.User{}, &models.Post{}, &models.MediaItem{})
r := NewRouter(db) r := NewRouter(db)
r.LoadHTMLGlob("templates/*.tmpl") r.LoadHTMLGlob("templates/**/*.tmpl")
r.Run(fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port"))) r.Run(fmt.Sprintf("%v:%v", config.GetString("server.host"), config.GetString("server.port")))
} }

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"net/url" "net/url"
"time" "time"
@ -67,7 +68,7 @@ func (s *Scrobbler) GetSearchEngineNameForType(scrobbleType string) string {
return NewSearchProvider(scrobbleType, s.db).SearchProvider.GetName() return NewSearchProvider(scrobbleType, s.db).SearchProvider.GetName()
} }
func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) { func (s *Scrobbler) BuildMicroPubPayload(post *models.Post) ([]byte, error) {
postObj := make(map[string]interface{}) postObj := make(map[string]interface{})
postObj["type"] = []string{"h-entry"} postObj["type"] = []string{"h-entry"}
postObj["visibility"] = []string{"public"} postObj["visibility"] = []string{"public"}
@ -82,7 +83,7 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) {
properties["rating"] = []string{post.Rating.String} properties["rating"] = []string{post.Rating.String}
} }
properties["summary"] = fmt.Sprintf("%v %v and gave it %v/5", ScrobbleTypeVerbs[post.PostType], post.MediaItem.DisplayName.String, post.Rating.String) properties["summary"] = []string{s.GenerateSummary(post)}
citationProps := make(map[string]interface{}) citationProps := make(map[string]interface{})
@ -105,7 +106,46 @@ func (s *Scrobbler) buildMicroPubPayload(post *models.Post) ([]byte, error) {
postObj["properties"] = properties postObj["properties"] = properties
return json.Marshal(postObj) return json.MarshalIndent(postObj, ""," ")
}
func (s *Scrobbler) GenerateSummary(post *models.Post) string{
return fmt.Sprintf("%v %v %v and gave it %v/5",
ScrobbleTypeEmojis[post.PostType],
ScrobbleTypeVerbs[post.PostType],
post.MediaItem.DisplayName.String,
post.Rating.String)
}
func (s *Scrobbler) Preview(form *url.Values) (*models.Post, error) {
if err := s.ValidateType(form); err != nil{
return nil, err
}
item := models.MediaItem{}
result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item)
if result.Error != nil{
return nil, result.Error
}
post := models.Post{
MediaItem: item,
PostType: form.Get("type"),
Content: sql.NullString{String: form.Get("content"), Valid: true},
Rating: sql.NullString{String: form.Get("rating"), Valid: true},
}
time, err := time.Parse(config.BROWSER_TIME_FORMAT, form.Get("when"))
if err == nil{
post.ScrobbledAt = sql.NullTime{Time: time, Valid: true}
}else{
log.Printf("Failed to parse time %v because %v",form.Get("when"), err )
}
return &post, nil
} }
func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*models.Post, error) { func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*models.Post, error) {
@ -118,6 +158,7 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item) result := s.db.Where(&models.MediaItem{MediaID: form.Get("item")}).First(&item)
if result.Error != nil{ if result.Error != nil{
log.Printf("Error finding media item with ID %v in db: %v\n", form.Get("item"), result.Error)
return nil, result.Error return nil, result.Error
} }
@ -138,28 +179,29 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
if err == nil{ if err == nil{
post.ScrobbledAt = sql.NullTime{Time: time, Valid: true} post.ScrobbledAt = sql.NullTime{Time: time, Valid: true}
}else{ }else{
fmt.Errorf("Failed to parse time %v because %v",form.Get("when"), err ) log.Printf("Failed to parse time %v because %v",form.Get("when"), err )
} }
postBody, err := s.buildMicroPubPayload(&post) postBody, err := s.BuildMicroPubPayload(&post)
fmt.Printf("Post body: %v\n", string(postBody))
if err != nil{ if err != nil{
return nil, err return nil, err
} }
log.Printf("Send post payload to %v\n", currentUser.Me)
resp, err := discovery.SubmitMicropub(currentUser, postBody) resp, err := discovery.SubmitMicropub(currentUser, postBody)
if err != nil{ if err != nil{
log.Printf("Error creating user post: %v\n", err)
return nil, err return nil, err
} }
loc, err := resp.Location() loc, err := resp.Location()
if err != nil{ if err != nil{
log.Printf("Error getting Location header from user micropub endpoint: %v\n", err)
return nil, err return nil, err
} }
@ -167,6 +209,7 @@ func (s *Scrobbler) Scrobble(form *url.Values, currentUser *models.BaseUser) (*m
result = s.db.Create(&post) result = s.db.Create(&post)
if result.Error != nil{ if result.Error != nil{
log.Printf("Error creating post in database: %v\n", result.Error)
return nil, result.Error return nil, result.Error
} }

View File

@ -7,6 +7,13 @@ const(
SCROBBLE_TYPE_READ = "read" SCROBBLE_TYPE_READ = "read"
) )
var ScrobbleTypeEmojis = map[string]string {
"scrobble" : "🎧",
"tv" : "📺",
"movie": "🎬",
"read": "📖",
};
var ScrobbleTypeNames = map[string]string { var ScrobbleTypeNames = map[string]string {
"scrobble" : "🎧 Listen", "scrobble" : "🎧 Listen",
"tv" : "📺 TV Show", "tv" : "📺 TV Show",

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
{{ template "head.tmpl" . }}
<body>
{{ template "header.tmpl" . }}
<main>
<h2>Error</h2>
{{ .message }}
</main>
</body>
</html>

View File

@ -1,7 +0,0 @@
{{ define "header.tmpl" }}
<header>
<h1>
IndieScrobble
</h1>
</header>
{{end}}

View File

@ -0,0 +1,13 @@
{{ define "error.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
<h2>Error</h2>
{{ .message }}
</main>
</body>
</html>
{{ end }}

21
templates/pages/faq.tmpl Normal file
View File

@ -0,0 +1,21 @@
{{ define "faq.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
for posting about your watches, reads and scrobbles directly back to your site.</p>
<h3>Is it copyright infringement to display movie/tv posters, book covers, album covers on my website?</h3>
<p>I am not a lawyer however, it is my understanding that review is an example of "fair usage" of related promotional material
as per <a href="https://splc.org/2019/03/ask-splc-can-we-use-an-image-found-online-to-illustrate-a-movie-review/">this legal thread</a></p>
</main>
{{ template "partial/footer.tmpl" . }}
</body>
</html>
{{end}}

View File

@ -0,0 +1,32 @@
{{ define "index.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
<p>Welcome to indiescrobble! IndieScrobble is a <a href="https://micropub.spec.indieweb.org/">MicroPub</a> compliant tool
for posting about your watches, reads and scrobbles directly back to your site.</p>
{{ if .user }}
<ul>
<li><a href="/scrobble/">Add a scrobble</a></li>
<li><a href="/posts">View your posts</a></li>
</ul>
{{else}}
<form action="/indieauth" method="POST">
<p>
<label>Your domain: </label>
<input type="text" name="domain"/>
<button type="submit">Log in</button>
</p>
</form>
{{ end }}
</main>
{{ template "partial/footer.tmpl" . }}
</body>
</html>
{{end}}

View File

@ -1,4 +1,4 @@
{{ define "footer.tmpl" }} {{ define "partial/footer.tmpl" }}
<footer> <footer>
IndieScrobble is a FLOSS service provided by <a href="https://brainsteam.co.uk">James Ravenscroft</a>. It is licensed under AGPL-3.0. IndieScrobble is a FLOSS service provided by <a href="https://brainsteam.co.uk">James Ravenscroft</a>. It is licensed under AGPL-3.0.
</footer> </footer>

View File

@ -1,4 +1,4 @@
{{ define "head.tmpl" }} {{ define "partial/head.tmpl" }}
<head> <head>
<link rel="stylesheet" href="/static/css/simple-v1.css" /> <link rel="stylesheet" href="/static/css/simple-v1.css" />
<link rel="stylesheet" href="/static/css/indiescrobble.css" /> <link rel="stylesheet" href="/static/css/indiescrobble.css" />

View File

@ -0,0 +1,23 @@
{{ define "partial/header.tmpl" }}
<header>
<nav>
<a href="/">Home</a>
<a href="/faqs">About/FAQs</a>
{{ if .user }}
<a href="/scrobble/">Add a Scrobble</a>
<a href="">My Posts</a>
<a href="">My Settings</a>
{{else}}
<a href="/">Sign in via IndieAuth</a>
{{end}}
</nav>
<h1>
IndieScrobble
</h1>
{{ if .user.Me }}
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
{{end}}
</header>
{{end}}

View File

@ -1,65 +0,0 @@
{{ define "preview.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "head.tmpl" . }}
<body>
{{ template "header.tmpl" . }}
<main>
{{ $scrobbleType := .scrobbleType }}
{{ if .user }}
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
{{end}}
<form method="POST" action="/scrobble/do">
<p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> &gt; {{.item.GetDisplayName}}</p>
<h3>Preview Post: {{.item.GetDisplayName}}</h3>
<div class="float-left">
{{if .item.GetThumbnailURL}}
<img class="thumbnail" src="{{.item.GetThumbnailURL}}"/>
{{end}}
</div>
<div>
<label>When: <b>{{.when}}</b></label> <input type="hidden" name="when" value="{{.when}}" /><br/>
<label>Rating: (out of 5)</label> <b>{{.rating}}</b> <input type="hidden" name="rating" value="{{.rating}}"/> <br/>
<label>Note/Content: </label> <br>
<pre>{{.content}}</pre>
<input type="hidden" name="content" value="{{.content}}"/>
{{if .config.SyndicateTargets}}
<h3>Syndication Options</h3>
{{ range $target := .config.SyndicateTargets}}
<label><input type="checkbox" name="mp-syndicate[]" value="{{$target.Uid}}" /> {{$target.Name}}</label><br />
{{end}}
{{end}}
<br/>
<button type="submit">Submit Post &gt; &gt;</button>
</div>
<input type="hidden" name="item" value="{{.item.GetID}}"/>
<input type="hidden" name="type" value="{{ .scrobbleType }}"/>
</form>
</main>
{{ template "footer.tmpl" . }}
</body>
</html>
{{end}}

View File

@ -1,8 +1,9 @@
{{ define "scrobble/begin.tmpl" }}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
{{ template "head.tmpl" . }} {{ template "partial/head.tmpl" . }}
<body> <body>
{{ template "header.tmpl" . }} {{ template "partial/header.tmpl" . }}
<main> <main>
{{ if .user }} {{ if .user }}
@ -35,3 +36,4 @@
{{ template "footer.tmpl" . }} {{ template "footer.tmpl" . }}
</body> </body>
</html> </html>
{{end}}

View File

@ -0,0 +1,47 @@
{{ define "scrobble/compose.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
{{ $scrobbleType := .scrobbleType }}
<form method="POST" action="/scrobble/preview">
<p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type=movie">Add {{ .scrobbleTypeName }}</a> &gt; {{.item.GetDisplayName}}</p>
<h3>{{.item.GetDisplayName}}</h3>
<div class="float-left">
{{if .item.GetThumbnailURL}}
<img class="thumbnail" src="{{.item.GetThumbnailURL}}"/>
{{end}}
</div>
<div>
<label>When: </label> <input type="datetime-local" name='when' value="{{.now}}"/><br/>
<label>Rating: (out of 5)</label> <input type="number" name='rating'/><br/>
<label>Note/Content: </label> <br>
<textarea rows="6" name='content'></textarea>
<br/>
<button type="submit">Preview &gt; &gt;</button>
</div>
<input type="hidden" name="item" value="{{.item.GetID}}"/>
<input type="hidden" name="type" value="{{.scrobbleType}}"/>
</form>
</main>
{{ template "partial/footer.tmpl" . }}
</body>
</html>
{{end}}

View File

@ -1,24 +1,20 @@
{{ define "scrobbled.tmpl" }} {{ define "scrobble/done.tmpl" }}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
{{ template "head.tmpl" . }} {{ template "partial/head.tmpl" . }}
<body> <body>
{{ template "header.tmpl" . }} {{ template "partial/header.tmpl" . }}
<main> <main>
{{ $scrobbleType := .scrobbleType }} {{ $scrobbleType := .scrobbleType }}
{{ if .user }}
Logged in as {{.user.Me}} <a href="/logout"><button>Log Out</button></a>
{{end}}
<p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> &gt; {{.post.MediaItem.DisplayName.String}}</p> <p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> &gt; {{.post.MediaItem.DisplayName.String}}</p>
<h3>Post Complete: <a href="{{.post.URL}}">{{.post.URL}}</a></h3> <h3>Post Complete: <a href="{{.post.URL}}">{{.post.URL}}</a></h3>
</main> </main>
{{ template "footer.tmpl" . }} {{ template "partial/footer.tmpl" . }}
</body> </body>
</html> </html>
{{end}} {{end}}

View File

@ -0,0 +1,73 @@
{{ define "scrobble/preview.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
{{ $scrobbleType := .scrobbleType }}
<form method="POST" action="/scrobble/do">
<p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type={{ .scrobbleType }}">Add {{ .scrobbleTypeName }}</a> &gt; {{.post.MediaItem.DisplayName.String}}</p>
<h3>Preview Post: {{.post.MediaItem.DisplayName.String}}</h3>
<h4>Summary</h4>
<p>{{.summary}}</p>
<h4>Thumbnail</h4>
<div class="float-left">
{{if .post.MediaItem.ThumbnailURL.Valid}}
<img class="thumbnail" src="{{.post.MediaItem.ThumbnailURL.String}}"/>
{{end}}
</div>
<div>
<h4>Details</h4>
<label>When: <b>{{.post.ScrobbledAt.Time}}</b></label> <input type="hidden" name="when" value="{{.when}}" /><br/>
<label>Rating: (out of 5)</label> <b>{{.post.Rating.String}}</b> <input type="hidden" name="rating" value="{{.rating}}"/> <br/>
<label>Note/Content: </label> <br>
<blockquote>{{.post.Content.String}}</blockquote>
<input type="hidden" name="content" value="{{.post.Content.String}}"/>
{{if .config.SyndicateTargets}}
<h4>Syndication Options</h4>
{{ range $target := .config.SyndicateTargets}}
<label><input type="checkbox" name="mp-syndicate[]" value="{{$target.Uid}}" /> {{$target.Name}}</label><br />
{{end}}
{{end}}
<br/>
<details>
<summary>Micropub Payload Details</summary>
<pre>{{.postBody}}</pre>
</details>
<button type="submit">Submit Post &gt; &gt;</button>
</div>
<input type="hidden" name="item" value="{{.post.MediaItem.MediaID}}"/>
<input type="hidden" name="type" value="{{ .scrobbleType }}"/>
</form>
</main>
{{ template "partial/footer.tmpl" . }}
</body>
</html>
{{end}}

View File

@ -0,0 +1,46 @@
{{ define "scrobble/search.tmpl" }}
<!DOCTYPE html>
<html lang="en">
{{ template "partial/head.tmpl" . }}
<body>
{{ template "partial/header.tmpl" . }}
<main>
{{ $scrobbleType := .scrobbleType }}
{{if .searchResults}}
<p><a href="/">Add A Post</a> &gt; <a href="/scrobble?type=movie">Add {{ .scrobbleTypeName }}</a> &gt; {{.searchEngine}} Results</p>
<ul>
{{ $scrobbleType := .scrobbleType }}
{{range $result := .searchResults}}
<li>
<a href="/scrobble?type={{$scrobbleType}}&item={{$result.GetID}}">{{$result.GetDisplayName}}</a>
<a href="{{$result.GetCanonicalURL}}" target="_blank">(🔍more info)</a>
</li>
{{end}}
</ul>
{{ else }}
<form method="GET" action="/scrobble">
<h2><a href="/">Add A Post</a> Add {{ .scrobbleTypeName }}</h2>
<p>Search <b>{{.searchEngine}}</b> for items to scrobble<p>
<input type="text" name="q" placeholder="{{.scrobblePlaceholder}}">
<button type="submit">Next &gt;&gt;</button>
<input type="hidden" name="type" value="{{.scrobbleType}}"/>
</form>
{{end}}
</main>
{{ template "partial/footer.tmpl" . }}
</body>
</html>
{{end}}