diff options
author | FChannel <> | 2022-04-24 00:46:49 -0700 |
---|---|---|
committer | FChannel <> | 2022-06-19 12:53:29 -0700 |
commit | 3db517715bef6a53225c5c3c06e8fc5fd0bf71e3 (patch) | |
tree | 9aa7fbcb12f2ec8d0e4e66cd85ace058e38dd32d | |
parent | 9718d34a757b66917747c1c4acfb9b35d154625b (diff) |
basic pass over view posts, post, catalog and manage page connections
-rw-r--r-- | config/config.go | 2 | ||||
-rw-r--r-- | db/actor.go | 16 | ||||
-rw-r--r-- | db/database.go | 7 | ||||
-rw-r--r-- | db/redis.go | 64 | ||||
-rw-r--r-- | main.go | 54 | ||||
-rw-r--r-- | routes/404.go | 4 | ||||
-rw-r--r-- | routes/admin.go | 50 | ||||
-rw-r--r-- | routes/index.go | 7 | ||||
-rw-r--r-- | routes/outbox.go | 21 | ||||
-rw-r--r-- | routes/post.go | 8 | ||||
-rw-r--r-- | util/accept.go (renamed from accept.go) | 4 | ||||
-rw-r--r-- | util/util.go | 2 | ||||
-rw-r--r-- | views/admin.html | 78 | ||||
-rw-r--r-- | views/catalog.html | 109 | ||||
-rw-r--r-- | views/index.html | 3 | ||||
-rw-r--r-- | views/layouts/main.html | 1 | ||||
-rw-r--r-- | webfinger/webfinger.go | 1 |
17 files changed, 361 insertions, 70 deletions
diff --git a/config/config.go b/config/config.go index d9e5a94..93531b8 100644 --- a/config/config.go +++ b/config/config.go @@ -10,7 +10,7 @@ import ( var Port = ":" + GetConfigValue("instanceport", "3000") var TP = GetConfigValue("instancetp", "") -var Domain = GetConfigValue("instance", "") +var Domain = TP + "" + GetConfigValue("instance", "") var InstanceName = GetConfigValue("instancename", "") var InstanceSummary = GetConfigValue("instancesummary", "") var SiteEmail = GetConfigValue("emailaddress", "") //contact@fchan.xyz diff --git a/db/actor.go b/db/actor.go index 51c8f41..7e36090 100644 --- a/db/actor.go +++ b/db/actor.go @@ -1,11 +1,13 @@ package db import ( + "encoding/json" "fmt" "regexp" "strings" "github.com/FChannel0/FChannel-Server/activitypub" + "github.com/gofiber/fiber/v2" ) func GetActorFromPath(location string, prefix string) (activitypub.Actor, error) { @@ -49,3 +51,17 @@ func GetActorByName(name string) activitypub.Actor { return actor } + +func GetActorInfo(ctx *fiber.Ctx, id string) error { + actor, err := GetActorFromDB(id) + if err != nil { + return err + } + + enc, _ := json.MarshalIndent(actor, "", "\t") + ctx.Response().Header.Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") + + _, err = ctx.Write(enc) + + return err +} diff --git a/db/database.go b/db/database.go index 0b44404..db7e715 100644 --- a/db/database.go +++ b/db/database.go @@ -858,6 +858,7 @@ func GetObjectFromDBCatalog(id string) (activitypub.Collection, error) { query := `select x.id, x.name, x.content, x.type, x.published, x.updated, x.attributedto, x.attachment, x.preview, x.actor, x.tripcode, x.sensitive from (select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note') as x order by x.updated desc limit 165` rows, err := db.Query(query, id) + if err != nil { return nColl, err } @@ -880,6 +881,7 @@ func GetObjectFromDBCatalog(id string) (activitypub.Collection, error) { post.Replies = &replies post.Replies.TotalItems, post.Replies.TotalImgs, err = GetObjectRepliesCount(post) + if err != nil { return nColl, err } @@ -1229,8 +1231,9 @@ func GetObjectRepliesCount(parent activitypub.ObjectBase) (int, int, error) { defer rows.Close() - rows.Next() - err = rows.Scan(&countId, &countImg) + for rows.Next() { + err = rows.Scan(&countId, &countImg) + } return countId, countImg, err } diff --git a/db/redis.go b/db/redis.go index 873ca27..1650b4f 100644 --- a/db/redis.go +++ b/db/redis.go @@ -3,10 +3,11 @@ package db import ( "bufio" "fmt" - "net/http" "os" + "strings" "github.com/FChannel0/FChannel-Server/config" + "github.com/gofiber/fiber/v2" "github.com/gomodule/redigo/redis" ) @@ -22,6 +23,50 @@ func CloseCache() error { return Cache.Close() } +func GetClientKey() (string, error) { + file, err := os.Open("clientkey") + if err != nil { + return "", err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + var line string + for scanner.Scan() { + line = fmt.Sprintf("%s", scanner.Text()) + } + + return line, nil +} + +func GetPasswordFromSession(c *fiber.Ctx) (string, string) { + + cookie := c.Cookies("session_token") + + if cookie == "" { + return "", "" + } + + sessionToken := cookie + + response, err := Cache.Do("GET", sessionToken) + + if err != nil { + return "", "" + } + + token := fmt.Sprintf("%s", response) + + parts := strings.Split(token, "|") + + if len(parts) > 1 { + return parts[0], parts[1] + } + + return "", "" +} + +/* TODO: Convert to fiber ctx func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { c, err := r.Cookie("session_token") @@ -49,20 +94,5 @@ func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { } return response, nil -} - -func GetClientKey() (string, error) { - file, err := os.Open("clientkey") - if err != nil { - return "", err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - var line string - for scanner.Scan() { - line = fmt.Sprintf("%s", scanner.Text()) } - - return line, nil -} +*/ @@ -105,6 +105,8 @@ func main() { TemplateFunctions(template) + template.Reload(true) + app := fiber.New(fiber.Config{ AppName: "FChannel", Views: template, @@ -128,25 +130,6 @@ func main() { app.Get("/followers", routes.Followers) /* - Board actor - */ - - app.Get("/:actor", routes.OutboxGet) - app.Get("/:actor/catalog", routes.CatalogGet) - - app.Get("/:actor/:post", routes.PostGet) - app.Get("/post", routes.ActorPost) - - app.Get("/:actor/inbox", routes.ActorInbox) - app.Get("/:actor/outbox", routes.ActorOutbox) - - app.Get("/:actor/following", routes.ActorFollowing) - app.Get("/:actor/followers", routes.ActorFollowers) - - app.Get("/:actor/reported", routes.ActorReported) - app.Get("/:actor/archive", routes.ActorArchive) - - /* Admin routes */ @@ -238,7 +221,26 @@ func main() { return c.SendStatus(404) }) - // 404 handler + /* + Board actor + */ + + app.Get("/:actor", routes.OutboxGet) + app.Get("/:actor/catalog", routes.CatalogGet) + + app.Get("/:actor/:post", routes.PostGet) + app.Get("/post", routes.ActorPost) + + app.Get("/:actor/inbox", routes.ActorInbox) + app.Get("/:actor/outbox", routes.ActorOutbox) + + app.Get("/:actor/following", routes.ActorFollowing) + app.Get("/:actor/followers", routes.ActorFollowers) + + app.Get("/:actor/reported", routes.ActorReported) + app.Get("/:actor/archive", routes.ActorArchive) + + //404 handler app.Use(routes.NotFound) fmt.Println("Mod key: " + config.Key) @@ -293,18 +295,6 @@ func CreateNewActor(board string, prefName string, summary string, authReq []str return actor } -func GetActorInfo(w http.ResponseWriter, id string) error { - actor, err := db.GetActorFromDB(id) - if err != nil { - return err - } - - enc, _ := json.MarshalIndent(actor, "", "\t") - w.Header().Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") - _, err = w.Write(enc) - return err -} - func GetActorPost(w http.ResponseWriter, path string) error { collection, err := db.GetCollectionFromPath(config.Domain + "" + path) if err != nil { diff --git a/routes/404.go b/routes/404.go index 64ea167..94b96e8 100644 --- a/routes/404.go +++ b/routes/404.go @@ -1,6 +1,8 @@ package routes -import "github.com/gofiber/fiber/v2" +import ( + "github.com/gofiber/fiber/v2" +) func NotFound(c *fiber.Ctx) error { return c.Status(404).Render("404", fiber.Map{}, "layouts/main") diff --git a/routes/admin.go b/routes/admin.go index 068dda3..528e40c 100644 --- a/routes/admin.go +++ b/routes/admin.go @@ -1,6 +1,11 @@ package routes -import "github.com/gofiber/fiber/v2" +import ( + "github.com/FChannel0/FChannel-Server/config" + "github.com/FChannel0/FChannel-Server/db" + "github.com/FChannel0/FChannel-Server/webfinger" + "github.com/gofiber/fiber/v2" +) func AdminVerify(c *fiber.Ctx) error { // STUB @@ -14,10 +19,47 @@ func AdminAuth(c *fiber.Ctx) error { return c.SendString("admin auth") } -func AdminIndex(c *fiber.Ctx) error { - // STUB +func AdminIndex(ctx *fiber.Ctx) error { + actor, err := webfinger.GetActor(config.Domain) + + if err != nil { + return err + } + + follow, _ := webfinger.GetActorCollection(actor.Following) + follower, _ := webfinger.GetActorCollection(actor.Followers) + + var following []string + var followers []string + + for _, e := range follow.Items { + following = append(following, e.Id) + } + + for _, e := range follower.Items { + followers = append(followers, e.Id) + } + + var adminData AdminPage + adminData.Following = following + adminData.Followers = followers + adminData.Actor = actor.Id + adminData.Key = config.Key + adminData.Domain = config.Domain + adminData.Board.ModCred, _ = db.GetPasswordFromSession(ctx) + adminData.Title = actor.Name + " Admin page" + + adminData.Boards = db.Boards + + adminData.Board.Post.Actor = actor.Id + + adminData.PostBlacklist, _ = db.GetRegexBlacklistDB() + + adminData.Themes = &config.Themes - return c.SendString("admin index") + return ctx.Render("admin", fiber.Map{ + "page": adminData, + }) } func AdminAddBoard(c *fiber.Ctx) error { diff --git a/routes/index.go b/routes/index.go index 3599455..5ff2bd4 100644 --- a/routes/index.go +++ b/routes/index.go @@ -3,6 +3,7 @@ package routes import ( "github.com/FChannel0/FChannel-Server/config" "github.com/FChannel0/FChannel-Server/db" + "github.com/FChannel0/FChannel-Server/util" "github.com/FChannel0/FChannel-Server/webfinger" "github.com/gofiber/fiber/v2" ) @@ -13,6 +14,12 @@ func Index(ctx *fiber.Ctx) error { return err } + // this is a activitpub json request return json instead of html page + if util.AcceptActivity(ctx.Get("Accept")) { + db.GetActorInfo(ctx, actor.Id) + return nil + } + var data PageData data.Title = "Welcome to " + actor.PreferredUsername data.PreferredUsername = actor.PreferredUsername diff --git a/routes/outbox.go b/routes/outbox.go index b00f946..1277011 100644 --- a/routes/outbox.go +++ b/routes/outbox.go @@ -16,6 +16,14 @@ func Outbox(ctx *fiber.Ctx) error { } func OutboxGet(ctx *fiber.Ctx) error { + + actor := db.GetActorByName(ctx.Params("actor")) + + if util.AcceptActivity(ctx.Get("Accept")) { + db.GetActorInfo(ctx, actor.Id) + return nil + } + collection, valid, err := wantToServePage(ctx.Params("actor"), 0) if err != nil { return err @@ -24,12 +32,13 @@ func OutboxGet(ctx *fiber.Ctx) error { return ctx.SendString("404") } - actor := collection.Actor - + var page int postNum := ctx.Query("page") - page, err := strconv.Atoi(postNum) - if err != nil { - return err + if postNum != "" { + page, err = strconv.Atoi(postNum) + if err != nil { + return err + } } var returnData PageData @@ -39,7 +48,7 @@ func OutboxGet(ctx *fiber.Ctx) error { returnData.Board.Summary = actor.Summary returnData.Board.InReplyTo = "" returnData.Board.To = actor.Outbox - returnData.Board.Actor = *actor + returnData.Board.Actor = actor returnData.Board.ModCred, _ = getPassword(ctx) returnData.Board.Domain = config.Domain returnData.Board.Restricted = actor.Restricted diff --git a/routes/post.go b/routes/post.go index 24dbbc3..e074f67 100644 --- a/routes/post.go +++ b/routes/post.go @@ -1,13 +1,13 @@ package routes import ( - "regexp" - + "fmt" "github.com/FChannel0/FChannel-Server/config" "github.com/FChannel0/FChannel-Server/db" "github.com/FChannel0/FChannel-Server/util" "github.com/FChannel0/FChannel-Server/webfinger" "github.com/gofiber/fiber/v2" + "regexp" ) func PostGet(ctx *fiber.Ctx) error { @@ -112,6 +112,8 @@ func CatalogGet(ctx *fiber.Ctx) error { collection, err := db.GetObjectFromDBCatalog(actor.Id) + fmt.Println(err) + // TODO: implement this in template functions // "showArchive": func() bool { // col, err := db.GetActorCollectionDBTypeLimit(collection.Actor.Id, "Archive", 1) @@ -162,7 +164,7 @@ func CatalogGet(ctx *fiber.Ctx) error { returnData.Themes = &config.Themes returnData.ThemeCookie = getThemeCookie(ctx) - return ctx.Render("ncatalog", fiber.Map{ + return ctx.Render("catalog", fiber.Map{ "page": returnData, }, "layouts/main") } diff --git a/accept.go b/util/accept.go index 6a15857..2765c32 100644 --- a/accept.go +++ b/util/accept.go @@ -1,4 +1,4 @@ -package main +package util import ( "regexp" @@ -8,7 +8,7 @@ import ( // False positive for application/ld+ld, application/activity+ld, application/json+json var activityRegexp = regexp.MustCompile("application\\/(ld|json|activity)((\\+(ld|json))|$)") -func acceptActivity(header string) bool { +func AcceptActivity(header string) bool { accept := false if strings.Contains(header, ";") { split := strings.Split(header, ";") diff --git a/util/util.go b/util/util.go index a56e871..1feb53a 100644 --- a/util/util.go +++ b/util/util.go @@ -29,7 +29,7 @@ func GetActorInstance(path string) (string, string) { } } - re = regexp.MustCompile(`(https?://)(www)?([\w\d-_.:]+)(/|\s+|\r|\r\n)?$`) + re = regexp.MustCompile(`(https?://)?(www)?([\w\d-_.:]+)(/|\s+|\r|\r\n)?$`) mainActor := re.MatchString(path) if mainActor { match := re.FindStringSubmatch(path) diff --git a/views/admin.html b/views/admin.html new file mode 100644 index 0000000..191444b --- /dev/null +++ b/views/admin.html @@ -0,0 +1,78 @@ +<div style="margin: 0 auto; width: 400px;"> + <h3>Add Board</h3> + <form id="new-post" action="/{{ .page.Key }}/addboard" method="post" enctype="application/x-www-form-urlencoded"> + <label>Name:</label><br> + <input type="text" name="name" placeholder="g" required><br> + <label>Prefered Name:</label><br> + <input type="text" name="prefname" placeholder="Technology" required><input type="submit" value="Add"><br> + <label>Summary:</label><br> + <textarea name="summary" rows="8" cols="50"></textarea><br> + <label>Restricted (i.e SFW):</label><br> + <select name="restricted"> + <option value="True">True</option> + <option value="False">False</option> + </select> + </form> + <ul style="display: inline-block; padding: 0;"> + <li style="display: inline-block;">[<a href="#news">Create News</a>]</li> + <li style="display: inline-block;">[<a href="#regex">Post Blacklist</a>]</li> + <!-- <li style="display: inline-block;"><a href="javascript:show('followers')">Followers</a></li> --> + <!-- <li style="display: inline-block;"><a href="#reported">Reported</a></li> --> + </ul> +</div> + +<div id="following" class="box2" style="margin-bottom: 25px; padding: 12px;"> + <h4 style="margin: 0; margin-bottom: 5px;">Subscribed</h4> + <form id="follow-form" action="/{{ .page.Key }}/follow" method="post" enctype="application/x-www-form-urlencoded"> + <input id="follow" name="follow" style="margin-bottom: 12px;" placeholder="http://localhost:3000/g"></input><input type="submit" value="Subscribe"><br> + <input type="hidden" name="actor" value="{{ .page.Actor }}"> + </form> + <ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;"> + {{ $actor := .page.Actor }} + {{ $key := .page.Key }} + {{ range .page.Following }} + <li>[<a href="/{{ $key }}/follow?follow={{ . }}&actor={{ $actor }}">Unfollow</a>]<a href="{{ . }}">{{ . }}</a></li> + {{ end }} + </ul> +</div> + +<div id="followers" class="box2" style="margin-bottom: 25px; padding: 12px; display:none;"> + <h4 style="margin: 0; margin-bottom: 5px;">Followers</h4> + <ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;"> + {{ range .page.Followers }} + <li><a href="http://localhost:3000/g">{{ . }}</a></li> + {{ end }} + </ul> +</div> + +<div class="box2" style="margin-bottom: 25px; padding: 12px;"> + <h3>Create News</h3> + <form id="news" action="/{{ .page.Key }}/postnews" method="post" enctype="application/x-www-form-urlencoded"> + <label>Title:</label><br> + <input type="text" name="title" placeholder="New Board" required><input type="submit" value="Post"><br> + <label>Content:</label><br> + <textarea name="summary" rows="8" cols="50"></textarea><br> + </form> +</div> + +<div id="regex" class="box2" style="margin-bottom: 25px; padding: 12px;"> + <h3>Regex Post Blacklist</h3> + <form id="blacklist" action="/blacklist" method="post" enctype="application/x-www-form-urlencoded"> + <label>Regex:</label><br> + <input type="text" name="regex" placeholder="(?i)(?s)(.+)?stuff?(.+)to(.+)?block(.+)?https?://(.+)?" size="38" required><input style="margin-left: 5px;" type="submit" value="Post"><br> + <label>Test Case:</label><br> + <textarea name="testCase" rows="8" cols="50" placeholder="enter a test case to block, if it passes the regex will be added to the blacklist. (?i) for case insesitive (?s) to span multiple lines"></textarea><br> + </form> + {{ if .page.PostBlacklist }} + <ul style="display: inline-block; padding: 0; margin: 0; margin-top: 25px; list-style-type: none;"> + {{ range .page.PostBlacklist }} + <li>{{ .Regex }} [<a href="/blacklist?remove={{ .Id }}">remove</a>]</li> + {{ end }} + </ul> + {{ end }} + +<!-- <div id="reported" class="popup-box" style="margin-bottom: 25px; padding: 12px;"> --> +<!-- <h4 style="margin: 0; margin-bottom: 5px;">Reported</h4> --> +<!-- <ul style="display: inline-block; padding: 0; margin: 0; list-style-type: none;"> --> +<!-- </ul> --> +<!-- </div> --> diff --git a/views/catalog.html b/views/catalog.html new file mode 100644 index 0000000..c70471e --- /dev/null +++ b/views/catalog.html @@ -0,0 +1,109 @@ +{{ define "header" }} +<title>/{{ .page.Board.Name }}/ - catalog</title> +<meta name="description" content="{{ .page.Board.Summary }}"> +<meta property="og:url" content="{{ .page.Board.Actor.Id }}"> +<meta property="og:site_name" content="{{ .page.Instance.PreferredUsername }}" /> + +<meta property="og:title" content="{{ .page.Title }}"> +<meta property="og:description" content="{{ .page.Board.Summary }}"> + +<meta name="twitter:title" content="{{ .page.Title }}"> +<meta name="twitter:description" content="{{ .page.Board.Summary }}"> +<meta name="twitter:card" content="summary_large_image"> + +<script src="/static/js/posts.js"></script> +{{ end }} + +{{ $board := .page.Board }} +<hr> + +<ul id="navlinks"> + <li>[<a href="/{{ $board.Name }}/">Return</a>]</li> + <!-- TODO: Implement showArchive --> + <!-- \{\{ if showArchive }} --> + <!-- <li>[<a href="/{{ $board.Name }}/archive">Archive</a>]</li> --> + <!-- \{\{ end }} --> + <li>[<a href="#bottom">Bottom</a>]</li> + <li>[<a href="javascript:location.reload()">Refresh</a>]</li> +</ul> + +<hr> + +<div style="padding: 10px; text-align: center;"> + {{ range .page.Posts }} + <div style="overflow: hidden; vertical-align: top; padding-right: 24px; padding-bottom: 24px; display: inline-block; width: 180px; max-height: 320px; margin-bottom: 10px;"> + {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + [<a href="/delete?id={{ .Id }}&board={{ $board.Actor.Name }}">Delete Post</a>] + {{ end }} + {{ if .Attachment }} + {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + [<a href="/deleteattach?id={{ .Id }}&board={{ $board.Actor.Name }}">Delete Attachment</a>] + [<a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">Mark Sensitive</a>] + {{ end }} + <div id="hide-{{ .Id }}" style="display: none;">[Hide]</div> + <div id="sensitive-{{ .Id }}" style="display: none;"> + <div style="position: relative; text-align: center;"> + <img id="sensitive-img-{{ .Id }}" style="float: left; margin-right: 10px; margin-bottom: 10px; max-width: 180px; max-height: 180px;" src="/static/sensitive.png"> + <div id="sensitive-text-{{ .Id }}" style="width: 170px; position: absolute; margin-top: 75px; padding: 5px; background-color: black; color: white; cursor: default; ">NSFW Content</div> + </div> + </div> + <a id="{{ .Id }}-anchor" href="/{{ $board.Name }}/{{ shortURL $board.Actor.Outbox .Id}}"> + <div id="media-{{ .Id }}" style="width:180px;"> {{ parseAttachment . true }}</div> + </a> + <script> + media = document.getElementById("media-{{ .Id }}") + + if(({{ .Sensitive }} && {{ $board.Actor.Restricted }}) || ({{ isOnion .Id }} && !{{ isOnion $board.Domain }})){ + sensitive = document.getElementById("sensitive-{{ .Id }}") + hide = document.getElementById("hide-{{ .Id }}") + sensitive.onclick = function(){document.getElementById("media-{{ .Id }}").style="display: block;"; document.getElementById("sensitive-{{ .Id }}").style="display: none;"; document.getElementById("hide-{{ .Id }}").style="display: block; cursor: pointer;"} + hide.onclick = function(){document.getElementById("media-{{ .Id }}").style="display: none;"; document.getElementById("sensitive-{{ .Id }}").style="display: block;"; document.getElementById("hide-{{ .Id }}").style="display: none;"} + sensitive.style = "display: block" + media.style = "display: none;" + } + + if({{ isOnion .Id }} && !{{ isOnion $board.Domain }}) { + sensitive = document.getElementById("sensitive-{{ .Id }}") + document.getElementById("sensitive-img-{{ .Id }}").src = "/static/onion.png" + document.getElementById("sensitive-text-{{ .Id }}").innerText = "Tor Instance" + hide = document.getElementById("hide-{{ .Id }}") + sensitive.onclick = function(){document.getElementById("media-{{ .Id }}").style="display: block;"; document.getElementById("sensitive-{{ .Id }}").style="display: none;"; document.getElementById("hide-{{ .Id }}").style="display: block; cursor: pointer;"} + hide.onclick = function(){document.getElementById("media-{{ .Id }}").style="display: none;"; document.getElementById("sensitive-{{ .Id }}").style="display: block;"; document.getElementById("hide-{{ .Id }}").style="display: none;"} + sensitive.style = "display: block" + media.style = "display: none;" + } + </script> + {{ end }} + <a style="color: unset;" id="{{ .Id }}-link" href="/{{ $board.Name }}/{{ shortURL $board.Actor.Outbox .Id }}"> + <div style="display: block;"> + {{ $replies := .Replies }} + {{ if $replies }} + <span>R: {{ $replies.TotalItems }}{{ if $replies.TotalImgs }}/ A: {{ $replies.TotalImgs }}{{ end }}</span> + {{ end }} + {{ if .Name }} + <br> + <span class="subject"><b>{{ .Name }}</b></span> + {{ end }} + + {{ if .Content }} + <br> + <span>{{.Content}}</span> + {{ end }} + </div> + </a> + </div> + {{ end }} +</div> +<hr> + +<ul id="navlinks"> + <li>[<a href="/{{ $board.Name }}/">Return</a>]</li> + <!-- TODO: Implement showArchive --> + <!-- \{\{ if showArchive }} --> + <!-- <li>[<a href="/{{ $board.Name }}/archive">Archive</a>]</li> --> + <!-- \{\{ end }} --> + <li>[<a href="#top">Top</a>]</li> + <li>[<a href="javascript:location.reload()">Refresh</a>]</li> +</ul> + +<hr> diff --git a/views/index.html b/views/index.html index f426d5d..e928ace 100644 --- a/views/index.html +++ b/views/index.html @@ -1,3 +1,6 @@ +{{ define "header" }} +<title>{{ .page.Title }}</title> +{{ end }} <div style="text-align: center; max-width: 800px; margin: 0 auto;"> <h1>{{ .page.Title }}</h1> <p style="text-align: justify">{{ .page.PreferredUsername }} is a federated image board based on <a href="https://activitypub.rocks/">ActivityPub</a>. The current version of the code running on the server is still a work-in-progress product, expect a bumpy ride for the time being. Get the server code here: <a href="https://github.com/FChannel0">https://github.com/FChannel0</a>.</p> diff --git a/views/layouts/main.html b/views/layouts/main.html index 4cd48f9..41e3412 100644 --- a/views/layouts/main.html +++ b/views/layouts/main.html @@ -45,6 +45,5 @@ {{ template "partials/footer" .page }} <script src="/static/js/themes.js"></script> - {{ template "scripts" .page }} </body> </html> diff --git a/webfinger/webfinger.go b/webfinger/webfinger.go index 9e8d67d..d937ae4 100644 --- a/webfinger/webfinger.go +++ b/webfinger/webfinger.go @@ -43,6 +43,7 @@ func GetActor(id string) (activitypub.Actor, error) { if err != nil { return respActor, err } + req.Header.Set("Accept", config.ActivityStreams) resp, err := util.RouteProxy(req) |