diff --git a/database/sidebox.go b/database/sidebox.go new file mode 100644 index 0000000..201fa4d --- /dev/null +++ b/database/sidebox.go @@ -0,0 +1,46 @@ +/* + * Amsterdam Web Communities System + * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ +// The database package contains database management and storage logic. +package database + +type Sidebox struct { + Uid int32 `db:"uid"` + Boxid int32 `db:"boxid"` + Sequence int32 `db:"sequence"` + Param *string `db:"param"` +} + +/* AmGetSideboxes returns all the configured sideboxes for a user. + * Parameters: + * uid = The ID of the user to retrieve sideboxes for. + * Returns: + * Array of Sidebox structures for the user, or nil + * Standard Go error status + */ +func AmGetSideboxes(uid int32) ([]*Sidebox, error) { + stmt, err := amdb.Preparex("SELECT * FROM sideboxes WHERE uid = ? ORDER BY SEQUENCE") + if err == nil { + defer stmt.Close() + rows, err := stmt.Queryx(uid) + if err == nil { + defer rows.Close() + sboxes := make([]*Sidebox, 0, 3) + for i := 0; rows.Next(); i++ { + box := Sidebox{} + rows.StructScan(&box) + sboxes = append(sboxes, &box) + } + if rows.Err() == nil { + return sboxes, nil + } + return nil, rows.Err() + } + } + return nil, err +} diff --git a/top.go b/top.go index cfa8ac5..7a5db84 100644 --- a/top.go +++ b/top.go @@ -9,9 +9,73 @@ // Package main contains the high-level Amsterdam logic. package main -import "git.erbosoft.com/amy/amsterdam/ui" +import ( + "fmt" + + "git.erbosoft.com/amy/amsterdam/database" + "git.erbosoft.com/amy/amsterdam/ui" +) + +type RenderedSideboxItem struct { + Text string + Link *string + Flags []string +} + +type RenderedSidebox struct { + TemplateName string + Title string + Subtext *string + Items []RenderedSideboxItem +} + +func buildFeaturedCommunities(uid int32, out *RenderedSidebox, in *database.Sidebox) error { + out.TemplateName = "sb_ftrcomm.jet" + return nil +} + +func buildFeaturedConferences(uid int32, out *RenderedSidebox, in *database.Sidebox) error { + out.TemplateName = "sb_ftrconf.jet" + return nil +} + +func buildUsersOnline(uid int32, out *RenderedSidebox, in *database.Sidebox) error { + out.TemplateName = "sb_online.jet" + return nil +} + +func buildRenderedSidebox(uid int32, out *RenderedSidebox, in *database.Sidebox) error { + switch in.Boxid { + case 1: + return buildFeaturedCommunities(uid, out, in) + case 2: + return buildFeaturedConferences(uid, out, in) + case 3: + return buildUsersOnline(uid, out, in) + default: + return fmt.Errorf("unknown sidebox boxid: %d", in.Boxid) + } +} func TopPage(ctxt ui.AmContext) (string, any, error) { + // Set the page title. ctxt.VarMap().Set("amsterdam_pageTitle", "My Front Page") + + // Retrieve the sideboxes and create the data to be presented. + uid := ctxt.Session().Values["user_id"].(int32) + sboxes, err := database.AmGetSideboxes(uid) + if err != nil { + return "string", "Unable to retrieve sideboxes", err + } + + rc := make([]RenderedSidebox, len(sboxes)) + for i, sb := range sboxes { + err = buildRenderedSidebox(uid, &(rc[i]), sb) + if err != nil { + return "string", "Unable to render sideboxes", err + } + } + + ctxt.VarMap().Set("sideboxes", rc) return "framed_template", "top.jet", nil } diff --git a/ui/amcontext.go b/ui/amcontext.go index cfd6acf..a4f3870 100644 --- a/ui/amcontext.go +++ b/ui/amcontext.go @@ -28,11 +28,12 @@ type AmContext interface { RC() int OutputType() string Render(string) error - Scratchpad() map[any]any + Scratchpad() map[string]any SubRender(string) ([]byte, error) Session() *sessions.Session SetOutputType(string) SetRC(int) + SetScratch(string, any) URLPath() string VarMap() jet.VarMap } @@ -43,7 +44,7 @@ type amContext struct { httprc int rendervars jet.VarMap outputType string - scratchpad map[any]any + scratchpad map[string]any session *sessions.Session } @@ -77,9 +78,9 @@ func (c *amContext) Render(name string) error { } // Scratchpad returns the per-request scratchpad for values. -func (c *amContext) Scratchpad() map[any]any { +func (c *amContext) Scratchpad() map[string]any { if c.scratchpad == nil { - c.scratchpad = make(map[any]any) + c.scratchpad = make(map[string]any) } return c.scratchpad } @@ -116,6 +117,13 @@ func (c *amContext) SetRC(rc int) { c.httprc = rc } +func (c *amContext) SetScratch(name string, val any) { + if c.scratchpad == nil { + c.scratchpad = make(map[string]any) + } + c.scratchpad[name] = val +} + // URLPath returns the path component of the request URL. func (c *amContext) URLPath() string { return c.echoContext.Request().URL.Path diff --git a/ui/views/sb_ftrcomm.jet b/ui/views/sb_ftrcomm.jet new file mode 100644 index 0000000..46b296b --- /dev/null +++ b/ui/views/sb_ftrcomm.jet @@ -0,0 +1,21 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + *} + +
+
+

Featured Communities:

+
+
+
+ 🟣 + La Piazza +
+
+
diff --git a/ui/views/sb_ftrconf.jet b/ui/views/sb_ftrconf.jet new file mode 100644 index 0000000..04a9822 --- /dev/null +++ b/ui/views/sb_ftrconf.jet @@ -0,0 +1,24 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + *} + +
+
+

Featured Conferences:

+
+
+
+ 🟣 +
+ General Discussion + (La Piazza) +
+
+
+
diff --git a/ui/views/sb_online.jet b/ui/views/sb_online.jet new file mode 100644 index 0000000..c4798bb --- /dev/null +++ b/ui/views/sb_online.jet @@ -0,0 +1,21 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + *} + +
+
+

Users Online:

+
+
+
1 total (max 1)
+
+ 🟣 + Not logged in (1) +
+
+
diff --git a/ui/views/top.jet b/ui/views/top.jet index a0cd017..720bfab 100644 --- a/ui/views/top.jet +++ b/ui/views/top.jet @@ -8,14 +8,16 @@ *}
- -
-

Welcome to Venice

-
-

- Welcome to the Venice Web Communities System. To get the most out of this site, you should log in or create an account, using one of the links above. -

-
+ {{ if .CurrentUser().IsAnon }} + +
+

Welcome to Amsterdam

+
+

+ Welcome to the Amsterdam Web Communities System. To get the most out of this site, you should log in or create an account, using one of the links above. +

+
+ {{ end }}
@@ -46,48 +48,9 @@ dead by now.
- -
-
-

Featured Communities:

-
-
-
- 🟣 - La Piazza -
-
-
- - -
-
-

Featured Conferences:

-
-
-
- 🟣 -
- General Discussion - (La Piazza) -
-
-
-
- - -
-
-

Users Online:

-
-
-
1 total (max 1)
-
- 🟣 - Not logged in (1) -
-
-
+ {{ ctxt := . }} + {{ range sideboxes }} + {{ ctxt.SetScratch("__sidebox", .) }} + {{ ctxt.SubRender(.TemplateName) | raw }} + {{ end }}