From fa04f67ab830493e301d6b76b24163f68dc87be6 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 23 Jan 2026 22:58:13 -0700 Subject: [PATCH] top page now displays published posts --- database/conference.go | 41 +++++++++++++++++++++++++++++++++++++++ database/topic.go | 23 ++++++++++++++++++++++ top.go | 34 ++++++++++++++++++++++++++++++-- ui/views/top.jet | 44 +++++++++++++++++++++++------------------- 4 files changed, 120 insertions(+), 22 deletions(-) diff --git a/database/conference.go b/database/conference.go index 20af1c0..07a9161 100644 --- a/database/conference.go +++ b/database/conference.go @@ -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) diff --git a/database/topic.go b/database/topic.go index 8507fe7..0979964 100644 --- a/database/topic.go +++ b/database/topic.go @@ -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 { diff --git a/top.go b/top.go index 2228544..eb2e585 100644 --- a/top.go +++ b/top.go @@ -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) diff --git a/ui/views/top.jet b/ui/views/top.jet index 17ae6ef..ff38b73 100644 --- a/ui/views/top.jet +++ b/ui/views/top.jet @@ -20,30 +20,34 @@ {{ end }} - +
-

Venice Currents

+

Latest from the Conferences


-
-
- Amy, formerly Eric - ( - Administrator, - Sep 8, 2025 5:17:02 PM - ) + {{ 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, .) }} +
+
+ {{ p.Pseud | raw }} + ( + {{ user }}, + {{ DisplayDateTime(p.Posted, .) }}) + ) +
+
{{ text | postRewrite | raw }}
+
+ (From the topic: {{ topic.Name | raw }}) +
-
This is a test.
-    This is only a test.
-    If this had been an actual emergency, we would all be 
-    dead by now.
-
- (From the topic: It Works Again!) -
-
+ {{ end }}