mirror of
https://github.com/rystaf/mlmym.git
synced 2024-11-21 21:27:15 +00:00
removed gorilla cookies, single host mode, settings page, default filter, mobile viewport style, voting xhr, docker workflow
This commit is contained in:
parent
8de7bbfa9c
commit
d61d68d9e4
36
main.go
36
main.go
|
@ -7,9 +7,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
|
@ -19,7 +17,6 @@ var watch = flag.Bool("w", false, "watch for file changes")
|
|||
var addr = flag.String("addr", ":80", "http service address")
|
||||
var md goldmark.Markdown
|
||||
var templates map[string]*template.Template
|
||||
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSIONSECRET")))
|
||||
|
||||
type AddHeaderTransport struct {
|
||||
T http.RoundTripper
|
||||
|
@ -54,7 +51,7 @@ func init() {
|
|||
md = goldmark.New(goldmark.WithExtensions(extension.Linkify))
|
||||
templates = make(map[string]*template.Template)
|
||||
if !*watch {
|
||||
for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html"} {
|
||||
for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html", "settings.html"} {
|
||||
t := template.New(name).Funcs(funcMap)
|
||||
glob, err := t.ParseGlob("templates/*")
|
||||
if err != nil {
|
||||
|
@ -81,36 +78,7 @@ func middleware(n httprouter.Handle) httprouter.Handle {
|
|||
func main() {
|
||||
flag.Parse()
|
||||
log.Println("serve", *addr)
|
||||
router := httprouter.New()
|
||||
router.ServeFiles("/:host/static/*filepath", http.Dir("public"))
|
||||
router.GET("/", GetRoot)
|
||||
router.POST("/", PostRoot)
|
||||
router.GET("/:host/", middleware(GetFrontpage))
|
||||
router.GET("/:host/search", middleware(Search))
|
||||
router.POST("/:host/search", middleware(UserOp))
|
||||
router.GET("/:host/inbox", middleware(Inbox))
|
||||
router.GET("/:host/login", middleware(GetLogin))
|
||||
router.POST("/:host/login", middleware(SignUpOrLogin))
|
||||
router.POST("/:host/", middleware(UserOp))
|
||||
router.GET("/:host/icon.jpg", middleware(GetIcon))
|
||||
router.GET("/:host/c/:community", middleware(GetFrontpage))
|
||||
router.POST("/:host/c/:community", middleware(UserOp))
|
||||
router.GET("/:host/c/:community/search", middleware(Search))
|
||||
router.GET("/:host/post/:postid", middleware(GetPost))
|
||||
router.POST("/:host/post/:postid", middleware(UserOp))
|
||||
router.GET("/:host/comment/:commentid", middleware(GetComment))
|
||||
router.GET("/:host/comment/:commentid/:op", middleware(GetComment))
|
||||
router.POST("/:host/comment/:commentid", middleware(UserOp))
|
||||
router.GET("/:host/u/:username", middleware(GetUser))
|
||||
router.GET("/:host/u/:username/message", middleware(GetMessageForm))
|
||||
router.POST("/:host/u/:username/message", middleware(SendMessage))
|
||||
router.POST("/:host/u/:username", middleware(UserOp))
|
||||
router.GET("/:host/u/:username/search", middleware(Search))
|
||||
router.GET("/:host/create_post", middleware(GetCreatePost))
|
||||
router.POST("/:host/create_post", middleware(UserOp))
|
||||
router.GET("/:host/create_community", middleware(GetCreateCommunity))
|
||||
router.POST("/:host/create_community", middleware(UserOp))
|
||||
|
||||
router := GetRouter()
|
||||
err := http.ListenAndServe(*addr, router)
|
||||
if err != nil {
|
||||
log.Fatal("ListenAndServe: ", err)
|
||||
|
|
219
routes.go
219
routes.go
|
@ -11,6 +11,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -24,6 +25,12 @@ import (
|
|||
)
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"host": func(host string) string {
|
||||
if l := os.Getenv("LEMMY_DOMAIN"); l != "" {
|
||||
return l
|
||||
}
|
||||
return host
|
||||
},
|
||||
"proxy": func(s string) string {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
|
@ -68,7 +75,7 @@ var funcMap = template.FuncMap{
|
|||
}
|
||||
return false
|
||||
},
|
||||
"host": func(p Post) string {
|
||||
"domain": func(p Post) string {
|
||||
if p.Post.URL.IsValid() {
|
||||
l, err := url.Parse(p.Post.URL.String())
|
||||
if err != nil {
|
||||
|
@ -111,8 +118,10 @@ var funcMap = template.FuncMap{
|
|||
}
|
||||
converted := buf.String()
|
||||
converted = strings.Replace(converted, `<img `, `<img loading="lazy" `, -1)
|
||||
re := regexp.MustCompile(`href="https:\/\/([a-zA-Z0-9\.]+\/(c\/[a-zA-Z0-9]+|(post|comment)\/\d+))`)
|
||||
converted = re.ReplaceAllString(converted, `href="/$1`)
|
||||
if os.Getenv("LEMMY_DOMAIN") != "" {
|
||||
re := regexp.MustCompile(`href="https:\/\/([a-zA-Z0-9\.]+\/(c\/[a-zA-Z0-9]+|(post|comment)\/\d+))`)
|
||||
converted = re.ReplaceAllString(converted, `href="/$1`)
|
||||
}
|
||||
return template.HTML(converted)
|
||||
},
|
||||
"contains": strings.Contains,
|
||||
|
@ -124,17 +133,20 @@ var funcMap = template.FuncMap{
|
|||
func Initialize(Host string, r *http.Request) (State, error) {
|
||||
state := State{
|
||||
Host: Host,
|
||||
Sort: "Hot",
|
||||
Page: 1,
|
||||
Status: http.StatusOK,
|
||||
}
|
||||
state.ParseQuery(r.URL.RawQuery)
|
||||
lemmyDomain := os.Getenv("LEMMY_DOMAIN")
|
||||
if lemmyDomain != "" {
|
||||
state.Host = "."
|
||||
Host = lemmyDomain
|
||||
}
|
||||
remoteAddr := r.RemoteAddr
|
||||
if r.Header.Get("CF-Connecting-IP") != "" {
|
||||
remoteAddr = r.Header.Get("CF-Connecting-IP")
|
||||
}
|
||||
client := http.Client{Transport: NewAddHeaderTransport(remoteAddr)}
|
||||
c, err := lemmy.NewWithClient("https://"+state.Host, &client)
|
||||
c, err := lemmy.NewWithClient("https://"+Host, &client)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
state.Status = http.StatusInternalServerError
|
||||
|
@ -142,24 +154,26 @@ func Initialize(Host string, r *http.Request) (State, error) {
|
|||
}
|
||||
state.HTTPClient = &client
|
||||
state.Client = c
|
||||
session, err := store.Get(r, state.Host)
|
||||
if err == nil {
|
||||
token, ok1 := session.Values["token"].(string)
|
||||
username, ok2 := session.Values["username"].(string)
|
||||
userid, ok3 := session.Values["id"].(int)
|
||||
if ok1 && ok2 && ok3 {
|
||||
token := getCookie(r, "jwt")
|
||||
user := getCookie(r, "user")
|
||||
parts := strings.Split(user, ":")
|
||||
if len(parts) == 2 {
|
||||
if id, err := strconv.Atoi(parts[1]); err == nil {
|
||||
state.Client.Token = token
|
||||
sess := Session{
|
||||
UserName: username,
|
||||
UserID: userid,
|
||||
UserName: parts[0],
|
||||
UserID: id,
|
||||
}
|
||||
state.Session = &sess
|
||||
if state.Listing == "" {
|
||||
state.Listing = "Subscribed"
|
||||
}
|
||||
}
|
||||
}
|
||||
if state.Listing == "" {
|
||||
state.Listing = getCookie(r, "DefaultListingType")
|
||||
state.Sort = getCookie(r, "DefaultSortType")
|
||||
state.ParseQuery(r.URL.RawQuery)
|
||||
if state.Sort == "" {
|
||||
state.Sort = "Hot"
|
||||
}
|
||||
if state.Listing == "" || state.Session == nil && state.Listing == "Subscribed" {
|
||||
state.Listing = "All"
|
||||
}
|
||||
return state, nil
|
||||
|
@ -410,11 +424,16 @@ func GetCreatePost(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
func GetCreateCommunity(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
state, err := Initialize(ps.ByName("host"), r)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
Render(w, "index.html", state)
|
||||
return
|
||||
}
|
||||
state.GetSite()
|
||||
state.Op = "create_community"
|
||||
if ps.ByName("community") != "" {
|
||||
state.GetCommunity(ps.ByName("community"))
|
||||
state.Op = "edit_community"
|
||||
}
|
||||
Render(w, "index.html", state)
|
||||
}
|
||||
|
||||
|
@ -428,6 +447,48 @@ func Inbox(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
Render(w, "index.html", state)
|
||||
state.MarkAllAsRead()
|
||||
}
|
||||
func getCookie(r *http.Request, name string) string {
|
||||
cookie, err := r.Cookie(name)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cookie.Value
|
||||
}
|
||||
func setCookie(w http.ResponseWriter, name string, value string) {
|
||||
cookie := http.Cookie{
|
||||
Name: name,
|
||||
Value: value,
|
||||
}
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
func deleteCookie(w http.ResponseWriter, name string) {
|
||||
cookie := http.Cookie{
|
||||
Name: name,
|
||||
MaxAge: -1,
|
||||
}
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
func Settings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
state, err := Initialize(ps.ByName("host"), r)
|
||||
if err != nil {
|
||||
Render(w, "index.html", state)
|
||||
return
|
||||
}
|
||||
switch r.Method {
|
||||
case "POST":
|
||||
fmt.Println(r.FormValue("DefaultSortType"))
|
||||
for _, name := range []string{"DefaultSortType", "DefaultListingType"} {
|
||||
setCookie(w, name, r.FormValue(name))
|
||||
}
|
||||
state.Listing = r.FormValue("DefaultListingType")
|
||||
state.Sort = r.FormValue("DefaultSortType")
|
||||
case "GET":
|
||||
if state.Session != nil {
|
||||
fmt.Println("get settings")
|
||||
}
|
||||
}
|
||||
Render(w, "settings.html", state)
|
||||
}
|
||||
|
||||
func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
state, err := Initialize(ps.ByName("host"), r)
|
||||
|
@ -436,6 +497,7 @@ func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
return
|
||||
}
|
||||
var token string
|
||||
var username string
|
||||
switch r.FormValue("submit") {
|
||||
case "log in":
|
||||
resp, err := state.Client.Login(context.Background(), types.Login{
|
||||
|
@ -451,6 +513,7 @@ func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
}
|
||||
if resp.JWT.IsValid() {
|
||||
token = resp.JWT.String()
|
||||
username = r.FormValue("username")
|
||||
}
|
||||
case "sign up":
|
||||
register := types.Register{
|
||||
|
@ -480,6 +543,7 @@ func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
return
|
||||
}
|
||||
if resp.JWT.IsValid() {
|
||||
username = r.FormValue("username")
|
||||
token = resp.JWT.String()
|
||||
} else {
|
||||
var alert string
|
||||
|
@ -496,7 +560,6 @@ func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
}
|
||||
}
|
||||
if token != "" {
|
||||
session, err := store.Get(r, state.Host)
|
||||
if err != nil {
|
||||
state.Error = err
|
||||
state.GetSite()
|
||||
|
@ -504,20 +567,11 @@ func SignUpOrLogin(w http.ResponseWriter, r *http.Request, ps httprouter.Params)
|
|||
Render(w, "login.html", state)
|
||||
return
|
||||
}
|
||||
if resp, err := state.Client.Site(context.Background(), types.GetSite{
|
||||
Auth: types.NewOptional(token),
|
||||
}); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
} else if myUser, err := resp.MyUser.Value(); err == nil {
|
||||
// Error is nil when value is nil?
|
||||
return
|
||||
} else {
|
||||
session.Values["username"] = myUser.LocalUserView.Person.Name
|
||||
session.Values["id"] = myUser.LocalUserView.Person.ID
|
||||
}
|
||||
session.Values["token"] = token
|
||||
session.Save(r, w)
|
||||
state.GetUser(username)
|
||||
setCookie(w, "jwt", token)
|
||||
userid := strconv.Itoa(state.User.PersonView.Person.ID)
|
||||
setCookie(w, "user", state.User.PersonView.Person.Name+":"+userid)
|
||||
setCookie(w, "jwt", token)
|
||||
r.URL.Path = "/" + state.Host
|
||||
http.Redirect(w, r, r.URL.String(), 301)
|
||||
return
|
||||
|
@ -598,10 +652,9 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
Follow: true,
|
||||
})
|
||||
case "logout":
|
||||
if session, err := store.Get(r, state.Host); err == nil {
|
||||
session.Options.MaxAge = -1
|
||||
session.Save(r, w)
|
||||
}
|
||||
fmt.Println("logout")
|
||||
deleteCookie(w, "jwt")
|
||||
deleteCookie(w, "user")
|
||||
case "login":
|
||||
resp, err := state.Client.Login(context.Background(), types.Login{
|
||||
UsernameOrEmail: r.FormValue("user"),
|
||||
|
@ -611,14 +664,10 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
state.Status = http.StatusUnauthorized
|
||||
}
|
||||
if resp.JWT.IsValid() {
|
||||
session, err := store.Get(r, state.Host)
|
||||
if err == nil {
|
||||
state.GetUser(r.FormValue("user"))
|
||||
session.Values["token"] = resp.JWT.String()
|
||||
session.Values["username"] = state.User.PersonView.Person.Name
|
||||
session.Values["id"] = state.User.PersonView.Person.ID
|
||||
session.Save(r, w)
|
||||
}
|
||||
state.GetUser(r.FormValue("user"))
|
||||
setCookie(w, "jwt", resp.JWT.String())
|
||||
userid := strconv.Itoa(state.User.PersonView.Person.ID)
|
||||
setCookie(w, "user", state.User.PersonView.Person.Name+":"+userid)
|
||||
}
|
||||
case "create_community":
|
||||
state.GetSite()
|
||||
|
@ -804,6 +853,12 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
Score: score,
|
||||
}
|
||||
state.Client.CreatePostLike(context.Background(), post)
|
||||
if r.FormValue("xhr") != "" {
|
||||
state.GetPost(postid)
|
||||
state.XHR = true
|
||||
Render(w, "index.html", state)
|
||||
return
|
||||
}
|
||||
case "vote_comment":
|
||||
var score int16
|
||||
score = 1
|
||||
|
@ -819,6 +874,12 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
Score: score,
|
||||
}
|
||||
state.Client.CreateCommentLike(context.Background(), post)
|
||||
if r.FormValue("xhr") != "" {
|
||||
state.XHR = true
|
||||
state.GetComment(commentid)
|
||||
Render(w, "index.html", state)
|
||||
return
|
||||
}
|
||||
case "create_comment":
|
||||
if ps.ByName("postid") != "" {
|
||||
postid, _ := strconv.Atoi(ps.ByName("postid"))
|
||||
|
@ -873,3 +934,71 @@ func UserOp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
}
|
||||
http.Redirect(w, r, r.URL.String(), 301)
|
||||
}
|
||||
func GetRouter() *httprouter.Router {
|
||||
host := os.Getenv("LEMMY_DOMAIN")
|
||||
router := httprouter.New()
|
||||
if host == "" {
|
||||
router.ServeFiles("/:host/static/*filepath", http.Dir("public"))
|
||||
router.GET("/", GetRoot)
|
||||
router.POST("/", PostRoot)
|
||||
router.GET("/:host/", middleware(GetFrontpage))
|
||||
router.GET("/:host/search", middleware(Search))
|
||||
router.POST("/:host/search", middleware(UserOp))
|
||||
router.GET("/:host/inbox", middleware(Inbox))
|
||||
router.GET("/:host/login", middleware(GetLogin))
|
||||
router.POST("/:host/login", middleware(SignUpOrLogin))
|
||||
router.GET("/:host/settings", middleware(Settings))
|
||||
router.POST("/:host/settings", middleware(Settings))
|
||||
router.POST("/:host/", middleware(UserOp))
|
||||
router.GET("/:host/icon.jpg", middleware(GetIcon))
|
||||
router.GET("/:host/c/:community", middleware(GetFrontpage))
|
||||
router.POST("/:host/c/:community", middleware(UserOp))
|
||||
router.GET("/:host/c/:community/search", middleware(Search))
|
||||
router.GET("/:host/c/:community/edit", middleware(GetCreateCommunity))
|
||||
router.GET("/:host/post/:postid", middleware(GetPost))
|
||||
router.POST("/:host/post/:postid", middleware(UserOp))
|
||||
router.GET("/:host/comment/:commentid", middleware(GetComment))
|
||||
router.GET("/:host/comment/:commentid/:op", middleware(GetComment))
|
||||
router.POST("/:host/comment/:commentid", middleware(UserOp))
|
||||
router.GET("/:host/u/:username", middleware(GetUser))
|
||||
router.GET("/:host/u/:username/message", middleware(GetMessageForm))
|
||||
router.POST("/:host/u/:username/message", middleware(SendMessage))
|
||||
router.POST("/:host/u/:username", middleware(UserOp))
|
||||
router.GET("/:host/u/:username/search", middleware(Search))
|
||||
router.GET("/:host/create_post", middleware(GetCreatePost))
|
||||
router.POST("/:host/create_post", middleware(UserOp))
|
||||
router.GET("/:host/create_community", middleware(GetCreateCommunity))
|
||||
router.POST("/:host/create_community", middleware(UserOp))
|
||||
} else {
|
||||
router.ServeFiles("/_/static/*filepath", http.Dir("public"))
|
||||
router.GET("/", middleware(GetFrontpage))
|
||||
router.GET("/search", middleware(Search))
|
||||
router.POST("/search", middleware(UserOp))
|
||||
router.GET("/inbox", middleware(Inbox))
|
||||
router.GET("/login", middleware(GetLogin))
|
||||
router.POST("/login", middleware(SignUpOrLogin))
|
||||
router.GET("/settings", middleware(Settings))
|
||||
router.POST("/settings", middleware(Settings))
|
||||
router.POST("/", middleware(UserOp))
|
||||
router.GET("/icon.jpg", middleware(GetIcon))
|
||||
router.GET("/c/:community", middleware(GetFrontpage))
|
||||
router.POST("/c/:community", middleware(UserOp))
|
||||
router.GET("/c/:community/search", middleware(Search))
|
||||
router.GET("/c/:community/edit", middleware(GetCreateCommunity))
|
||||
router.GET("/post/:postid", middleware(GetPost))
|
||||
router.POST("/post/:postid", middleware(UserOp))
|
||||
router.GET("/comment/:commentid", middleware(GetComment))
|
||||
router.GET("/comment/:commentid/:op", middleware(GetComment))
|
||||
router.POST("/comment/:commentid", middleware(UserOp))
|
||||
router.GET("/u/:username", middleware(GetUser))
|
||||
router.GET("/u/:username/message", middleware(GetMessageForm))
|
||||
router.POST("/u/:username/message", middleware(SendMessage))
|
||||
router.POST("/u/:username", middleware(UserOp))
|
||||
router.GET("/u/:username/search", middleware(Search))
|
||||
router.GET("/create_post", middleware(GetCreatePost))
|
||||
router.POST("/create_post", middleware(UserOp))
|
||||
router.GET("/create_community", middleware(GetCreateCommunity))
|
||||
router.POST("/create_community", middleware(UserOp))
|
||||
}
|
||||
return router
|
||||
}
|
||||
|
|
42
state.go
42
state.go
|
@ -176,41 +176,6 @@ func (state *State) ParseQuery(RawQuery string) {
|
|||
}
|
||||
}
|
||||
|
||||
//func (state *State) Build() {
|
||||
// if state.Listing == "" {
|
||||
// state.Listing = "All"
|
||||
// }
|
||||
// if state.Op == "create_post" {
|
||||
// if state.CommunityName != "" {
|
||||
// state.GetCommunity()
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
// if state.CommentID > 0 {
|
||||
// state.GetComment()
|
||||
// state.GetPost()
|
||||
// state.GetCommunity()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if state.UserName != "" {
|
||||
// state.GetUser()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if state.PostID == 0 {
|
||||
// state.GetPosts()
|
||||
// } else {
|
||||
// state.GetPost()
|
||||
// state.GetComments()
|
||||
// }
|
||||
//
|
||||
// if state.CommunityName != "" {
|
||||
// state.GetCommunity()
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
func (state *State) LemmyError(domain string) error {
|
||||
var nodeInfo NodeInfo
|
||||
res, err := state.HTTPClient.Get("https://" + domain + "/nodeinfo/2.0.json")
|
||||
|
@ -255,6 +220,9 @@ func (state *State) GetSite() {
|
|||
}
|
||||
|
||||
func (state *State) GetComment(commentid int) {
|
||||
if state.Sort != "Hot" && state.Sort != "Top" && state.Sort != "Old" && state.Sort != "New" {
|
||||
state.Sort = "Hot"
|
||||
}
|
||||
state.CommentID = commentid
|
||||
cresp, err := state.Client.Comments(context.Background(), types.GetComments{
|
||||
ParentID: types.NewOptional(state.CommentID),
|
||||
|
@ -284,6 +252,9 @@ func (state *State) GetComment(commentid int) {
|
|||
}
|
||||
}
|
||||
func (state *State) GetComments() {
|
||||
if state.Sort != "Hot" && state.Sort != "Top" && state.Sort != "Old" && state.Sort != "New" {
|
||||
state.Sort = "Hot"
|
||||
}
|
||||
cresp, err := state.Client.Comments(context.Background(), types.GetComments{
|
||||
PostID: types.NewOptional(state.PostID),
|
||||
Sort: types.NewOptional(types.CommentSortType(state.Sort)),
|
||||
|
@ -293,6 +264,7 @@ func (state *State) GetComments() {
|
|||
})
|
||||
if err != nil {
|
||||
state.Status = http.StatusInternalServerError
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
state.CommentCount = len(cresp.Comments)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="comment{{if or (lt .P.Counts.Score -5) .P.Comment.Deleted }} hidden{{end}}" id="c{{.P.Comment.ID}}" onclick="commentClick(event)">
|
||||
<div class="meta">
|
||||
{{ if .State.Session }}
|
||||
<div class="score{{ if eq .P.MyVote.String "1"}} like{{ else if eq .P.MyVote.String "-1"}} dislike{{end}}">
|
||||
<form class="link-btn" method="POST">
|
||||
<div class="score">
|
||||
<form class="link-btn{{ if eq .P.MyVote.String "1"}} like{{ else if eq .P.MyVote.String "-1"}} dislike{{end}}" method="POST">
|
||||
<input type="submit" name="vote" value="▲">
|
||||
<div></div>
|
||||
{{ if .P.MyVote.IsValid}}
|
||||
|
@ -10,7 +10,7 @@
|
|||
{{ end}}
|
||||
<input type="hidden" name="op" value="vote_comment">
|
||||
<input type="hidden" name="commentid" value="{{.P.Comment.ID }}">
|
||||
<input type="submit" value="▼">
|
||||
<input type="submit" name="vote" value="▼">
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{ $c := .Community }}
|
||||
<form class="create" method="POST" enctype="multipart/form-data">
|
||||
<form class="create" method="POST" {{ if eq .Op "edit_community" }} action="./" {{ end }} enctype="multipart/form-data">
|
||||
<div>
|
||||
<label class="required" for="name">name</label>
|
||||
<input type="text" required name="name" id="name" value="{{ if $c }}{{ $c.CommunityView.Community.Name }}{{end}}">
|
||||
<input type="text" required name="name" id="name" {{ if $c }}value="{{ $c.CommunityView.Community.Name }}" disabled{{end}}>
|
||||
</div>
|
||||
<div>
|
||||
<label class="required" for="title">display name</label>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>{{ if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ .Host }}{{end}}</title>
|
||||
<title>{{ if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ host .Host }}{{end}}</title>
|
||||
<link rel="shortcut icon" href="/{{.Host}}/icon.jpg">
|
||||
<link rel="stylesheet" href="/_/static/style.css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
@ -17,7 +18,6 @@
|
|||
</noscript>
|
||||
|
||||
{{ template "nav.html" . -}}
|
||||
{{ template "sidebar.html" . }}
|
||||
{{ if or (contains .Sort "Top") (and (not .PostID) (not .User) (not .Community) (not .Activities) (eq .Op ""))}}
|
||||
{{ template "menu.html" . }}
|
||||
{{ end}}
|
||||
|
@ -31,11 +31,7 @@
|
|||
{{ template "post.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ if and .Session (not .Posts) (not .Community) (and .Listing "Subscribed") }}
|
||||
<h2>This is your home</h2>
|
||||
<p>When you find a community that you like, click the <span class="join">join</span> button</p>
|
||||
<p><a href="/{{.Host}}/search?searchtype=Communities">Click here</a> to find communities or <a href="/{{.Host}}?listingType=All&sort=TopDay">check out what's popular</a></p>
|
||||
{{ else if or (and (not .Op) (not .Activities) (not .Comments) (not .Posts) (not .Communities)) (and (not .Comments) .PostID) (and (not .Activities) (not .Query) .User) }}
|
||||
{{ if or (and (not .Op) (not .Activities) (not .Comments) (not .Posts) (not .Communities)) (and (not .Comments) .PostID) (and (not .Activities) (not .Query) .User) }}
|
||||
<div class="error">there doesn't seem to be anything here</div>
|
||||
{{ end }}
|
||||
|
||||
|
@ -46,7 +42,8 @@
|
|||
</div>
|
||||
{{ end }}
|
||||
|
||||
<script src="/_/static/utils.js"></script>
|
||||
{{ template "sidebar.html" . }}
|
||||
</main>
|
||||
<script src="/_/static/utils.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>{{ .Host }}: sign up or log in</title>
|
||||
<title>{{ host .Host }}: sign up or log in</title>
|
||||
<link rel="shortcut icon" href="/{{.Host}}/icon.jpg">
|
||||
<link rel="stylesheet" href="/_/static/style.css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
|
@ -23,7 +24,7 @@
|
|||
<img class="icon" src="{{ if .Site }}{{ .Site.SiteView.Site.Icon.String }}{{else}}/{{ .Host}}/icon.jpg{{end}}">
|
||||
</a>
|
||||
</div>
|
||||
<span class="title"><a class="title" href="/{{.Host}}">{{.Host}}</a> - sign up or login</span>
|
||||
<span class="title"><a class="title" href="/{{.Host}}">{{ host .Host}}</a> - sign up or login</span>
|
||||
</nav>
|
||||
{{ if .Alert }}
|
||||
<div class="alert">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>{{if and .Posts .PostID }}{{ (index .Posts 0).Post.Name}} : {{.CommunityName}}{{else if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ .Host }}{{end}}</title>
|
||||
<title>{{if and .Posts .PostID }}{{ (index .Posts 0).Post.Name}} : {{.CommunityName}}{{else if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ host .Host }}{{end}}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="shortcut icon" href="/{{.Host}}/icon.jpg">
|
||||
<link rel="stylesheet" href="/_/static/style.css">
|
||||
</head>
|
||||
|
@ -17,7 +18,6 @@
|
|||
</noscript>
|
||||
|
||||
{{ template "nav.html" . -}}
|
||||
{{ template "sidebar.html" . }}
|
||||
{{ if or (contains .Sort "Top") (and (not .PostID) (not .User) (not .Community) (not .Activities) (eq .Op ""))}}
|
||||
{{ template "menu.html" . }}
|
||||
{{ end}}
|
||||
|
@ -118,6 +118,7 @@
|
|||
{{ end }}
|
||||
|
||||
<script src="/_/static/utils.js"></script>
|
||||
{{ template "sidebar.html" . }}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
<div class="menu">
|
||||
listing:
|
||||
<a href="{{ .ListBy "All"}}" {{if eq .Listing "All"}}class="selected"{{end}}>all</a>
|
||||
<span>-</span>
|
||||
<a href="{{ .ListBy "Local"}}" {{if eq .Listing "Local"}}class="selected"{{end}}>local</a>
|
||||
{{ if .Session }}
|
||||
<span>-</span>
|
||||
<a href="{{ .ListBy "Subscribed"}}" {{if eq .Listing "Subscribed"}}class="selected"{{end}}>subscribed</a>
|
||||
{{ end }}
|
||||
{{ if contains .Sort "Top" }}
|
||||
links from past:
|
||||
<a {{ if eq .Sort "TopDay"}}class="selected"{{end}} href="{{ .SortBy "TopDay"}}">day</a>
|
||||
|
@ -11,12 +19,5 @@
|
|||
<span>-</span>
|
||||
<a {{ if eq .Sort "TopAll"}}class="selected"{{end}} href="{{ .SortBy "TopAll"}}">all time</a>
|
||||
{{ end }}
|
||||
<a href="{{ .ListBy "All"}}" {{if eq .Listing "All"}}class="selected"{{end}}>everywhere</a>
|
||||
<span>-</span>
|
||||
<a href="{{ .ListBy "Local"}}" {{if eq .Listing "Local"}}class="selected"{{end}}>local</a>
|
||||
{{ if .Session }}
|
||||
<span>-</span>
|
||||
<a href="{{ .ListBy "Subscribed"}}" {{if eq .Listing "Subscribed"}}class="selected"{{end}}>subscribed</a>
|
||||
{{ end }}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,21 @@
|
|||
{{ end }}
|
||||
<a href="/{{$host}}/search?searchtype=Communities" class="more">more »</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ if .Session }}
|
||||
<a href="/{{.Host}}/u/{{ .Session.UserName}}">{{ .Session.UserName }}</a>
|
||||
|
|
||||
<a href="/{{.Host}}/inbox" class="mailbox{{ if .UnreadCount }} orangered{{end}}">✉</a>
|
||||
|
|
||||
<a href="/{{.Host}}/settings">settings</a>
|
||||
|
|
||||
<form method="POST"><input type="submit" name="op" value="logout"></form>
|
||||
{{else}}
|
||||
Want to join? <a href="/{{.Host}}/login">Log in</a> or <a href="/{{.Host}}/login">sign up</a> in seconds
|
||||
|
|
||||
<a href="/{{.Host}}/settings">settings</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="spacer">
|
||||
<a href="/{{ .Host}}/">
|
||||
<img class="icon" src="{{ if .Site }}{{ .Site.SiteView.Site.Icon.String }}{{else}}/{{ .Host}}/icon.jpg{{end}}">
|
||||
|
@ -21,7 +36,7 @@
|
|||
{{ else if .User }}
|
||||
<a class="title" href="/{{ .Host}}/u/{{fullname .User.PersonView.Person}}">{{fullname .User.PersonView.Person}}</a>
|
||||
{{ else }}
|
||||
<a class="title" href="/{{.Host}}">{{.Host}}</a>
|
||||
<a class="title" href="/{{.Host}}">{{ host .Host}}</a>
|
||||
{{- end -}}
|
||||
{{- if eq .Op "create_post" "create_community" -}}
|
||||
<span>: submit</span>
|
||||
|
@ -49,15 +64,4 @@
|
|||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
<div class="right">
|
||||
{{ if .Session }}
|
||||
<a href="/{{.Host}}/u/{{ .Session.UserName}}">{{ .Session.UserName }}</a>
|
||||
|
|
||||
<a href="/{{.Host}}/inbox" class="mailbox{{ if .UnreadCount }} orangered{{end}}">✉</a>
|
||||
|
|
||||
<form method="POST"><input type="submit" name="op" value="logout"></form>
|
||||
{{else}}
|
||||
Want to join? <a href="/{{.Host}}/login">Log in</a> or <a href="/{{.Host}}/login">sign up</a> in seconds
|
||||
{{end}}
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{{ if not .State.XHR }}
|
||||
<div class="post {{if .Post.Deleted}}deleted{{end}}" onclick="postClick(event)">
|
||||
{{ if gt .Rank 0 }}
|
||||
{{ if gt .Rank 0 }}
|
||||
<div class="rank"> {{ .Rank }} </div>
|
||||
{{ end }}
|
||||
<div class="score">
|
||||
{{ end }}
|
||||
<div class="score {{ if lt .Rank 1 }}squish{{end}}{{ if eq .MyVote.String "1" }} like{{else if eq .MyVote.String "-1"}} dislike{{end}}">
|
||||
{{ if .State.Session }}
|
||||
<form class="link-btn" method="POST">
|
||||
<form class="link-btn {{ if lt .Rank 1 }}squish{{end}}{{ if eq .MyVote.String "1" }} like{{else if eq .MyVote.String "-1"}} dislike{{end}}" method="POST" onsubmit="formSubmit(event)">
|
||||
<input type="submit" name="vote" value="▲">
|
||||
{{ if .MyVote.IsValid}}
|
||||
<input type="hidden" name="undo" value="{{.MyVote.String}}">
|
||||
|
@ -12,17 +14,18 @@
|
|||
<input type="hidden" name="op" value="vote_post">
|
||||
<input type="hidden" name="postid" value="{{.Post.ID }}">
|
||||
<div>{{ .Counts.Score }}</div>
|
||||
<input type="submit" value="▼">
|
||||
<input type="submit" name="vote" value="▼">
|
||||
</form>
|
||||
{{ else }}
|
||||
<div style="margin-top: 19px;">{{ .Counts.Score }}</div>
|
||||
{{ end }}
|
||||
{{ if not .State.XHR}}
|
||||
</div>
|
||||
<div class="thumb" style="background-image: url({{if .Post.ThumbnailURL.IsValid}}{{.Post.ThumbnailURL.String}}?format=jpg&thumbnail=96{{else if .Post.URL.IsValid}}/_/static/link.png{{else}}/_/static/text.png{{end}})"></div>
|
||||
<div class="entry">
|
||||
<div class="title">
|
||||
<a href="{{ if .Post.URL.IsValid }}{{ .Post.URL }}{{ else }}/{{ .State.Host }}/post/{{ .Post.ID }}{{ end }}">{{ .Post.Name }}</a>
|
||||
({{ host . }})
|
||||
({{ domain . }})
|
||||
</div>
|
||||
{{ if or (and .Post.Body.IsValid (ne .Post.Body.String "")) (isImage .Post.URL.String) }}
|
||||
<div class="expando-button {{ if eq .Rank 0}}open{{ end }}"></div>
|
||||
|
@ -66,3 +69,4 @@
|
|||
<div></div>
|
||||
<div class="clearleft"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<title>mlmym</title>
|
||||
<link rel="shortcut icon" href="/{{.Host}}/icon.jpg">
|
||||
<link rel="stylesheet" href="/_/static/style.css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
{{ if and .Session (isMod .Community .Session.UserName) }}
|
||||
MODERATOR TOOLS
|
||||
<div class="moderators">
|
||||
<a href="/{{.Host}}/c/{{.CommunityName}}?edit">community settings</a>
|
||||
<a href="/{{.Host}}/c/{{.CommunityName}}/edit">community settings</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .Community.Moderators }}
|
||||
|
|
Loading…
Reference in a new issue