top page now displays published posts

This commit is contained in:
2026-01-23 22:58:13 -07:00
parent b6de9bd9ec
commit fa04f67ab8
4 changed files with 120 additions and 22 deletions
+41
View File
@@ -112,6 +112,28 @@ func (c *Conference) Hosts(ctx context.Context) ([]*User, error) {
return rc, nil
}
// ContainedBy returns the communities that contain this conference.
func (c *Conference) ContainedBy(ctx context.Context) ([]*Community, error) {
rs, err := amdb.QueryContext(ctx, "SELECT commid FROM commtoconf WHERE confid = ?", c.ConfId)
if err != nil {
return nil, err
}
rc := make([]*Community, 0, 1)
for rs.Next() {
var cid int32
if err = rs.Scan(&cid); err != nil {
return nil, err
}
comm, err := AmGetCommunity(ctx, cid)
if err == nil {
rc = append(rc, comm)
} else {
return nil, err
}
}
return rc, nil
}
// Hosts returns the list of users that host this conference, quietly.
func (c *Conference) HostsQ(ctx context.Context) []*User {
rc, _ := c.Hosts(ctx)
@@ -176,6 +198,25 @@ func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings
return &(dbdata[0]), nil
}
// Link returns a link string to this conference.
func (c *Conference) Link(ctx context.Context, scope string) (string, error) {
aliases, err := c.Aliases(ctx)
if err != nil {
return "", err
}
if scope == "community" {
return fmt.Sprintf("%s.", aliases[0]), nil
}
if scope == "global" {
comms, err := c.ContainedBy(ctx)
if err == nil {
return fmt.Sprintf("%s!%s", comms[0].Alias, aliases[0]), nil
}
return "", err
}
return "", errors.New("invalid scope")
}
// DefaultPseud returns the default pseud for a user in the conference.
func (c *Conference) DefaultPseud(ctx context.Context, u *User) (string, error) {
settings, err := c.Settings(ctx, u)
+23
View File
@@ -35,6 +35,29 @@ type Topic struct {
Name string `db:"name"` // topic name
}
// Link returns a link string to this topic.
func (t *Topic) Link(ctx context.Context, scope string) (string, error) {
if scope == "conference" {
return fmt.Sprintf("%d.", t.Number), nil
}
if scope == "community" || scope == "global" {
conf, err := AmGetConference(ctx, t.ConfId)
if err == nil {
var plink string
plink, err = conf.Link(ctx, scope)
if err == nil {
if strings.HasSuffix(plink, ".") {
return fmt.Sprintf("%s%d", plink, t.Number), nil
} else {
return fmt.Sprintf("%s.%d", plink, t.Number), nil
}
}
}
return "", err
}
return "", errors.New("invalid scope")
}
// GetPost returns a post in the topic by number.
func (t *Topic) GetPost(ctx context.Context, num int32) (*PostHeader, error) {
if num > t.TopMessage {
+32 -2
View File
@@ -12,9 +12,11 @@ package main
import (
"fmt"
"net/http"
"reflect"
"git.erbosoft.com/amy/amsterdam/database"
"git.erbosoft.com/amy/amsterdam/ui"
"github.com/CloudyKit/jet/v6"
)
// RenderedSideboxItem is an item for display inside a rendered sidebox.
@@ -164,6 +166,22 @@ func buildRenderedSidebox(ctxt ui.AmContext, uid int32, out *RenderedSidebox, in
}
}
// templateGetTopic returns the pointer to the topic.
func templateGetTopic(args jet.Arguments) reflect.Value {
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
topic, _ := database.AmGetTopic(ctxt.Ctx(), post.TopicId)
return reflect.ValueOf(topic)
}
// templateTopicLink returns the link string for the given topic.
func templateTopicLink(args jet.Arguments) reflect.Value {
topic := args.Get(0).Convert(reflect.TypeFor[*database.Topic]()).Interface().(*database.Topic)
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
link, _ := topic.Link(ctxt.Ctx(), "global")
return reflect.ValueOf(link)
}
/* TopPage renders the "top level" Amsterdam page (the "home page").
* Parameters:
* ctxt - The AmContext for the request.
@@ -176,18 +194,30 @@ func TopPage(ctxt ui.AmContext) (string, any, error) {
// Set the page title.
ctxt.VarMap().Set("amsterdam_pageTitle", "My Front Page")
// Retrieve the published posts.
hdrs, err := database.AmGetPublishedPosts(ctxt.Ctx())
if err != nil {
return ui.ErrorPage(ctxt, err)
}
ctxt.VarMap().Set("posts", hdrs)
ctxt.VarMap().SetFunc("post_getText", templatePostText)
ctxt.VarMap().SetFunc("post_getUserName", templateExtractUserName)
ctxt.VarMap().SetFunc("post_topic", templateGetTopic)
ctxt.VarMap().SetFunc("post_topicLink", templateTopicLink)
// Retrieve the sideboxes and create the data to be presented.
uid := ctxt.CurrentUserId()
sboxes, err := database.AmGetSideboxes(ctxt.Ctx(), uid)
if err != nil {
return "string", "Unable to retrieve sideboxes", err
return ui.ErrorPage(ctxt, err)
}
rc := make([]RenderedSidebox, len(sboxes))
for i, sb := range sboxes {
err = buildRenderedSidebox(ctxt, uid, &(rc[i]), sb)
if err != nil {
return "string", "Unable to render sideboxes", err
return ui.ErrorPage(ctxt, err)
}
}
ctxt.VarMap().Set("sideboxes", rc)
+18 -14
View File
@@ -20,30 +20,34 @@
</div>
{{ end }}
<!-- Venice Currents Section -->
<!-- Front Page Posts Section -->
<div>
<h2 class="text-blue-800 text-4xl font-bold mb-2">Venice Currents</h2>
<h2 class="text-blue-800 text-4xl font-bold mb-2">Latest from the Conferences</h2>
<hr class="border-2 border-gray-400 w-4/5 mb-4">
{{ user := "" }}
{{ text := "" }}
{{ topic := nil }}
{{ link := "" }}
{{ range i, p := posts }}
{{ user = post_getUserName(p, .) }}
{{ text = post_getText(p, .) }}
{{ topic = post_topic(p, .) }}
{{ link = post_topicLink(topic, .) }}
<div class="text-black text-sm">
<div class="mb-2">
<strong>Amy, formerly Eric</strong>
<strong>{{ p.Pseud | raw }}</strong>
(<em>
<a href="http://necrovenice:8080/venice/user/Administrator"
target="_blank"
class="text-blue-700 hover:text-blue-900">Administrator</a>,
Sep 8, 2025 5:17:02 PM
<a href="/user/{{ user }}" target="_blank" class="text-blue-700 hover:text-blue-900">{{ user }}</a>,
{{ DisplayDateTime(p.Posted, .) }}</em>)
</em>)
</div>
<pre class="mb-4 whitespace-pre-wrap">This is a test.
This is only a test.
If this had been an <em>actual</em> emergency, we would all be
dead by now.</pre>
<div class="text-xs italic">
(From the topic: <a href="http://necrovenice:8080/venice/go/Piazza!General.1"
class="text-blue-700 hover:text-blue-900">It Works Again!</a>)
<pre class="mb-4 amsPost whitespace-pre-wrap">{{ text | postRewrite | raw }}</pre>
<div class="text-xs mb-8 italic">
(From the topic: <a href="/go/{{ link }}" class="text-blue-700 hover:text-blue-900">{{ topic.Name | raw }}</a>)
</div>
</div>
{{ end }}
</div>
</div>